Wie bekomme ich ein Lineal in Spalte 80?


81

Als Programmierer möchte ich ein Lineal in einer bestimmten Spalte (normalerweise 80) sehen, und zwar sowohl, wenn ich diese Spalte überschreite, als auch, wie nah ich daran bin, damit ich meinen Code frühzeitig neu formatieren kann.

Die Optionen, die ich bisher gefunden habe, erreichen alle dieses Ziel nicht:

  • whitespace-mode,, column-enforce-modeund column-markermarkieren Sie einzelne Zeilen erst, nachdem der Text in der Zeile die Markierung bereits passiert hat fill-column. Ich würde gerne sehen, wann ich mich der Säule nähere, nicht nur, wenn ich sie überquere.
  • fill-column-indicatorwäre eine gute Lösung, außer es bricht auto-complete-mode, company-mode, avyund vieles mehr. Dies sind Probleme, die schwer zu beheben sind und jeweils eine individuelle Problemumgehung erfordern (siehe z. B. das company-modeProblem und das auto-complete-modeProblem , letzteres älter als zwei Jahre).

Gibt es bessere Alternativen?


8
Dies ist keine Antwort auf Ihre Frage an sich, aber eine praktische Lösung besteht darin, die Breite Ihres Fensters / Rahmens auf 80 Zeichen festzulegen.
Eric Brown

Danke für den Vorschlag. Ich denke, ich würde es vorziehen, die optionale Breite bei Bedarf zur Verfügung zu haben, aber es ist sicherlich eine Option. :-)
Jorgen Schäfer

5
Ich würde @ EricBrowns Vorschlag ergänzen, nicht die tatsächliche Fensterbreite ändern, sondern den rechten Rand des Fensters so einstellen, dass der Bearbeitungsbereich 80 Zeichen beträgt. (set-window-margins nil 0 (max (- (window-width) 80) 0))Wenn Sie also ein 120 Zeichen breites Fenster haben, wird der Platz, den Sie zum Anzeigen des Codes tatsächlich benötigen, auf 80 Zeichen verkleinert. Auf diese Weise wird Ihre Fensterkonfiguration nicht durcheinander gebracht, und Sie können sie bei Bedarf ein- und ausschalten. Wenn Sie Ränder haben, wird tatsächlich eine Linie mit 80 Spalten gezeichnet.
Jordon Biondo

1
Hier ist ein Kern der Idee: gist.github.com/jordonbiondo/aa6d68b680abdb1a5f70 und hier ist sie in Aktion: i.imgur.com/dUx4bNz.gif
Jordon Biondo

@ jordon-biondo - dies verpasst Update-Hooks für die Fenstergröße, siehe: bitbucket.org/snippets/ideasman42/zexMG5
ideasman42

Antworten:


39

fill-column-indicatorist die ausgereifteste Lösung. Wenn Sie überlagerten Code finden, mit dem ein Konflikt besteht, können Sie Code hinzufügen, der angehalten werden soll, fci-modewährend der Konfliktcode aktiv ist. Mit dem folgenden Code funktioniert es beispielsweise 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
Oder finden Sie unter github.com/company-mode/company-mode/issues/… eine ähnliche Lösung für company-mode.
Dmitry

Hallo, danke, dass du die Idee geteilt hast. Wie bringe ich das zum Laufen? Ich habe den Code in meinem .emacs, aber ich nehme an, ich muss ein paar Hooks hinzufügen, damit es funktioniert?
PierreE

Ja, das obige Beispiel rät popup-createund popup-delete- je nach Anwendungsfall müssen Sie möglicherweise unterschiedliche Funktionen empfehlen.
Sanityinc


21

Hier ist eine Option, die robuster ist, fast nichts bricht (gelegentlich ist der Firmenmodus eine bemerkenswerte Ausnahme), aber nicht so bequem wie fill-column-indicator.

Verwenden Sie das Kopfzeilenformat , um die 80. Spalte in der Kopfzeile zu markieren.
So etwas sollte ausreichen:

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

Sie sollten die Anzahl der Leerzeichen in dieser ersten Zeichenfolge in Abhängigkeit von der Größe Ihres linken Randes ändern. Davon abgesehen sollte dies jedoch einigermaßen gut funktionieren. Es ist nicht so praktisch wie ein Lineal im eigentlichen Puffer, aber es hilft.

