現在受け入れられている回答は、記載されている要件を満たしていますが、2 つの大きな制限があります。
- で挿入モードに入ったときにのみトリガーされますi。I、A、 、または任意のカスタム関数/キーバインドを使用して最後の行にジャンプするにはa、追加のスクリプトが必要になります。
- がすでに最後の行にある場合
point(たとえば、現在のコマンドを編集している場合)、現在の位置で挿入モードに入る方法はありません。
iに効果的にリバウンドしAます。
最初の制限は、最初に on をフックし、eshell-mode次に 2 番目を on にフックすることで解消できますevil-insert-state-entry。
2 番目の制限はpoint、最初に行番号に基づいて、次に読み取り専用のtext-propertyに基づいて の位置を設定することで対処できます。
- まだ最後の行にない場合
pointは、point-max(常に読み書き可能) に移動されます。
- それ以外の場合、テキスト
pointが読み取り専用の場合pointは、読み取り専用の text-property が変更される現在の行の位置に移動されます。
次のコードは、受け入れられた回答の制限を無効にします。
(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)