Snippet share

在 Eshell 中像 fzf 那般搜索历史命令

Updated on 2017-12-17 15:51 (Created on: 2017-12-17 15:46)

fzf

我的主力Shell 是Eshell, 但是平时我也会用Zsh, 而 fzf 是一个非常好用的命令行工具,用了fzf 搜索 历史命令: fzf

Eshell

我日常的操作基本都是在 Eshell 上面进行的,不过 Eshell 是没办法直接像 Bash 那样调 用 fzf 来查找命令历史的,所以我希望把这个功能迁移到到 Eshell 上面来。我在 Emacs 使用的补全框架是 Ivy/Counsel,它有一个 counsel-esh-history的命令可以使 用 Ivy 来搜索命令,但是没办法使用用户已经输入的内容来过滤命令,所以我就在自己 折腾了一个 counsel-esh-history 命令。效果如下: eshell

感觉很不错嘛 :)

源代码

得益于 Ivy,代码也很少,完整代码如下:

(defun samray/esh-history ()
  "Interactive search eshell history."
  (interactive)
  (require 'em-hist)
  (save-excursion
    (let* ((start-pos (eshell-bol))
	   (end-pos (point-at-eol))
	   (input (buffer-substring-no-properties start-pos end-pos)))
      (let* ((command (ivy-read "Command: "
				(delete-dups
				 (when (> (ring-size eshell-history-ring) 0)
				   (ring-elements eshell-history-ring)))
				:preselect input
				:action #'ivy-completion-in-region-action))
	     (cursor-move (length command)))
	(kill-region (+ start-pos cursor-move) (+ end-pos cursor-move))
	)))
  ;; move cursor to eol
  (end-of-line)
  )

我也顺便把代码分享到 Emacs社区