Bagaimana saya bisa mendapatkan penggaris di kolom 80?

81

Sebagai seorang programmer, saya ingin melihat penggaris pada kolom tertentu (biasanya 80), keduanya jadi saya melihat ketika saya melewati kolom itu, tetapi juga untuk melihat seberapa dekat saya sampai sehingga saya dapat memformat ulang kode saya lebih awal.

Opsi yang saya temukan sejauh ini semuanya tidak mencapai tujuan ini:

  • whitespace-mode,,, column-enforce-modedan column-markerhanya menyorot setiap baris setelah teks di baris telah melewati fill-column. Saya ingin melihat ketika saya semakin dekat ke kolom, bukan hanya ketika saya menyeberanginya.
  • fill-column-indicatorakan menjadi solusi yang baik, kecuali rusak auto-complete-mode, company-mode, avy, dan banyak lagi. Ini adalah masalah yang tampaknya sulit untuk memperbaiki, masing-masing membutuhkan sebuah solusi individu - misalnya, melihat yang company-modemasalah dan yang auto-complete-modemasalah , yang terakhir lebih dua tahun).

Apakah ada alternatif yang lebih baik?

Jorgen Schäfer
sumber
8
Ini bukan jawaban untuk pertanyaan Anda semata, tetapi solusi praktis adalah dengan mengatur lebar jendela / bingkai Anda menjadi 80 karakter.
Eric Brown
Terima kasih untuk sarannya. Saya pikir saya lebih suka memiliki lebar opsional yang tersedia bila perlu, tapi itu tentu saja pilihan. :-)
Jorgen Schäfer
5
Saya akan menambahkan saran @ EricBrown, jangan mengubah lebar jendela yang sebenarnya, tetapi mengatur margin kanan jendela sehingga ruang pengeditan adalah 80 karakter. (set-window-margins nil 0 (max (- (window-width) 80) 0))Jadi, jika Anda memiliki jendela lebar 120 karakter, itu akan mengecilkan ruang Anda harus benar-benar menampilkan kode menjadi 80 karakter. Dengan cara ini tidak akan mengacaukan konfigurasi jendela Anda dan Anda dapat mengaktifkannya jika Anda mau. Jika Anda memiliki pinggiran, sebenarnya akan ada garis yang ditarik pada 80 kolom.
Jordon Biondo
1
Inilah intisari dari gagasan itu: gist.github.com/jordonbiondo/aa6d68b680abdb1a5f70 dan ini dia sedang beraksi: i.imgur.com/dUx4bNz.gif
Jordon Biondo
@ Jordon-Biondo - ini merindukan pembaruan kait untuk mengubah ukuran jendela, lihat: bitbucket.org/snippets/ideasman42/zexMG5
ideasman42

Jawaban:

39

fill-column-indicatoradalah solusi yang paling matang, dan jika Anda menemukan kode berbasis overlay yang bertentangan, Anda dapat menambahkan kode untuk ditangguhkan fci-modesaat kode yang bertentangan aktif. Misalnya, kode berikut membuatnya berfungsi dengan 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)))
sanityinc
sumber
5
Atau lihat github.com/company-mode/company-mode/issues/… untuk solusi serupa company-mode.
Dmitry
Hai, terima kasih telah berbagi ide. Bagaimana saya membuatnya bekerja? Saya memiliki kode di .emacs saya, tetapi saya kira saya harus menambahkan beberapa kait agar bisa berfungsi?
PierreE
Ya, contoh di atas menyarankan popup-createdan popup-delete- tergantung pada kasus penggunaan Anda, Anda mungkin perlu menyarankan fungsi yang berbeda.
sanityinc
2
Sangat lambat .
Alexander Shukaev
21

Berikut adalah salah satu opsi yang lebih kuat, hampir tidak merusak apa pun (kadang-kadang mode perusahaan menjadi pengecualian yang patut diperhatikan), tetapi tidak senyaman itu fill-column-indicator.

Gunakan format baris-header untuk menandai kolom ke-80 pada header.
Sesuatu seperti yang berikut ini sudah cukup:

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

Anda harus mengubah jumlah spasi dalam string pertama tergantung pada ukuran pinggiran kiri Anda. Tapi selain itu, ini harus bekerja dengan cukup baik. Ini tidak senyaman penggaris di buffer aktual, tetapi membantu.

