Як я можу отримати лінійку в стовпці 80?


81

Як програміст, я хочу бачити лінійку в певному стовпчику (як правило, 80), і тому я бачу, коли я перетинаю цей стовпець, а також бачу, наскільки я близький до нього, щоб я міг рано переформатувати свій код.

Я знайшов варіанти, які поки що не досягнуто цієї мети:

  • whitespace-mode, column-enforce-modeі column-markerвиділити лише окремі рядки після того, як текст у рядку вже пройшов fill-column. Мені б хотілося бачити, коли я наближаюся до колони, а не тільки коли я її перетинаю.
  • fill-column-indicatorбуло б хорошим рішенням, за винятком того, що ламається auto-complete-mode, company-mode, avyі багато іншого. Це питання , які здаються важко виправити, кожен з яких вимагає окремого тимчасового рішення - наприклад, див на company-modeпитання і на auto-complete-modeпитання , останній в протягом двох років).

Чи є кращі альтернативи?


8
Це не є відповіддю на ваше запитання як таке, але практичне рішення - встановити ширину вікна / рамки на 80 символів.
Ерік Браун

Дякую за пропозицію. Я думаю, я вважаю за краще, щоб при необхідності була доступна опціональна ширина, але це, безумовно, варіант. :-)
Йорген Шефер

5
Я б додав до пропозиції @ EricBrown, не змінюйте фактичну ширину вікна, а встановіть правий запас вікна, щоб місце для редагування становило 80 символів. (set-window-margins nil 0 (max (- (window-width) 80) 0))Тож якщо у вас вікно на 120 символів, воно зменшить простір, який ви повинні фактично відобразити до 80 символів. Таким чином він не зіпсує вашу конфігурацію вікна, і ви можете вимкнути його, якщо хочете. Якщо у вас є бахрома, насправді буде лінія, намальована у 80 стовпцях.
Джордон Біондо

1
Ось суть ідеї: gist.github.com/jordonbiondo/aa6d68b680abdb1a5f70 і ось вона в дії: i.imgur.com/dUx4bNz.gif
Jordon Biondo

@ jordon-biondo - це не вистачає гачок оновлення для зміни розміру вікон, див .: bitbucket.org/snippets/ideasman42/zexMG5
Ideman42

Відповіді:


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/isissue/… для подібного рішення для company-mode.
Дмитро

Привіт, дякую за те, що поділився ідеєю. Як змусити це працювати? Я маю код у своєму .emacs, але, мабуть, я мушу додати кілька гачків, щоб він працював?
PierreE

Так, наведений вище приклад радить popup-createі popup-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 не вдається правильно врахувати рядок заголовка під час обчислення висоти вікна. Отже, компанія не зможе намалювати належні спливаючі вікна у випадках, коли висота важлива, тобто в самому дні буфера.
місячник

1
Це дійсно цікава ідея. Шкода, що я не можу відзначити дві відповіді правильними, відповідь "патч fci" має деякі недоліки, і залежно від обставин це може бути кращим вибором. Дякую!
Jorgen Schäfer

10
Там також M-x ruler-mode.
sanityinc

Це не малюватиметься після цифр (коли відображаються номери рядків)
ideaman42

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 індикатор ) і використовуючи пробільні режим для виділення тексту , який проходить повз колони.

(Якщо вам потрібен рядок, що знаходиться праворуч від усіх текстів у всіх рядках, ви завжди можете ввімкнути його picture-mode, але це, мабуть, корисно тут лише як тимчасове вирішення.)

Дивіться також Знайти довгі рядки щодо способів пошуку довгих ліній за запитом.


6

Не точно те, що ви хочете, але така лінійка, як @ Malabarba ♦ буде витрачати місце, ось краще рішення:

Існує вбудований пакет emacs-goodies-el(рекомендую встановити його в терміналі), який називається підкреслити-не-заповнити-колонку.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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.