ฉันจะได้ไม้บรรทัดที่คอลัมน์ 80 ได้อย่างไร


81

ในฐานะโปรแกรมเมอร์ฉันต้องการเห็นไม้บรรทัดที่คอลัมน์เฉพาะ (ปกติ 80) ทั้งคู่ดังนั้นฉันเห็นเมื่อฉันข้ามคอลัมน์นั้น แต่ยังเพื่อดูว่าฉันเข้าใกล้มันมากแค่ไหนเพื่อให้ฉันสามารถฟอร์แมตโค้ดใหม่ได้เร็วขึ้น

ตัวเลือกที่ฉันพบจนถึงขณะนี้ทั้งหมดไม่บรรลุเป้าหมายนี้:

  • whitespace-mode, column-enforce-modeและเพียงเน้นแต่ละแถวหลังข้อความในแถวได้ผ่านไปแล้วcolumn-marker fill-columnฉันต้องการที่จะเห็นเมื่อฉันเข้าใกล้คอลัมน์ไม่เพียง แต่เมื่อฉันข้ามมัน
  • fill-column-indicatorจะเป็นทางออกที่ดีนอกจากจะแบ่งauto-complete-mode, company-mode, avyและอื่น ๆ เหล่านี้เป็นปัญหาที่ดูเหมือนยากที่จะแก้ไขที่กำหนดให้แต่ละวิธีแก้ปัญหาของแต่ละบุคคล - เช่นดูปัญหาและปัญหาหลังมากกว่าสองปี)company-modeauto-complete-mode

มีทางเลือกที่ดีกว่านี้อีกไหม?


8
นี่ไม่ใช่คำตอบสำหรับคำถามของคุณ แต่การแก้ปัญหาในทางปฏิบัติคือการกำหนดความกว้างของหน้าต่าง / กรอบของคุณเป็น 80 ตัวอักษร
Eric Brown

ขอบคุณสำหรับคำแนะนำ ฉันคิดว่าฉันต้องการให้มีความกว้างที่เป็นทางเลือกเมื่อจำเป็น แต่ก็เป็นตัวเลือกอย่างแน่นอน :-)
Jorgen Schäfer

5
ฉันจะเพิ่มคำแนะนำของ @ EricBrown อย่าเปลี่ยนความกว้างของหน้าต่างจริง แต่ควรตั้งระยะขอบด้านขวาของหน้าต่างเพื่อให้พื้นที่การแก้ไขคือ 80 อักขระ (set-window-margins nil 0 (max (- (window-width) 80) 0))ดังนั้นหากคุณมีหน้าต่างกว้าง 120 ตัวอักษรมันจะลดขนาดพื้นที่ที่คุณต้องแสดงรหัสจริงถึง 80 ตัวอักษร วิธีนี้จะไม่ทำให้การกำหนดค่าหน้าต่างของคุณยุ่งเหยิงและคุณสามารถสลับเป็นแบบปิดได้หากคุณต้องการ หากคุณมีขอบจะมีการลากเส้นที่ 80 คอลัมน์
Jordon Biondo

1
นี่คือส่วนสำคัญของความคิด: gist.github.com/jordonbiondo/aa6d68b680abdb1a5f70และนี่คือการดำเนินการ: i.imgur.com/dUx4bNz.gif
Jordon Biondo

@ jordon-biondo - นี่ขาดการปรับปรุง hooks สำหรับการปรับขนาดหน้าต่างดู: bitbucket.org/snippets/ideasman42/zexMG5
ideasman42

คำตอบ:


39

