如何仅在 eshell 上覆盖键绑定?
How to overwrite a key binding only on eshell?
我在 emacs 上使用 evil-mode
,最近我开始使用 eshell
,我真的很喜欢我可以离开插入模式并移动到 eshell
缓冲区以复制内容或其他内容的方式好东西,但是当再次进入插入模式时它会在光标当前位置执行,我想要的是当我进入插入模式时自动将光标移动到提示行(最后一行,行尾)。
我所做的是:
(add-hook 'eshell-mode-hook
(lambda()
(define-key evil-normal-state-map (kbd "i") (lambda () (interactive) (evil-goto-line) (evil-append-line nil)))))
然而它在所有其他缓冲区中应用此映射,我只是想让它在 eshell 缓冲区上激活。
如何定义在 eshell 中工作方式不同的键绑定?
感谢@lawlist 为我指明了正确的方向,解决方案非常简单:
;; Insert at prompt only on eshell
(add-hook 'eshell-mode-hook
'(lambda ()
(define-key evil-normal-state-local-map (kbd "i") (lambda () (interactive) (evil-goto-line) (evil-append-line nil)))))
谢谢!
当前的 满足规定的要求,但有两个主要限制:
- 它仅在使用 i 进入插入模式时触发。
使用 I、A、a 或任何自定义 functions/keybindings 跳转到最后一行将需要额外的脚本。
- 如果
point
已经在最后一行(例如编辑当前命令时),则无法在当前位置进入插入模式;
i 有效反弹至 A.
第一个限制可以通过首先在 eshell-mode
上挂钩然后在 evil-insert-state-entry
上挂钩来消除。
第二个限制可以通过设置 point
的位置来解决,第一个基于行号,第二个基于只读 text-property:
- 如果
point
不在最后一行,则将其移至 point-max
(始终为读写)。
- 否则,如果
point
处的文本是只读的,point
将移动到当前行中只读文本 -属性 发生变化的位置。
以下代码否定了已接受答案的限制。
(defun move-point-to-writeable-last-line ()
"Move the point to a non-read-only part of the last line.
If point is not on the last line, move point to the maximum position
in the buffer. Otherwise if the point is in read-only text, move the
point forward out of the read-only sections."
(interactive)
(let* ((curline (line-number-at-pos))
(endline (line-number-at-pos (point-max))))
(if (= curline endline)
(if (not (eobp))
(let (
;; Get text-properties at the current location
(plist (text-properties-at (point)))
;; Record next change in text-properties
(next-change
(or (next-property-change (point) (current-buffer))
(point-max))))
;; If current text is read-only, go to where that property changes
(if (plist-get plist 'read-only)
(goto-char next-change))))
(goto-char (point-max)))))
(defun move-point-on-insert-to-writeable-last-line ()
"Only edit the current command in insert mode."
(add-hook 'evil-insert-state-entry-hook
'move-point-to-writeable-last-line
nil
t))
(add-hook 'eshell-mode-hook
'move-point-on-insert-to-writeable-last-line)
我在 emacs 上使用 evil-mode
,最近我开始使用 eshell
,我真的很喜欢我可以离开插入模式并移动到 eshell
缓冲区以复制内容或其他内容的方式好东西,但是当再次进入插入模式时它会在光标当前位置执行,我想要的是当我进入插入模式时自动将光标移动到提示行(最后一行,行尾)。
我所做的是:
(add-hook 'eshell-mode-hook
(lambda()
(define-key evil-normal-state-map (kbd "i") (lambda () (interactive) (evil-goto-line) (evil-append-line nil)))))
然而它在所有其他缓冲区中应用此映射,我只是想让它在 eshell 缓冲区上激活。
如何定义在 eshell 中工作方式不同的键绑定?
感谢@lawlist 为我指明了正确的方向,解决方案非常简单:
;; Insert at prompt only on eshell
(add-hook 'eshell-mode-hook
'(lambda ()
(define-key evil-normal-state-local-map (kbd "i") (lambda () (interactive) (evil-goto-line) (evil-append-line nil)))))
谢谢!
当前的
- 它仅在使用 i 进入插入模式时触发。 使用 I、A、a 或任何自定义 functions/keybindings 跳转到最后一行将需要额外的脚本。
- 如果
point
已经在最后一行(例如编辑当前命令时),则无法在当前位置进入插入模式; i 有效反弹至 A.
第一个限制可以通过首先在 eshell-mode
上挂钩然后在 evil-insert-state-entry
上挂钩来消除。
第二个限制可以通过设置 point
的位置来解决,第一个基于行号,第二个基于只读 text-property:
- 如果
point
不在最后一行,则将其移至point-max
(始终为读写)。 - 否则,如果
point
处的文本是只读的,point
将移动到当前行中只读文本 -属性 发生变化的位置。
以下代码否定了已接受答案的限制。
(defun move-point-to-writeable-last-line ()
"Move the point to a non-read-only part of the last line.
If point is not on the last line, move point to the maximum position
in the buffer. Otherwise if the point is in read-only text, move the
point forward out of the read-only sections."
(interactive)
(let* ((curline (line-number-at-pos))
(endline (line-number-at-pos (point-max))))
(if (= curline endline)
(if (not (eobp))
(let (
;; Get text-properties at the current location
(plist (text-properties-at (point)))
;; Record next change in text-properties
(next-change
(or (next-property-change (point) (current-buffer))
(point-max))))
;; If current text is read-only, go to where that property changes
(if (plist-get plist 'read-only)
(goto-char next-change))))
(goto-char (point-max)))))
(defun move-point-on-insert-to-writeable-last-line ()
"Only edit the current command in insert mode."
(add-hook 'evil-insert-state-entry-hook
'move-point-to-writeable-last-line
nil
t))
(add-hook 'eshell-mode-hook
'move-point-on-insert-to-writeable-last-line)