如何在modeline中显示当前文件的父目录?


11

我希望能够独立于当前缓冲区名称查看当前文件的父目录的位置。


也许使用uniquify库是理想的解决方案(请参阅Gilles的答案)
alex_1948511

Answers:


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.extfile.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
@Malabarba:也许吧。如果是这样,则差异微不足道-添加。
2014年

7

您安装使用 smart-mode-line 它被配置为在相关时在模式行中显示文件路径。

黑暗主题

只需安装它,然后使用打开它(sml/setup)

它还具有许多功能,可以使显示更加简洁。例如,“〜/ .emacs.d /”被替换为“:ED:”(您可以配置其他替换)。

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.