Emacs eshell。按下RET键如何读取命令行内容

5
我的意图是在按下RET时,为每个提示使用bm.el 可见书签。我已经在一定程度上实现了这一目标。如果代码中缺少重要的问题,请在下面进行评论,例如,我不知道是否需要处理除将它们传递给默认函数之外的参数。
当我在空命令行上按RET时,我不想将该行作为书签保存。如何在将控制权传递给默认函数eshell-send-input之前拦截命令行内容呢?
(defun eshell-send-input-zAp (&optional use-region queue-p no-newline)
  "eshell-send-input, customized to add bm-bookmark to prompt line"
 (interactive)
  (bm-bookmark-add)
  (eshell-send-input use-region queue-p no-newline))

(add-hook 'eshell-mode-hook
          #'(lambda ()
              (define-key eshell-mode-map
                [return]
                'eshell-send-input-zAp)))
3个回答

4
您的代码看起来不错。如果您阅读 eshell-send-input 的代码,您将了解如何获取当前输入内容。
同时,请查阅有关交互式参数的信息。使用 "P" 是将用户区域传递给 eshell-send-input 的必要条件。
(defun eshell-send-input-zAp (&optional use-region queue-p no-newline)
  "eshell-send-input, customized to add bm-bookmark to prompt line"
  (interactive "*P")
  (unless (string-equal (eshell-get-old-input use-region) "")
    (bm-bookmark-add))
  (eshell-send-input use-region queue-p no-newline))

它运行得很好。感谢您消除了困惑...在所有的帮助下,我正在逐渐破解这个elisp难题 :) - Peter.O

1

esh-mode 定义了一个变量 eshell-last-output-end,每次输出时都会更新它。因此,您可以通过类似于 (buffer-substring eshell-last-output-end (point-max)) 的方式获取要发送到 shell 的字符串。

编辑:从 eshel-send-input 文档中引用:

“将接收到的输入发送到 Eshell 进行解析和处理。在 eshell-last-output-end 之后,将所有文本从该标记到 point 作为输入发送。在该标记之前,调用 `eshell-get-old-input' 检索旧输入,将其复制到缓冲区的末尾并发送它。

如果 USE-REGION 非 nil,则当前区域(point 和 mark 之间)将用作输入。

如果 QUEUE-P 非 nil,则输入将排队等待下一个提示,而不是发送到当前活动进程。如果没有进程,则立即处理输入。

如果 NO-NEWLINE 非 nil,则输入将被发送而没有隐含的最终换行符。”

重点在于我。如果你查看eshel-send-input的源代码,你可能会了解它的使用方法。

回应event_jr的答案-如果你自己的函数没有这样的选项,你不一定需要向该函数传递通用参数...显然,到目前为止你还没有用到它,那就是不必要的。


我无法从eshell-last-output-end中运行任何内容。它的文档说:未记录为变量 - Peter.O
嗯... esh-modeeshel- 部分有点令人困惑,但似乎每个连字符分隔的名称片段都有自己的完成方式... 我似乎有太多 bash 的先入为主观念了...(现在正在阅读所有相关内容...) - Peter.O
谢谢提供这些好的参考资料。我学到了一些新的知识点(当然,在elisp和其他方面还有很多要学习的 :))。 - Peter.O

0
(回答自己的问题)...我意识到eshell本质上只是一个emacs缓冲区,因此,考虑到这一点,我想出了这种方法,它确实有效,但可能可以做得更好。也许有关于它的某些方面我还不知道,所以我仍然愿意听取建议。
(defun eshell-send-input-zAp (&optional use-region queue-p no-newline)
  "A customized `eshell-send-input`, to add bm-bookmark to prompt line" 
  (interactive)
  (let ((line (buffer-substring-no-properties (point-at-bol) (point-at-eol))))
    (if (string-match eshell-prompt-regexp line)
        (if (> (length (substring line (match-end 0))) 0)
            (bm-bookmark-add))))
  (eshell-send-input use-region queue-p no-newline))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接