Sie können es auch so einstellen, dass es nur auf Programmierpuffer angewendet wird.

(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)

Ergebnis:
Sie sollten ungefähr Folgendes erhalten (die erste Zeile befindet sich nicht im Puffer, sondern in der Kopfzeile).

-------------------------------------------------------------------------------|
;; 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
Beachten Sie, dass dies in Emacs 24.3 auch den Firmenmodus unterbricht, zumindest in einigen Randfällen. Emacs 24.3 kann die Kopfzeile bei der Berechnung der Höhe eines Fensters nicht korrekt berücksichtigen. Infolgedessen kann das Unternehmen in Fällen, in denen die Höhe wichtig ist, dh ganz unten im Puffer, keine ordnungsgemäßen Popups zeichnen.
Lunaryorn

1
Das ist eine wirklich interessante Idee. Schade, dass ich zwei Antworten nicht als richtig markieren kann. Die "Patch-FCI" -Antwort weist einige Nachteile auf. Abhängig von den Umständen kann dies eine bessere Wahl sein. Danke!
Jorgen Schäfer

10
Es gibt auch M-x ruler-mode.
Sanityinc

Dies beginnt nicht nach den Zahlen (wenn Zeilennummern angezeigt werden)
ideasman42

17

Nach vielem Leid wegen diverser Bugs habe fill-column-indicatorich es endgültig aus meiner Konfiguration entfernt.

Derzeit verwende ich die integrierte Emacs-Funktionalität, um zu lange Zeilen hervorzuheben. Das sieht sogar besser aus, ich würde es fill-column-indicatorjetzt nicht aktivieren, selbst wenn es fehlerfrei wäre.

Zum einen können Sie mein Setup greifen:

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

Aktivieren Sie es dann, wo Sie möchten. Ich benutze es nur im Programmierkontext:

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

9

Gibt es bessere Alternativen?

Emacs 27 unterstützt einen Füllspaltenindikator nativ über den Buffer-Local-Minor-Modus display-fill-column-indicator-modeund sein globales Gegenstück global-display-fill-column-indicator-mode.

Hier ist es in Aktion:

Bildbeschreibung hier eingeben

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

Diese EmacsWiki-Seite enthält viele Informationen zu verschiedenen Möglichkeiten, eine bestimmte Spalte zu markieren oder Sie anderweitig zu informieren, wenn Sie daran vorbeigehen.

Das, was ich benutze, ist Mode Line Position .

In anderen Fällen wird eine vertikale Linie in der Spalte angezeigt (Spaltenmarkierung , Füllspaltenanzeige ) und im Leerzeichenmodus wird Text hervorgehoben, der über die Spalte hinausgeht.

(Wenn die Zeile in allen Zeilen weit rechts vom gesamten Text stehen muss, können Sie sie jederzeit picture-modeaktivieren. Dies ist hier jedoch wahrscheinlich nur als vorübergehende Problemumgehung hilfreich.)

Siehe auch Lange Leitungen suchen, um bei Bedarf lange Leitungen zu finden.


6

Nicht genau das, was Sie wollen, aber Lineal wie @ Malabarba ♦ wird Platz verschwenden, hier ist eine bessere Lösung:

Es gibt ein eingebautes Paket in emacs-goodies-el(es wird empfohlen, es im Terminal zu installieren) mit dem Namen highlight-beyond-fill-column.el. Fügen Sie dies zu Ihrem hinzu .emacsoder 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" )))))

Der Text, hinter fill-columndem im Snippet 80 steht, wird mit der Farbe von hervorgehoben red. Sie können das Gesicht einstellen, wie Sie möchten.


1

Da fill-column-indicatores ziemlich schwer ist, zeigt diese Lösung ein Zeichen rechts von der aktuellen Zeile.

Wenn Sie also tippen, können Sie das Zeilenlimit sehen, bevor Sie es überschreiten.

Dies definiert den Nebenmodus 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))))

Wenn Sie evil-modeden Einfügemodus verwenden und ihn einschränken möchten, können Sie die folgenden Hooks hinzufügen:

(add-hook 'evil-insert-state-entry-hook #'hl-line-margin-mode-enable)
(add-hook 'evil-insert-state-exit-hook #'hl-line-margin-mode-disable)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.