Как я могу отобразить родительский каталог текущего файла в модельной строке?

11

Я хотел бы иметь возможность видеть местоположение родительского каталога текущего файла, независимо от текущего имени буфера.

secondplanet
источник
Может быть, использование библиотеки uniquify - желаемое решение (см. Ответ Жиля)
alex_1948511

Ответы:

12

Вы можете настроить формат строки режима по своему усмотрению. Если вы хотите показать родительский каталог вместе с именем буфера (обычно это имя файла, для буфера, который посещает файл), измените mode-line-buffer-identification; в противном случае добавьте запись в mode-line-format. Не существует встроенной конструкции для «родительского каталога текущего файла», поэтому вам нужно создать ее самостоятельно , например, с помощью :eval. Вот пример, который добавляет имя каталога после имени буфера и ничего не делает в буферах, которые не посещают файлы (включая Dired); Вы можете уточнить это с форматированием.

(defun mode-line-buffer-file-parent-directory ()
  (when buffer-file-name
    (concat "[" (file-name-nondirectory (directory-file-name (file-name-directory buffer-file-name))) "]")))
(setq-default mode-line-buffer-identification
      (cons (car mode-line-buffer-identification) '((:eval (mode-line-buffer-file-parent-directory)))))

Другой способ - установить переменную, содержащую текст, который вы хотите использовать find-file-hooks. Я также покажу, как вы можете установить свойства с помощью :propertizeконструкции.

(defvar buffer-file-parent-directory nil
  "Parent directory of the current directory.
This variable is nil if the current buffer isn't visiting a file.")
(make-variable-buffer-local 'buffer-file-parent-directory)
(put 'buffer-file-parent-directory 'permanent-local t)
(defconst mode-line-buffer-file-parent-directory
  '(:propertize (list buffer-file-parent-directory "/") face mode-line-buffer-id))
(defun set-buffer-file-parent-directory ()
  (when buffer-file-name
    (setq buffer-file-parent-directory
          (file-name-as-directory (file-name-nondirectory (directory-file-name (file-name-directory buffer-file-name)))))))
(add-hook 'find-file-hook 'set-buffer-file-parent-directory)
(let ((list mode-line-format))
  (while (not (eq (car list) 'mode-line-buffer-identification))
    (setq list (cdr list)))
  (setcdr list (cons (car list) (cdr list)))
  (setcar list 'mode-line-buffer-file-parent-directory))

Если вы действительно хотели иметь имя каталога на тот случай, если у вас есть несколько файлов с одинаковым именем в разных каталогах, Emacs имеет встроенную библиотеку uniquify . Когда будет несколько буферов с одним и тем же именем, эта библиотека заставляет имя буфера выглядеть file.ext<foo>и file.ext<bar>вместо file.extи file.ext<2>. Вы можете точно настроить формат, настроив uniquify-buffer-name-style.

(require 'uniquify)
Жиль "ТАК - перестань быть злым"
источник
9

Я предполагаю, что вы имеете в виду, что вы хотите видеть каталог вместо имени буфера.

(setq-default mode-line-buffer-identification
              '(:eval default-directory))

Или, если вы хотите, чтобы ваш домашний каталог был сокращен до ~/(вместо абсолютного имени файла из корня), то:

(setq-default mode-line-buffer-identification
              '(:eval (abbreviate-file-name default-directory)))

Или, если вам нужно только имя родительского каталога, в качестве одного имени компонента каталога, то:

(setq-default mode-line-buffer-identification
              '(:eval (file-name-nondirectory
                        (directory-file-name default-directory))))

Или, если вы хотите сохранить также имя буфера, как предполагает @Malabarba, то:

(setq-default mode-line-buffer-identification
              (let ((orig  (car mode-line-buffer-identification)))
                `(:eval (cons (concat ,orig (abbreviate-file-name default-directory))
                              (cdr mode-line-buffer-identification)))))

Дело в том, что вам просто нужно использовать значение default-directory(возможно, упрощенное от абсолютного имени, если хотите) в mode-line-buffer-identification. Вы можете установить для этой переменной только имя каталога или установить для него значение, которое также содержит имя буфера.

Если то, что вы просите, - это все, что вы хотите, просто настроить строку режима так default-directory, чтобы она отображалась, как бы вы ни хотели. Нет необходимости загружать несколько библиотек для этого (что и smart-mode-lineделает).

Нарисовалась
источник
1
Несмотря на его формулировку, я думаю , что он имел в виду «в дополнение к« не »вместо этого». Конечно, я могу ошибаться.
Малабарба
1
@ Малабарба: Возможно. Если так, то разница тривиальна - добавлено.
Дрю
7

Вы устанавливаете использовать smart-mode-line . Он настроен на отображение пути к файлу в строке режима, когда это актуально.

темная тема

Просто установите его, а затем включите его с помощью (sml/setup).

У этого также есть много особенностей, чтобы сделать этот показ более кратким. Например, «~ / .emacs.d /» заменяется на «: ED:» (и вы можете настроить дальнейшие замены).

Malabarba
источник