如何在第80列获得标尺?


81

作为程序员,我想在特定的列(通常为80)上看到一个标尺,既可以看到跨过该列的时间,又可以看到距它有多近,因此可以尽早重新格式化代码。

到目前为止,我发现的所有选项都无法实现此目标:

有更好的选择吗?


8
这本身并不是对您问题的答案,但实际的解决方案是将窗口/框架的宽度设置为80个字符。
埃里克·布朗

谢谢你的建议。我认为我更愿意在必要时使用可选宽度,但这当然是一个选择。:-)
JorgenSchäfer2014年

5
我会增加@EricBrown的建议,不要更改实际的窗口宽度,而是设置窗口的右边界,以便编辑空间为80个字符。(set-window-margins nil 0 (max (- (window-width) 80) 0))因此,如果您有一个120个字符的宽窗口,它将缩小实际显示代码所需的空间为80个字符。这样,它不会弄乱您的窗口配置,并且您可以根据需要将其打开。如果您有条纹,实际上会在80列处画一条线。
Jordon Biondo


@ jordon-biondo-错过了窗口大小调整的更新钩子,请参见:bitbucket.org/snippets/ideasman42/zexMG5
ideaman42

Answers:


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中有代码,但是我想必须添加一些钩子才能使其正常工作?
PierreE '17

是的,上面的例子中建议popup-createpopup-delete-取决于你的使用情况,您可能需要通知不同的功能。
sanityinc


21

这是一个更健壮的选项,它几乎不会破坏任何内容(有时,公司模式是一个值得注意的例外),但是不如fill-column-indicator

使用 标题行格式 在标题上标记第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 2014年

1
这是一个非常有趣的想法。太糟糕了,我不能将两个答案标记为正确,“ patch fci”答案有一些缺点,根据情况的不同,这可能是一个更好的选择。谢谢!
JorgenSchäfer2014年

10
也有M-x ruler-mode
sanityinc 2014年

这不会在数字(显示行号)之后开始绘制
ideaman42 '16

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-mode及其全局对应方式本地支持填充列指示器global-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页面包含许多有关标记特定列或以其他方式通知您的特定方法的信息。

我使用的是模式行位置

但是其他方法包括在列上显示垂直线(Column MarkerFill-Column Indicator),并使用空格模式突出显示超出列的文本。

(如果您需要使该行位于所有行中所有文本的右侧,则可以始终打开picture-mode,但这在这里仅作为一种临时解决方法可能很有用。)

另请参阅查找长线以获取按需查找长线的方法。


6

不完全是您想要的,但是像@ Malabarba♦这样的标尺会浪费空间,这是更好的解决方案:

有一个内置包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并希望将此模式限制为插入模式,则可以添加以下挂钩:

(add-hook 'evil-insert-state-entry-hook #'hl-line-margin-mode-enable)
(add-hook 'evil-insert-state-exit-hook #'hl-line-margin-mode-disable)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.