(defun eshell-list-eshell-buffers ()
(interactive)
(let* ((eshell-buffers
(delq nil (mapcar (lambda (buf)
(when (eq 'eshell-mode (buffer-local-value 'major-mode buf))
(let* ((buf-name (buffer-name buf))
(buf-dir (buffer-local-value 'default-directory buf)))
(cl-list* buf-dir buf-name))))
(buffer-list)))))
eshell-buffers))
(defun eshell-switch-to-buffer ()
(interactive)
(let* ((eshell-buffers (eshell-list-eshell-buffers))
(eshell-buffers-dirs (mapcar #'car eshell-buffers))
(buf-dir (completing-read "Switch to eshell buffer: " eshell-buffers-dirs nil t))
(buf (assoc-default buf-dir eshell-buffers)))
(switch-to-buffer buf)))
大家觉得好用可以拿去用
2 个赞
几个小的代码建议:
-
eshell-list-eshell-buffers
不需要(interactive)
。
-
eshell-list-eshell-buffers
里,可以把(let* ((eshell-buffers EXPR)) eshell-buffers)
直接改写为EXPR
。
- 看到你用了几次
buffer-*
函数,可以用with-current-buffer
,然后直接引用变量名。
-
(cl-list* a b)
等价于 (cons a b)
。
-
(eq MODE major-mode)
约等于 (derived-mode-p MODE)
。
- 在
eshell-list-eshell-buffers
的λ中,看到你用了buf-name
,可以直接用buf
,因为switch-to-buffer
可以直接接受buffer实例。
-
(when (let* ((buf-name ...) (buf-dir ...)) ...))
,并且逻辑上来说buf-name
和buf-dir
不为nil,所以可以试试when-let
。
-
(delq nil (mapcar (λ ... (when-let ... EXPR)) ...))
可以改写成(mapcan (λ ... (when-let ... (list EXPR))))
。这里可以理解为,每次调用λ,会把结果列表append
到上一次的结果列表里面去。
-
completing-read
接受alist作为collection(只用其car
,忽略其cdr
),所以不用mapcar #‘car
,直接把eshell-buffers
给进去。
另外,如何区分多个不同的,且default-directory
在同一个文件夹的eshell buffer?
6 个赞
(defun campania/eshell-list-eshell-buffers ()
(mapcan (lambda (buf)
(with-current-buffer buf
(when (derived-mode-p 'eshell-mode)
(list (cons (buffer-name) default-directory)))))
(buffer-list)))
(defun campania/eshell-buffer-annotation-fn (str)
(let* ((dir-name (assoc-default str minibuffer-completion-table)))
(concat "\t\t" dir-name)))
(defun campania/eshell-switch-to-buffer ()
(interactive)
(let* ((eshell-buffers (campania/eshell-list-eshell-buffers))
(completion-extra-properties
'(:annotation-function campania/eshell-buffer-annotation-fn))
(buf-name (completing-read "Switch to eshell buffer: " eshell-buffers)))
(switch-to-buffer buf-name)))
照你说的改了一下,谢谢!
1 个赞
看到你用了cl-flet
,不知道你注意到docstring里提到没有,cl-flet
定义一个函数有简易写法,不用带λ。
(cl-flet ((foo (arg1 arg2) (+ arg1 arg2 42)))
(foo 1 2))
或者把cl-letf
替换成let
,然后把底下的#‘aux
换成aux
。
或者也可以直接省掉let
/ cl-flet
,直接把λ作为mapcan
的第一个参数。
3 个赞