eshell buffer 里获得shell的信息,比如pwd

怎么在eshell buffer里用lisp获得当前目录?

我想让Emacs自动把eshell buffer的名字改成当前eshell目录,方便我区分各个eshell buffer。

pwd 函数获取当前目录, pwd 使用lisp 重写, 本质上就是调用Lisp 函数:

把eshell buffer的名字改成当前eshell目录

(rename-buffer (pwd))

Emacs自动把eshell buffer的名字改成当前eshell目录

(add-hook 'eshell-mode-hook (lambda () (rename-buffer (pwd)))

1 个赞

default-directory 获得当前路径,所有 Buffer 都如此。

加上路径信息不见得能达到这个目的,当前路径可能一直在变化当中,不同的 Eshell 访问到同样的路径也有可能。

(defun my-eshell-rename-buffer ()
  (rename-buffer (format "*eshell %s*" default-directory)))

(defun my-eshell-mode-setup ()
  (add-hook 'eshell-after-prompt-hook #'my-eshell-rename-buffer))

(add-hook 'eshell-mode-hook #'my-eshell-mode-setup)
1 个赞
;; cd变换目录或执行其它命令时,将buffer name改成上次执行的命令,及当前目录
(defadvice eshell-send-input (around change-buffer-name activate)
  "change-buffer-name."
  (let ((input (eshell-get-old-input))
        (eshell-buffer )
        )
    ad-do-it
    (setq eshell-buffer (generate-new-buffer-name (format "*eshell* %s (%s)"  input default-directory)))
    (rename-buffer eshell-buffer)
   ))

https://github.com/jixiuf/vmacs/blob/master/lazy/lazy-toggle-eshell.el#L82

(global-set-key [f2] 'toggle-eshell)
(global-set-key [C-f2] 'toggle-eshell-cd)
如果按了C-u ,则列出所有的eshell buffer 供选择

实现了在当前buffer 所在目录打开eshell, 打开的多个eshell共享相同的history

2 个赞

原来default-directory就行……

eshell有一个专门的hook

(defun eshell-sync-dir-buffer-name ()
  "Change eshell buffer name by directory change."
  (when (equal major-mode 'eshell-mode)
    (rename-buffer (format "Esh: %s" (replace-regexp-in-string (expand-file-name "~") "~" default-directory)))))

(add-hook 'eshell-directory-change-hook #'eshell-sync-dir-buffer-name)

话说有专门把完整地址转为缩写地址的函数吗? 比如 /Users/yuan/xxx -> ~/xxx

1 个赞

有:abbreviate-file-name,举例:

default-directory
;; => "~/"

(expand-file-name default-directory)
;; => "/Users/xcy/"

(abbreviate-file-name "/Users/xcy/")
;; => "~/"

我一直用的是这个,来自

EmacsWiki: Eshell Prompt

(defun fish-path (path max-len)
  "Return a potentially trimmed-down version of the directory PATH, replacing
parent directories with their initial characters to try to get the character
length of PATH (sans directory slashes) down to MAX-LEN."
  (let* ((components (split-string (abbreviate-file-name path) "/"))
         (len (+ (1- (length components))
                 (reduce '+ components :key 'length)))
         (str ""))
    (while (and (> len max-len)
                (cdr components))
      (setq str (concat str
                        (cond ((= 0 (length (car components))) "/")
                              ((= 1 (length (car components)))
                               (concat (car components) "/"))
                              (t
                               (if (string= "."
                                            (string (elt (car components) 0)))
                                   (concat (substring (car components) 0 2)
                                           "/")
                                 (string (elt (car components) 0) ?/)))))
            len (- len (1- (length (car components))))
            components (cdr components)))
    (concat str (reduce (lambda (a b) (concat a "/" b)) components))))
1 个赞