ตรวจสอบสี่คำตอบที่มีอยู่ในปัจจุบัน ( สองในผู้ใช้ Superและสองในคำถามนี้) ฉันเห็นปัญหาต่อไปนี้:
- สิ่งที่อยู่ใน SuperUser โดย Stefan และ Peng Bai (การย้ายบรรทัดต่อบรรทัดดูที่การเยื้องปัจจุบัน) ไม่ได้ใช้การคงตำแหน่งคอลัมน์ปัจจุบันและเลื่อนขึ้นไปที่ผู้ปกครอง
- คำตอบโดยแดน (ใช้ใหม่ค้นหาไปข้างหน้าเพื่อหาบรรทัดถัดไปกับการเยื้องเดียวกัน) ข้ามผ่านสายที่มีการเยื้องน้อย: มันไม่ได้รู้ว่าเมื่อไม่มีพี่น้องต่อไปและดังนั้นจึงสามารถย้ายไปยังบางสิ่งบางอย่างที่ไม่ได้เป็นพี่น้อง แต่ลูกของผู้ปกครองอีกคน ... อาจเป็น "ลูกพี่ลูกน้อง" คนต่อไป
- คำตอบโดยกิลส์ (โดยใช้ร่างโหมด) ไม่รักษาตำแหน่งคอลัมน์และมันไม่ได้ทำงานกับเส้นที่มีศูนย์การเยื้อง ( "ระดับบน" บรรทัด) นอกจากนี้การดูรหัสใน
outline.el
มันก็เป็นไปตามบรรทัดต่อบรรทัด (ใช้outline-next-visible-heading
) ในกรณีของเราเป็น (เกือบ) ทุกบรรทัดจะตรงกับ regexp เค้าร่างและนับเป็น "หัวเรื่อง"
ดังนั้นเมื่อรวบรวมแนวคิดบางอย่างของแต่ละข้อฉันมีสิ่งต่อไปนี้: เดินหน้าบรรทัดต่อบรรทัดข้ามบรรทัดว่างและเยื้องมากขึ้น หากคุณอยู่ที่การเยื้องเท่ากันมันก็เป็นพี่น้องคนต่อไป แนวคิดพื้นฐานมีลักษณะดังนี้:
(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)))
generalized ที่เหมาะสม (ไปข้างหน้า / ข้างหลัง / ขึ้น / ลง) สิ่งที่ฉันใช้อยู่ดูเหมือนว่าต่อไปนี้:
(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
ได้รับคุณใกล้ชิดกับสิ่งที่คุณต้องการ?