fill-column-indicatorเป็นวิธีแก้ปัญหาที่ผู้ใหญ่ที่สุดและหากคุณพบรหัสที่ซ้อนทับซึ่งมันขัดแย้งกันคุณสามารถเพิ่มรหัสเพื่อระงับfci-modeขณะที่รหัสที่ขัดแย้งกันทำงานอยู่ ตัวอย่างเช่นรหัสต่อไปนี้ทำให้ทำงานกับauto-complete:

  (defun sanityinc/fci-enabled-p () (symbol-value 'fci-mode))

  (defvar sanityinc/fci-mode-suppressed nil)
  (make-variable-buffer-local 'sanityinc/fci-mode-suppressed)

  (defadvice popup-create (before suppress-fci-mode activate)
    "Suspend fci-mode while popups are visible"
    (let ((fci-enabled (sanityinc/fci-enabled-p)))
      (when fci-enabled
        (setq sanityinc/fci-mode-suppressed fci-enabled)
        (turn-off-fci-mode))))

  (defadvice popup-delete (after restore-fci-mode activate)
    "Restore fci-mode when all popups have closed"
    (when (and sanityinc/fci-mode-suppressed
               (null popup-instances))
      (setq sanityinc/fci-mode-suppressed nil)
      (turn-on-fci-mode)))

5
หรือดูgithub.com/company-mode/company-mode/issues/...company-modeสำหรับการแก้ปัญหาที่คล้ายกันสำหรับ
Dmitry

สวัสดีขอบคุณสำหรับการแบ่งปันความคิด ฉันจะทำให้เรื่องนี้ทำงานได้อย่างไร ฉันมีรหัสใน. emacs ของฉัน แต่ฉันคิดว่าฉันต้องเพิ่ม hooks เพื่อให้มันใช้งานได้หรือไม่
PierreE

ใช่ตัวอย่างข้างต้นแนะนำpopup-createและpopup-delete- ขึ้นอยู่กับกรณีการใช้งานของคุณคุณอาจจำเป็นต้องแนะนำฟังก์ชั่นที่แตกต่างกัน
sanityinc

2
ช้าไม่น่า
Alexander Shukaev

21

นี่คือหนึ่งในตัวเลือกที่มีประสิทธิภาพมากขึ้นจะแบ่งเกือบไม่มีอะไร (บางครั้ง บริษัท โหมดเป็นข้อยกเว้นที่น่าสังเกต) fill-column-indicatorแต่ไม่ได้เป็นความสะดวกที่

ใช้ header-line-format เพื่อทำเครื่องหมายคอลัมน์ที่ 80 บนส่วนหัว
สิ่งต่อไปนี้น่าจะพอเพียง:

(setq-default header-line-format 
              (list " " (make-string 79 ?-) "|"))

คุณควรเปลี่ยนจำนวนช่องว่างในสตริงแรกนั้นขึ้นอยู่กับขนาดของขอบด้านซ้ายของคุณ แต่นอกเหนือจากนี้ควรทำงานได้ดีพอสมควร มันไม่สะดวกเท่ากับไม้บรรทัดในบัฟเฟอร์จริง แต่ช่วยได้

นอกจากนี้คุณยังสามารถตั้งค่าให้ใช้กับการตั้งโปรแกรมบัฟเฟอร์เท่านั้น

(defun prog-mode-header-line ()
  "Setup the `header-line-format' on for buffers."
  (setq header-line-format 
        (list " " (make-string 79 ?-) "|")))

(add-hook 'prog-mode-hook #'prog-mode-header-line)

ผลลัพธ์:
คุณควรได้รับสิ่งต่อไปนี้ (บรรทัดแรกไม่ได้อยู่ในบัฟเฟอร์ แต่ในส่วนหัว)

-------------------------------------------------------------------------------|
;; This is what your buffer should look like all the way up to column number 80.
(setq some-dummy-variable we-are-all-friends)

1
โปรดทราบว่าใน Emacs 24.3 จะเป็นการแบ่งโหมด บริษัท เช่นกันอย่างน้อยในบางกรณีของขอบ Emacs 24.3 ล้มเหลวในการบรรทัดส่วนหัวอย่างถูกต้องเมื่อคำนวณความสูงของหน้าต่าง ดังนั้น บริษัท ไม่สามารถดึงป๊อปอัปที่เหมาะสมในกรณีที่ความสูงมีความสำคัญเช่นที่ด้านล่างสุดของบัฟเฟอร์
Lunaryorn

1
นี่เป็นความคิดที่น่าสนใจจริงๆ น่าเสียดายที่ฉันไม่สามารถทำเครื่องหมายสองคำตอบว่าถูกต้องคำตอบ "patch fci" มีข้อบกพร่องบางประการและขึ้นอยู่กับสถานการณ์ซึ่งอาจเป็นตัวเลือกที่ดีกว่า ขอขอบคุณ!
Jorgen Schäfer

10
M-x ruler-modeนอกจากนี้ยังมี
sanityinc

สิ่งนี้ไม่ได้วาดหลังจากเริ่มต้นตัวเลข (เมื่อแสดงหมายเลขบรรทัด)
ideasman42

17

หลังจากความทุกข์ทรมานมากเนื่องจากข้อบกพร่องต่าง ๆfill-column-indicatorแนะนำฉันกำจัดมันจากการตั้งค่าของฉันให้ดี

สิ่งที่ฉันใช้อยู่ในขณะนี้คือฟังก์ชั่น Emacs ในตัวเพื่อเน้นบรรทัดที่ยาวเกินไป สิ่งนี้ดูดีกว่าฉันจะไม่เปิดใช้งานfill-column-indicatorตอนนี้แม้ว่าจะปราศจากข้อผิดพลาดก็ตาม

สำหรับการเริ่มต้นคุณอาจคว้าการตั้งค่าของฉัน:

(setq-default
 whitespace-line-column 80
 whitespace-style       '(face lines-tail))

จากนั้นเปิดใช้งานได้ตามที่คุณต้องการ ฉันใช้มันเฉพาะในบริบทการเขียนโปรแกรม:

(add-hook 'prog-mode-hook #'whitespace-mode)

9

มีทางเลือกที่ดีกว่านี้อีกไหม?

Emacs 27 จะสนับสนุนตัวบ่งชี้คอลัมน์เติมกำเนิดโดยวิธีการโหมดย่อยบัฟเฟอร์ท้องถิ่นและคู่ทั่วโลกdisplay-fill-column-indicator-modeglobal-display-fill-column-indicator-mode

นี่คือการกระทำ:

ป้อนคำอธิบายรูปภาพที่นี่

Quoth (emacs) Displaying Boundaries:

14.15 Displaying Boundaries
===========================

Emacs can add an indicator to display a fill column position.  The fill
column indicator is a useful functionality specially in prog-mode to
indicate the position of an specific column.

   You can set the buffer-local variables
‘display-fill-column-indicator’ and
‘display-fill-column-indicator-character’ to activate the indicator and
controls how the indicator looks.

   Alternatively you can type ‘M-x display-fill-column-indicator-mode’
or ‘M-x global-display-fill-column-indicator-mode’ which enables the
indicator locally and globally respectively and also chooses the
character to use if none is set already.  It is possible to use the
first one to activate the indicator in a hook or the second one to
enable it globally.

   There are 2 buffer local variables and 1 face to customize this mode:

‘display-fill-column-indicator-column’
     Specifies the column number where the indicator should be set.  It
     can take positive numerical values for the column or the special
     value ‘t’ which means that the variable ‘fill-column’ will be used.

     Any other value disables the indicator.  The default value is ‘t’.

‘display-fill-column-indicator-character’
     Specifies the character used for the indicator.  This character can
     be any valid char including unicode ones if the actual font
     supports them.

     When the mode is enabled through the functions
     ‘display-fill-column-indicator-mode’ or
     ‘global-display-fill-column-indicator-mode’, the initialization
     functions check if this variable is ‘non-nil’, otherwise the
     initialization tries to set it to U+2502 or ‘|’.

‘fill-column-indicator’
     Specifies the face used to display the indicator.  It inherits its
     default values from shadow but without background color.  To change
     the indicator color you need to set only the foreground color of
     this face.

7

หน้า EmacsWiki นี้มีข้อมูลมากมายเกี่ยวกับวิธีต่างๆในการทำเครื่องหมายคอลัมน์ใดคอลัมน์หนึ่งหรือแจ้งให้คุณทราบเมื่อคุณผ่านมันไป

อย่างใดอย่างหนึ่งที่ผมใช้เป็นโหมดสายตำแหน่ง

แต่คนอื่น ๆ รวมถึงการแสดงเส้นแนวตั้งที่คอลัมน์ ( คอลัมน์ Marker , เติมคอลัมน์ดัชนี ) และการใช้โหมดช่องว่างเพื่อเน้นข้อความที่จะไปที่ผ่านมาคอลัมน์

(หากคุณต้องการให้บรรทัดอยู่ด้านขวาสุดของข้อความทั้งหมดในทุกแถวคุณสามารถเปิดใช้งานได้ตลอดเวลาpicture-modeแต่นั่นอาจเป็นประโยชน์สำหรับที่นี่เป็นวิธีแก้ปัญหาชั่วคราวเท่านั้น)

ดูเพิ่มเติมค้นหาเส้นทางยาวเพื่อหาเส้นทางยาวตามความต้องการ


6

ไม่ต้องการสิ่งที่แน่นอน แต่ผู้ปกครองเช่น @ Malabarba ♦จะเป็นพื้นที่ waster นี่คือทางออกที่ดีกว่า:

มีแพ็คเกจในตัวในemacs-goodies-el(แนะนำให้ติดตั้งในเทอร์มินอล) ที่เรียกว่าhighlight-Beyond-fill-column.elเพิ่มสิ่งนี้ลงในของคุณ.emacsหรือinit.el:

(setq-default fill-column 80)
(add-hook 'prog-mode-hook 'highlight-beyond-fill-column)
(custom-set-faces '(highlight-beyond-fill-column-face
                    ((t (:foreground "red" )))))

ข้อความเกินfill-columnซึ่งเป็น 80 redในตัวอย่างจะถูกเน้นด้วยสีของ คุณสามารถตั้งค่าใบหน้าตามที่คุณต้องการ


1

เนื่องจากfill-column-indicatorค่อนข้างหนักโซลูชันนี้จะแสดงอักขระทางด้านขวาของบรรทัดปัจจุบัน

ดังนั้นเมื่อคุณพิมพ์คุณจะเห็นขีด จำกัด บรรทัดก่อนที่จะเกิน

สิ่งนี้จะกำหนดโหมดรองhl-line-margin-mode:

;; Global, ensures one active margin for the active buffer.
(defvar hl-line-margin--overlay nil)

(defun hl-line-margin--overlay-clear ()
  "Clear the overlays."
  (when hl-line-margin--overlay
    (delete-overlay hl-line-margin--overlay)
    (setq hl-line-margin--overlay nil)))

(defun hl-line-margin--overlay ()
  "Create the line highlighting overlay."
  ;; Remove in the event of a changed buffer,
  ;; ensures we update for a modified fill-column.
  (when (and hl-line-margin--overlay
             (not (eq (current-buffer)
                      (overlay-buffer hl-line-margin--overlay))))
    (hl-line-margin--overlay-clear))
  (unless hl-line-margin--overlay
    (setq hl-line-margin--overlay (make-overlay 0 0))
    (let ((space `((space :align-to ,fill-column)
                   (space :width 0))))
      (overlay-put hl-line-margin--overlay 'after-string
                   (concat (propertize " " 'display space 'cursor t)
                           (propertize " " 'face '(:inverse-video t))))))
  (let ((eol (line-end-position)))
    (unless (eql eol (overlay-start hl-line-margin--overlay))
      (move-overlay hl-line-margin--overlay eol eol))))

(defun hl-line-margin-mode-enable ()
  "Turn on `hl-line-margin-mode' for the current buffer."
  (add-hook 'post-command-hook #'hl-line-margin--overlay nil t))

(defun hl-line-margin-mode-disable ()
  "Turn off `hl-line-margin-mode' for the current buffer."
  (hl-line-margin--overlay-clear)
  (remove-hook 'post-command-hook #'hl-line-margin--overlay t))

;;;###autoload
(define-minor-mode hl-line-margin-mode
  "Show a character at the fill column of the current line."
  :lighter ""
  (cond (hl-line-margin-mode
         (jit-lock-unregister #'hl-line-margin-mode-enable)
         (hl-line-margin-mode-enable))
        (t
         (jit-lock-unregister #'hl-line-margin-mode-disable)
         (hl-line-margin-mode-disable))))

หากคุณใช้evil-modeและต้องการ จำกัด สิ่งนี้ในโหมดแทรกคุณสามารถเพิ่ม hooks ต่อไปนี้:

(add-hook 'evil-insert-state-entry-hook #'hl-line-margin-mode-enable)
(add-hook 'evil-insert-state-exit-hook #'hl-line-margin-mode-disable)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.