Anda juga dapat mengaturnya agar berlaku hanya pada buffer pemrograman.

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

Hasil:
Anda harus mendapatkan sesuatu seperti berikut ini (baris pertama sebenarnya tidak ada di buffer, tetapi di header).

-------------------------------------------------------------------------------|
;; This is what your buffer should look like all the way up to column number 80.
(setq some-dummy-variable we-are-all-friends)
Malabarba
sumber
1
Perhatikan bahwa dalam Emacs 24.3 ini juga akan merusak Mode Perusahaan, setidaknya dalam beberapa kasus tepi. Emacs 24.3 gagal untuk benar baris header ke akun saat menghitung ketinggian jendela. Akibatnya Perusahaan gagal menggambar popup yang tepat dalam kasus-kasus di mana ketinggiannya penting, yaitu di bagian paling bawah buffer.
lunaryorn
1
Ini ide yang sangat menarik. Sayang sekali saya tidak dapat menandai dua jawaban sebagai benar, jawaban "patch fci" memiliki beberapa kekurangan dan tergantung pada keadaan, ini bisa menjadi pilihan yang lebih baik. Terima kasih!
Jorgen Schäfer
10
Ada juga M-x ruler-mode.
sanityinc
Ini tidak menarik mulai setelah angka (ketika nomor baris ditampilkan)
ideasman42
17

Setelah banyak penderitaan karena berbagai bug fill-column-indicatormemperkenalkan, saya menghilangkannya dari konfigurasi saya untuk selamanya.

Apa yang saya gunakan saat ini adalah fungsi bawaan Emacs untuk menyoroti garis yang terlalu panjang. Ini bahkan terlihat lebih baik, saya tidak akan mengaktifkan fill-column-indicatorsekarang bahkan jika itu bebas bug.

Sebagai permulaan, Anda dapat mengambil pengaturan saya:

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

Kemudian aktifkan di tempat yang Anda inginkan. Saya menggunakannya hanya dalam konteks pemrograman:

(add-hook 'prog-mode-hook #'whitespace-mode)
Mark Karpov
sumber
9

Apakah ada alternatif yang lebih baik?

Emacs 27 akan mendukung indikator kolom pengisian secara native melalui mode minor buffer-local display-fill-column-indicator-modedan mitra globalnya global-display-fill-column-indicator-mode.

Ini dia sedang beraksi:

masukkan deskripsi gambar di sini

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.
Kemangi
sumber
7

Halaman EmacsWiki ini memiliki banyak informasi tentang berbagai cara untuk menandai kolom tertentu atau memberi tahu Anda ketika Anda melewatinya.

Yang saya gunakan adalah Mode Line Position .

Tetapi yang lain termasuk menunjukkan garis vertikal pada kolom ( Penanda Kolom , Indikator Isi-Kolom ) dan menggunakan mode spasi untuk menyorot teks yang melewati kolom.

(Jika Anda membutuhkan baris yang berada jauh di sebelah kanan semua teks di semua baris, Anda selalu dapat mengaktifkannya picture-mode, tetapi itu mungkin berguna di sini hanya sebagai solusi sementara.)

Lihat juga Temukan Garis Panjang untuk cara menemukan garis panjang sesuai permintaan.

Drew
sumber
6

Tidak persis apa yang Anda inginkan, tetapi penguasa seperti @ Malabarba ♦ akan membuang-buang ruang, berikut ini solusi yang lebih baik:

Ada paket bawaanemacs-goodies-el (merekomendasikan untuk menginstalnya di terminal) bernama highlight-beyond-fill-column.el , tambahkan ini ke Anda .emacsatau 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" )))))

Teks lebih dari fill-column80 dalam potongan akan disorot dengan warna red. Anda dapat mengatur wajah sesuka Anda.

CodyChan
sumber
1

Karena fill-column-indicatorcukup berat, solusi ini menunjukkan karakter di sebelah kanan garis saat ini.

Jadi saat Anda mengetik, Anda dapat melihat batas garis sebelum Anda melampauinya.

Ini mendefinisikan mode minor 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))))

Jika Anda menggunakan evil-modedan ingin membatasi ini untuk memasukkan mode Anda dapat menambahkan kait berikut:

(add-hook 'evil-insert-state-entry-hook #'hl-line-margin-mode-enable)
(add-hook 'evil-insert-state-exit-hook #'hl-line-margin-mode-disable)
gagasanman42
sumber