代码分享:在 Eshell 实现 fzf 般查找历史命令

那看来是 shell layer 的锅?

图片

没有啊

eshell-cmpl-expand-before-complete 呢?

图片

依然没有

不过我刚才看了一下 shell layer,确实是重度修改,还添加了许多不知道干啥用的插件

可能相关的配置:

(defun shell/init-eshell ()
  (use-package eshell
    :defer t
    :init
    (progn
      (spacemacs/register-repl 'eshell 'eshell)
      (setq eshell-cmpl-cycle-completions nil
            ;; auto truncate after 20k lines
            eshell-buffer-maximum-lines 20000
            ;; history size
            eshell-history-size 350
            ;; no duplicates in history
            eshell-hist-ignoredups t
            ;; buffer shorthand -> echo foo > #'buffer
            eshell-buffer-shorthand t
            ;; my prompt is easy enough to see
            eshell-highlight-prompt nil
            ;; treat 'echo' like shell echo
            eshell-plain-echo-behavior t
            ;; cache directory
            eshell-directory-name (concat spacemacs-cache-directory "eshell/"))

      (when shell-protect-eshell-prompt
        (add-hook 'eshell-after-prompt-hook 'spacemacs//protect-eshell-prompt))

      (autoload 'eshell-delchar-or-maybe-eof "em-rebind")

      (add-hook 'eshell-mode-hook 'spacemacs//init-eshell)
      (add-hook 'eshell-mode-hook 'spacemacs/disable-hl-line-mode))
    :config
    (progn

      ;; Work around bug in eshell's preoutput-filter code.
      ;; Eshell doesn't call preoutput-filter functions in the context of the eshell
      ;; buffer. This breaks the xterm color filtering when the eshell buffer is updated
      ;; when it's not currently focused.
      ;; To remove if/when fixed upstream.
      (defun eshell-output-filter@spacemacs-with-buffer (fn process string)
        (let ((proc-buf (if process (process-buffer process)
                          (current-buffer))))
          (when proc-buf
            (with-current-buffer proc-buf
              (funcall fn process string)))))
      (advice-add
       #'eshell-output-filter
       :around
       #'eshell-output-filter@spacemacs-with-buffer)

      (require 'esh-opt)

      ;; quick commands
      (defalias 'eshell/e 'find-file-other-window)
      (defalias 'eshell/d 'dired)
      (setenv "PAGER" "cat")

      ;; support `em-smart'
      (when shell-enable-smart-eshell
        (require 'em-smart)
        (setq eshell-where-to-jump 'begin
              eshell-review-quick-commands nil
              eshell-smart-space-goes-to-end t)
        (add-hook 'eshell-mode-hook 'eshell-smart-initialize))

      ;; Visual commands
      (require 'em-term)
      (mapc (lambda (x) (push x eshell-visual-commands))
            '("el" "elinks" "htop" "less" "ssh" "tmux" "top"))

      ;; automatically truncate buffer after output
      (when (boundp 'eshell-output-filter-functions)
        (push 'eshell-truncate-buffer eshell-output-filter-functions))

      ;; These don't work well in normal state
      ;; due to evil/emacs cursor incompatibility
      (evil-define-key 'insert eshell-mode-map
        (kbd "C-k") 'eshell-previous-matching-input-from-input
        (kbd "C-j") 'eshell-next-matching-input-from-input))))

(defun shell/init-eshell-prompt-extras ()
  (use-package eshell-prompt-extras
    :commands epe-theme-lambda
    :init
    (setq eshell-highlight-prompt nil
          eshell-prompt-function 'epe-theme-lambda)))

(defun shell/init-eshell-z ()
  (use-package eshell-z
    :defer t
    :init
    (with-eval-after-load 'eshell
      (require 'eshell-z))))

其中的一个变量 shell-enable-smart-eshell 我这里设置为 nil

用过 neovim 的内嵌终端,就会觉着 Eshell 有点鸡肋的感觉。

像 fzf 这种需求根本不是事儿。 ๑乛ェ乛๑

1 个赞

求终端的字体 :smiley:

vim 用户又来砸场子 :joy:

额,身份被发现了吗?( ´◔ ‸◔’)

上面有很多终端截图,不知道你要哪位同学的截图呢?

这论坛如果回复上一楼的话是不会显示回复的是哪个贴的。比如现在这样。

所以默认回复的就是这个楼上

我没有用过 neovim, 比较好奇neovim 的内嵌终端,是ternimal emulator 还是 shell, Eshell 可以一个真正的Shell吖,除了top 这种强交互的命令没办法比较好滴处理之外,其他日常的命令都是用elisp 重写了的,这才是真正跨平台的shell ,最重要的是和Emacs 完美整合,即可以解析 shell 语法,可以解析 lisp 语法.只是文档少,用的人也不多

neovim 的内嵌终端和 eshell 应该都算 terminal emulator 吧?不太相信日常命令都用 elisp 重写了的这种做法。。。neovim 终端能应对 top 这种强交互的命令,因为它就是个 真正意义上的终端 ,和其它终端一模一样的……额……“终端”。

言尽于此。你何不自己花点时间尝试一下呢?

(defsubst eshell/ls (&rest args)
  "An alias version of `eshell-do-ls'."
  (let ((insert-func 'eshell-buffered-print)
	(error-func 'eshell-error)
	(flush-func 'eshell-flush))
    (apply 'eshell-do-ls args)))

(put 'eshell/ls 'eshell-no-numeric-conversions t)

(declare-function eshell-glob-regexp "em-glob" (pattern))

(defun eshell-do-ls (&rest args)
  "Implementation of \"ls\" in Lisp, passing ARGS."
  (funcall flush-func -1)
  ;; Process the command arguments, and begin listing files.
  (eshell-eval-using-options
   "ls" (if eshell-ls-initial-args
	    (list eshell-ls-initial-args args)
	  args)
   `((?a "all" nil show-all
	 "do not ignore entries starting with .")
     (?A "almost-all" nil show-almost-all
	 "do not list implied . and ..")
     (?c nil by-ctime sort-method
	 "sort by last status change time")
     (?d "directory" nil dir-literal
	 "list directory entries instead of contents")
     (?k "kilobytes" 1024 block-size
	 "using 1024 as the block size")
     (?h "human-readable" 1024 human-readable
	 "print sizes in human readable format")
     (?H "si" 1000 human-readable
	 "likewise, but use powers of 1000 not 1024")
     (?I "ignore" t ignore-pattern
	 "do not list implied entries matching pattern")
     (?l nil long-listing listing-style
	 "use a long listing format")
     (?n "numeric-uid-gid" nil numeric-uid-gid
	 "list numeric UIDs and GIDs instead of names")
     (?r "reverse" nil reverse-list
	 "reverse order while sorting")
     (?s "size" nil show-size
	 "print size of each file, in blocks")
     (?t nil by-mtime sort-method
	 "sort by modification time")
     (?u nil by-atime sort-method
	 "sort by last access time")
     (?x nil by-lines listing-style
	 "list entries by lines instead of by columns")
     (?C nil by-columns listing-style
	 "list entries by columns")
     (?L "dereference" nil dereference-links
	 "list entries pointed to by symbolic links")
     (?R "recursive" nil show-recursive
	 "list subdirectories recursively")
     (?S nil by-size sort-method
	 "sort by file size")
     (?U nil unsorted sort-method
	 "do not sort; list entries in directory order")
     (?X nil by-extension sort-method
	 "sort alphabetically by entry extension")
     (?1 nil single-column listing-style
	 "list one file per line")
     (nil "dired" nil dired-flag
	  "Here for compatibility with GNU ls.")
     (nil "help" nil nil
	  "show this usage display")
     :external "ls"
     :usage "[OPTION]... [FILE]...
List information about the FILEs (the current directory by default).
Sort entries alphabetically across.")
   ;; setup some defaults, based on what the user selected
   (unless block-size
     (setq block-size eshell-ls-default-blocksize))
   (unless listing-style
     (setq listing-style 'by-columns))
   (unless args
     (setq args (list ".")))
   (let ((eshell-ls-exclude-regexp eshell-ls-exclude-regexp) ange-cache)
     (when ignore-pattern
       (unless (eshell-using-module 'eshell-glob)
	 (error (concat "-I option requires that `eshell-glob'"
			" be a member of `eshell-modules-list'")))
       (set-text-properties 0 (length ignore-pattern) nil ignore-pattern)
       (setq eshell-ls-exclude-regexp
	     (if eshell-ls-exclude-regexp
		 (concat "\\(" eshell-ls-exclude-regexp "\\|"
			 (eshell-glob-regexp ignore-pattern) "\\)")
	       (eshell-glob-regexp ignore-pattern))))
     ;; list the files!
     (eshell-ls-entries
      (mapcar (lambda (arg)
		(cons (if (and (eshell-under-windows-p)
			       (file-name-absolute-p arg))
			  (expand-file-name arg)
			arg)
		      (eshell-file-attributes
		       arg (if numeric-uid-gid 'integer 'string))))
	      args)
      t (expand-file-name default-directory)))
   (funcall flush-func)))

包括 ls cd cp ln mv rm pwd env man cat exit info time grep diff kill make ... 都用 elisp 重新实現/包装了。

是楼主的,第一张图

同学,你应该了解一下什么叫Shell, 什么叫 terminal emulator. 附上 Reddit 关于Eshell 的帖子一篇,里面有一句话说得非常好:

It’s important to understand that shells are not (or should not be) semantically bound to terminal emulator restrictions. Shells are a textual interface to the machine

FantasqueSansMono

1 个赞

这种通篇全是“畅想”,没有实操,罔顾实际使用体验的文章,还是少看为妙。

1 个赞

预告:之前想介绍下 neovim 的内嵌终端,不过拖延症犯了,一直到现在还是 draft 状态。。。

我今明两天尽快把文章写完发出来 =՞ェ ՞=

那个看起来像是terminal emulator,在Emacs中对应应该是term/ansi-term/emacs-libvterm(3rd-party). 目前来看,功能比较完善的是emacs-libvterm,缺陷是性能不及native。而term/ansi-term对一些复杂的显示的处理还不够好。