현재 사용 가능한 4 가지 답변 ( 수퍼 유저 2 명,이 질문 2 명)을 검토하면 다음과 같은 문제가 나타납니다.
- 스테판과 펭 바이로 슈퍼 유저에 사람은 , 현재 열 위치를 유지하고 부모까지 이동 구현하지 않는 (현재 들여보고, 줄 단위 이동)
- Dan 의 대답 (동일한 들여 쓰기가있는 다음 줄을 찾기 위해 re-search-forward 사용)은 들여 쓰기가 적은 줄을 건너 뜁니다. 다음 형제가 없는지 알지 못하므로 형제가 아닌 것으로 이동할 수 있습니다. 그러나 다른 부모의 아이… 아마 다음 "사촌".
- Gilles 의 답변 (개요 모드 사용)은 열 위치를 유지하지 않으며 들여 쓰기가없는 줄 ( "최상위"줄)에서는 작동하지 않습니다. 또한의 코드를 살펴보면
outline.el
기본적으로 어쨌든 outline-next-visible-heading
모든 행이 개요 정규 표현식과 일치하고 "제목"으로 계산되므로 기본적으로 어쨌든 한 줄씩 이동합니다 .
그래서, 각각의 아이디어를 모아서 다음과 같은 것을 가지고 있습니다. 들여 쓰기가 동일하면 다음 형제입니다. 기본 아이디어는 다음과 같습니다.
(defun indentation-get-next-sibling-line ()
"The line number of the next sibling, or nil if there isn't any."
(let ((wanted-indentation (current-indentation)))
(save-excursion
(while (and (zerop (forward-line)) ; forward-line returns 0 on success
(or (eolp) ; Skip past blank lines and more-indented lines
(> (current-indentation) wanted-indentation))))
;; Now we can't go further. Which case is it?
(if (and (not (eobp)) (= (current-indentation) wanted-indentation))
(line-number-at-pos)
nil))))
(defun indentation-forward-to-next-sibling ()
(interactive)
(let ((saved-column (current-column)))
(forward-line (- (indentation-get-next-sibling-line) (line-number-at-pos)))
(move-to-column saved-column)))
적절하게 일반화 (앞으로 / 뒤로 / 위로 / 아래로), 내가 사용하는 것은 현재 다음과 같습니다.
(defun indentation-get-next-good-line (direction skip good)
"Moving in direction `direction', and skipping over blank lines and lines that
satisfy relation `skip' between their indentation and the original indentation,
finds the first line whose indentation satisfies predicate `good'."
(let ((starting-indentation (current-indentation))
(lines-moved direction))
(save-excursion
(while (and (zerop (forward-line direction))
(or (eolp) ; Skip past blank lines and other skip lines
(funcall skip (current-indentation) starting-indentation)))
(setq lines-moved (+ lines-moved direction)))
;; Now we can't go further. Which case is it?
(if (and
(not (eobp))
(not (bobp))
(funcall good (current-indentation) starting-indentation))
lines-moved
nil))))
(defun indentation-get-next-sibling-line ()
"The line number of the next sibling, if any."
(indentation-get-next-good-line 1 '> '=))
(defun indentation-get-previous-sibling-line ()
"The line number of the previous sibling, if any"
(indentation-get-next-good-line -1 '> '=))
(defun indentation-get-parent-line ()
"The line number of the parent, if any."
(indentation-get-next-good-line -1 '>= '<))
(defun indentation-get-child-line ()
"The line number of the first child, if any."
(indentation-get-next-good-line +1 'ignore '>))
(defun indentation-move-to-line (func preserve-column name)
"Move the number of lines given by func. If not possible, use `name' to say so."
(let ((saved-column (current-column))
(lines-to-move-by (funcall func)))
(if lines-to-move-by
(progn
(forward-line lines-to-move-by)
(move-to-column (if preserve-column
saved-column
(current-indentation))))
(message "No %s to move to." name))))
(defun indentation-forward-to-next-sibling ()
"Move to the next sibling if any, retaining column position."
(interactive "@")
(indentation-move-to-line 'indentation-get-next-sibling-line t "next sibling"))
(defun indentation-backward-to-previous-sibling ()
"Move to the previous sibling if any, retaining column position."
(interactive "@")
(indentation-move-to-line 'indentation-get-previous-sibling-line t "previous sibling"))
(defun indentation-up-to-parent ()
"Move to the parent line if any."
(interactive "@")
(indentation-move-to-line 'indentation-get-parent-line nil "parent"))
(defun indentation-down-to-child ()
"Move to the first child line if any."
(interactive "@")
(indentation-move-to-line 'indentation-get-child-line nil "child"))
여전히 더 많은 기능이 바람직하며, outline.el
그 중 일부를 살펴보고 다시 구현 하면 도움이 될 수 있지만 지금은이 목적에 만족합니다.
set-selective-display
필요한 것에 가까이 가나 요?