emacs-libvterm
emacs-libvterm copied to clipboard
vterm and evil-mode
Many people use evil-mode
, but unfortunately, I know almost nothing about it. It would be great to collect known problems/workarounds regarding vterm+evil and add them to the README. Help (PRs) would greatly be appreciated in this respect.
In general, it would also be useful to know what vterm can do to support evil-mode
better.
Thanks
evil-collection
integrates with vterm
.
evil-collection/modes/vterm/evil-collection-vterm.el
Some evil-mode user use the cursor's shape and color as evil-state indicator, for example:
(setq evil-insert-state-cursor '(bar "#00FF00")
evil-visual-state-cursor '(box "#FF00FF")
evil-normal-state-cursor '(box "#E2E8EF"))
will set the cursor as a green bar in insert
state; a white box in normal
state; a magenta box in visual
state.
The problem with vterm is, sometimes it dose not respect the cursor shape. I don't know how to reproduce it consistently but sometimes after I leaved the vterm buffer then re-visit it, the cursor will change to bar shape while it should be a box shape.
One annoyance I have is the following scenario:
- Enter insert mode, type some text
- Enter normal mode, move cursor back a bit
- Enter insert mode, start typing
When doing step 3, the cursor jumps back to the end of the line when typing. I guess vterm doesn't track the cursor in normal mode as it does in insert mode (moving in insert mode using arrow keys work fine).
Using normal mode, it's possible to move the cursor out of the prompt (like vterm-copy-mode
), and in that case it makes sense that the cursor is reset when typing.
Ideally, when entering insert mode, the vterm cursor position should either be set to the current point if within the prompt, or to the last cursor position if outside it.
One annoyance I have is the following scenario:
- Enter insert mode, type some text
- Enter normal mode, move cursor back a bit
- Enter insert mode, start typing
When doing step 3, the cursor jumps back to the end of the line when typing. I guess vterm doesn't track the cursor in normal mode as it does in insert mode (moving in insert mode using arrow keys work fine).
Using normal mode, it's possible to move the cursor out of the prompt (like
vterm-copy-mode
), and in that case it makes sense that the cursor is reset when typing.Ideally, when entering insert mode, the vterm cursor position should either be set to the current point if within the prompt, or to the last cursor position if outside it.
Yes, we do not really support evil-mode
at the moment. My understanding is that the most common way to have it with vterm is to set evil-mode
to always use emacs-mode
(in vterm buffers), then, the shell is configured with a VI emulation mode.
One annoyance I have is the following scenario:
- Enter insert mode, type some text
- Enter normal mode, move cursor back a bit
- Enter insert mode, start typing
When doing step 3, the cursor jumps back to the end of the line when typing. I guess vterm doesn't track the cursor in normal mode as it does in insert mode (moving in insert mode using arrow keys work fine). Using normal mode, it's possible to move the cursor out of the prompt (like
vterm-copy-mode
), and in that case it makes sense that the cursor is reset when typing. Ideally, when entering insert mode, the vterm cursor position should either be set to the current point if within the prompt, or to the last cursor position if outside it.Yes, we do not really support
evil-mode
at the moment. My understanding is that the most common way to have it with vterm is to setevil-mode
to always useemacs-mode
(in vterm buffers), then, the shell is configured with a VI emulation mode.
Would someone be able to point to an example of how to set this up?
I think I can figure out the "always use emacs-mode
in vterm buffers" part, but how do I configure my shell for VI emulation? I'm using Oh My Zsh and vi-mode, which works in iTerm2, but I'm not sure how to get it to work in emacs vterm.
Some evil-mode user use the cursor's shape and color as evil-state indicator, for example:
(setq evil-insert-state-cursor '(bar "#00FF00") evil-visual-state-cursor '(box "#FF00FF") evil-normal-state-cursor '(box "#E2E8EF"))
will set the cursor as a green bar in
insert
state; a white box innormal
state; a magenta box invisual
state.The problem with vterm is, sometimes it dose not respect the cursor shape. I don't know how to reproduce it consistently but sometimes after I leaved the vterm buffer then re-visit it, the cursor will change to bar shape while it should be a box shape.
I have the same problem and I think I found a way to reproduce it.
- Enter insert mode
- List git branches on a git enabled folder using
git branch
- Press
q
to exitgit branch
After doing that, the cursor is shaped like it's on normal state, even though it's actually on insert state
One annoyance I have is the following scenario:
- Enter insert mode, type some text
- Enter normal mode, move cursor back a bit
- Enter insert mode, start typing
When doing step 3, the cursor jumps back to the end of the line when typing. I guess vterm doesn't track the cursor in normal mode as it does in insert mode (moving in insert mode using arrow keys work fine). Using normal mode, it's possible to move the cursor out of the prompt (like
vterm-copy-mode
), and in that case it makes sense that the cursor is reset when typing. Ideally, when entering insert mode, the vterm cursor position should either be set to the current point if within the prompt, or to the last cursor position if outside it.Yes, we do not really support
evil-mode
at the moment. My understanding is that the most common way to have it with vterm is to setevil-mode
to always useemacs-mode
(in vterm buffers), then, the shell is configured with a VI emulation mode.Would someone be able to point to an example of how to set this up?
I think I can figure out the "always use
emacs-mode
in vterm buffers" part, but how do I configure my shell for VI emulation? I'm using Oh My Zsh and vi-mode, which works in iTerm2, but I'm not sure how to get it to work in emacs vterm.
@yosevu I have the opposite issue, could you share how you set it to always use emacs-mode in vterm buffers? Below are some links on how to setup vi emulation for your shell bash zsh
One annoyance I have is the following scenario:
- Enter insert mode, type some text
- Enter normal mode, move cursor back a bit
- Enter insert mode, start typing
When doing step 3, the cursor jumps back to the end of the line when typing. I guess vterm doesn't track the cursor in normal mode as it does in insert mode (moving in insert mode using arrow keys work fine).
Using normal mode, it's possible to move the cursor out of the prompt (like
vterm-copy-mode
), and in that case it makes sense that the cursor is reset when typing.Ideally, when entering insert mode, the vterm cursor position should either be set to the current point if within the prompt, or to the last cursor position if outside it.
Does anyone please have some workaround for this? evil-mode
is my main motivation for migrating my terminal from urxvt to emacs.
One annoyance I have is the following scenario:
- Enter insert mode, type some text
- Enter normal mode, move cursor back a bit
- Enter insert mode, start typing
When doing step 3, the cursor jumps back to the end of the line when typing. I guess vterm doesn't track the cursor in normal mode as it does in insert mode (moving in insert mode using arrow keys work fine). Using normal mode, it's possible to move the cursor out of the prompt (like
vterm-copy-mode
), and in that case it makes sense that the cursor is reset when typing. Ideally, when entering insert mode, the vterm cursor position should either be set to the current point if within the prompt, or to the last cursor position if outside it.Does anyone please have some workaround for this?
evil-mode
is my main motivation for migrating my terminal from urxvt to emacs.
We do, https://github.com/Sbozzolo/vterm-extra This pakcage provide a function that copy the current command line to a new buffer then when edit finished, replace the old command line with the new command line
One annoyance I have is the following scenario:
- Enter insert mode, type some text
- Enter normal mode, move cursor back a bit
- Enter insert mode, start typing
When doing step 3, the cursor jumps back to the end of the line when typing. I guess vterm doesn't track the cursor in normal mode as it does in insert mode (moving in insert mode using arrow keys work fine). Using normal mode, it's possible to move the cursor out of the prompt (like
vterm-copy-mode
), and in that case it makes sense that the cursor is reset when typing. Ideally, when entering insert mode, the vterm cursor position should either be set to the current point if within the prompt, or to the last cursor position if outside it.Yes, we do not really support
evil-mode
at the moment. My understanding is that the most common way to have it with vterm is to setevil-mode
to always useemacs-mode
(in vterm buffers), then, the shell is configured with a VI emulation mode.Would someone be able to point to an example of how to set this up? I think I can figure out the "always use
emacs-mode
in vterm buffers" part, but how do I configure my shell for VI emulation? I'm using Oh My Zsh and vi-mode, which works in iTerm2, but I'm not sure how to get it to work in emacs vterm.@yosevu I have the opposite issue, could you share how you set it to always use emacs-mode in vterm buffers? Below are some links on how to setup vi emulation for your shell bash zsh
I think evil-emacs-state-modes
can be used for this purpose. I haven't tried it, but saw it discussed in this article: Living in Emacs
I don't use evil
, but I would expect the following to work:
(add-hook 'vterm-mode-hook (lambda () (setq evil-default-state 'emacs)))
This should force evil
to be in the emacs
state in vterm buffers, which in practice means that vi
keybindings are disabled and you can enable them in your shell.
Currently this works reasonably well:
(evil-define-key 'normal vterm-mode-map "h" 'vterm-send-left)
(evil-define-key 'normal vterm-mode-map "l" 'vterm-send-right)
(evil-define-key 'normal vterm-mode-map "b" 'vterm-send-M-b)
(evil-define-key 'normal vterm-mode-map "e" 'vterm-send-M-f)
(evil-define-key 'normal vterm-mode-map "db" 'vterm-send-C-w)
(evil-define-key 'normal vterm-mode-map "de" 'vterm-send-M-d)
(evil-define-key 'normal vterm-mode-map "p" 'vterm-yank)
(evil-define-key 'normal vterm-mode-map "P" '(lambda ()
(interactive)
(vterm-send-C-b)
(vterm-yank)))
It's not a like for like replacement, but basic movement can be added like this. I think you could replace most of the functionality like this. Only thing I'm really missing is selections for visual mode, is there a vterm way to send C-Space
to set a mark?
Currently this works reasonably well:
(evil-define-key 'normal vterm-mode-map "h" 'vterm-send-left) (evil-define-key 'normal vterm-mode-map "l" 'vterm-send-right) (evil-define-key 'normal vterm-mode-map "b" 'vterm-send-M-b) (evil-define-key 'normal vterm-mode-map "e" 'vterm-send-M-f) (evil-define-key 'normal vterm-mode-map "db" 'vterm-send-C-w) (evil-define-key 'normal vterm-mode-map "de" 'vterm-send-M-d) (evil-define-key 'normal vterm-mode-map "p" 'vterm-yank) (evil-define-key 'normal vterm-mode-map "P" '(lambda () (interactive) (vterm-send-C-b) (vterm-yank)))
It's not a like for like replacement, but basic movement can be added like this. I think you could replace most of the functionality like this. Only thing I'm really missing is selections for visual mode, is there a vterm way to send
C-Space
to set a mark?
Okay this actually works as a solution to the visual mode deletion:
(evil-define-key 'visual vterm-mode-map "d" 'vterm-send-M-w)
I'll try and put together a complete set of bindings that you could add to the README or something?
Currently this works reasonably well:
(evil-define-key 'normal vterm-mode-map "h" 'vterm-send-left) (evil-define-key 'normal vterm-mode-map "l" 'vterm-send-right) (evil-define-key 'normal vterm-mode-map "b" 'vterm-send-M-b) (evil-define-key 'normal vterm-mode-map "e" 'vterm-send-M-f) (evil-define-key 'normal vterm-mode-map "db" 'vterm-send-C-w) (evil-define-key 'normal vterm-mode-map "de" 'vterm-send-M-d) (evil-define-key 'normal vterm-mode-map "p" 'vterm-yank) (evil-define-key 'normal vterm-mode-map "P" '(lambda () (interactive) (vterm-send-C-b) (vterm-yank)))
It's not a like for like replacement, but basic movement can be added like this. I think you could replace most of the functionality like this. Only thing I'm really missing is selections for visual mode, is there a vterm way to send
C-Space
to set a mark?Okay this actually works as a solution to the visual mode deletion:
(evil-define-key 'visual vterm-mode-map "d" 'vterm-send-M-w)
I'll try and put together a complete set of bindings that you could add to the README or something?
What is the difference between this approach and, say, this?
Currently this works reasonably well:
(evil-define-key 'normal vterm-mode-map "h" 'vterm-send-left) (evil-define-key 'normal vterm-mode-map "l" 'vterm-send-right) (evil-define-key 'normal vterm-mode-map "b" 'vterm-send-M-b) (evil-define-key 'normal vterm-mode-map "e" 'vterm-send-M-f) (evil-define-key 'normal vterm-mode-map "db" 'vterm-send-C-w) (evil-define-key 'normal vterm-mode-map "de" 'vterm-send-M-d) (evil-define-key 'normal vterm-mode-map "p" 'vterm-yank) (evil-define-key 'normal vterm-mode-map "P" '(lambda () (interactive) (vterm-send-C-b) (vterm-yank)))
It's not a like for like replacement, but basic movement can be added like this. I think you could replace most of the functionality like this. Only thing I'm really missing is selections for visual mode, is there a vterm way to send
C-Space
to set a mark?Okay this actually works as a solution to the visual mode deletion:
(evil-define-key 'visual vterm-mode-map "d" 'vterm-send-M-w)
I'll try and put together a complete set of bindings that you could add to the README or something?
What is the difference between this approach and, say, this?
The issue with that approach is that you have to disable evil mode for that to work properly, otherwise your escape key will trigger evil instead of zsh vi mode. When in emacs mode no evil bindings will work e.g. evil tab navigation, evil leader key binds. Personally I have most emacs navigation functions such as: kill window and buffer bound to leader combinations like ,kw
. Copy and paste also becomes a bit of a nightmare of which shortcut do I use between these three modes.
Currently this works reasonably well:
(evil-define-key 'normal vterm-mode-map "h" 'vterm-send-left) (evil-define-key 'normal vterm-mode-map "l" 'vterm-send-right) (evil-define-key 'normal vterm-mode-map "b" 'vterm-send-M-b) (evil-define-key 'normal vterm-mode-map "e" 'vterm-send-M-f) (evil-define-key 'normal vterm-mode-map "db" 'vterm-send-C-w) (evil-define-key 'normal vterm-mode-map "de" 'vterm-send-M-d) (evil-define-key 'normal vterm-mode-map "p" 'vterm-yank) (evil-define-key 'normal vterm-mode-map "P" '(lambda () (interactive) (vterm-send-C-b) (vterm-yank)))
It's not a like for like replacement, but basic movement can be added like this. I think you could replace most of the functionality like this. Only thing I'm really missing is selections for visual mode, is there a vterm way to send
C-Space
to set a mark?Okay this actually works as a solution to the visual mode deletion:
(evil-define-key 'visual vterm-mode-map "d" 'vterm-send-M-w)
I'll try and put together a complete set of bindings that you could add to the README or something?
What is the difference between this approach and, say, this?
The issue with that approach is that you have to disable evil mode for that to work properly, otherwise your escape key will trigger evil instead of zsh vi mode. When in emacs mode no evil bindings will work e.g. evil tab navigation, evil leader key binds. Personally I have most emacs navigation functions such as: kill window and buffer bound to leader combinations like
,kw
. Copy and paste also becomes a bit of a nightmare of which shortcut do I use between these three modes.
I see, thanks.
What about the following (temporary) solution:
In vterm-extra
, there is a command vterm-extra-edit-command-in-new-buffer
. If you bind this function to a key, a new buffer appear where you can edit freely the command that will be sent to the terminal. The annoyance with this function is that for each command two additional keys have to pressed (one to enter in this mode, and one to leave it). What if I develop a similar minor-mode vterm-extra-minibuffer
. With this minor mode, if you press enter on the prompt line in vterm buffers, you'll end up in the minibuffer, where you can use your evil commands, then, when you are done, you press enter again and the command is sent to the vterm buffer. When this minor mode is activated, this would be the only way to send commands to vterm.
I propose this because it should be an easy extension of what I already have in vterm-extra
..
I had another idea. This is a very minimal sketch of a new minor mode, which at the moment is called vterm-extra-line-mode
.
(defvar vterm-extra-line-mode-map nil)
(setq vterm-extra-line-mode-map (make-sparse-keymap))
(define-key vterm-extra-line-mode-map (kbd "<return>")
'vterm-extra-read-and-send)
(define-minor-mode vterm-extra-line-mode "VTermLine"
"Vterm extra line mode."
(read-only-mode -1))
(defun vterm-extra-read-and-send ()
(interactive)
(let ((command (buffer-substring-no-properties
(vterm--get-prompt-point) (vterm--get-end-of-line))))
(vterm-send-C-a)
(vterm-send-C-k)
(vterm-send-string command)
(vterm-send-return)))
With this minor mode, the buffer is turned into writable, and you can use any evil command. When you hit enter, what is on screen is sent to vterm.
There's A LOT to be polished, but I think that this may be the core idea to enable using evil in the smoothest way. The idea is to send the updated string every time there's some interaction with the term, like hitting tab.
I am going to develop this as part of vterm-extra
initially.
I had another idea. This is a very minimal sketch of a new minor mode, which at the moment is called
vterm-extra-line-mode
.(defvar vterm-extra-line-mode-map nil) (setq vterm-extra-line-mode-map (make-sparse-keymap)) (define-key vterm-extra-line-mode-map (kbd "<return>") 'vterm-extra-read-and-send) (define-minor-mode vterm-extra-line-mode "VTermLine" "Vterm extra line mode." (read-only-mode -1)) (defun vterm-extra-read-and-send () (interactive) (let ((command (buffer-substring-no-properties (vterm--get-prompt-point) (vterm--get-end-of-line)))) (vterm-send-C-a) (vterm-send-C-k) (vterm-send-string command) (vterm-send-return)))
With this minor mode, the buffer is turned into writable, and you can use any evil command. When you hit enter, what is on screen is sent to vterm.
There's A LOT to be polished, but I think that this may be the core idea to enable using evil in the smoothest way. The idea is to send the updated string every time there's some interaction with the term, like hitting tab.
I am going to develop this as part of
vterm-extra
initially.
This sounds like an ideal solution! Can you link to the branch in vterm-extra
so I can try it out when there is some done? :)
One annoyance I have is the following scenario:
- Enter insert mode, type some text
- Enter normal mode, move cursor back a bit
- Enter insert mode, start typing
When doing step 3, the cursor jumps back to the end of the line when typing. I guess vterm doesn't track the cursor in normal mode as it does in insert mode (moving in insert mode using arrow keys work fine). Using normal mode, it's possible to move the cursor out of the prompt (like
vterm-copy-mode
), and in that case it makes sense that the cursor is reset when typing. Ideally, when entering insert mode, the vterm cursor position should either be set to the current point if within the prompt, or to the last cursor position if outside it.Yes, we do not really support
evil-mode
at the moment. My understanding is that the most common way to have it with vterm is to setevil-mode
to always useemacs-mode
(in vterm buffers), then, the shell is configured with a VI emulation mode.Would someone be able to point to an example of how to set this up? I think I can figure out the "always use
emacs-mode
in vterm buffers" part, but how do I configure my shell for VI emulation? I'm using Oh My Zsh and vi-mode, which works in iTerm2, but I'm not sure how to get it to work in emacs vterm.@yosevu I have the opposite issue, could you share how you set it to always use emacs-mode in vterm buffers? Below are some links on how to setup vi emulation for your shell bash zsh
I think
evil-emacs-state-modes
can be used for this purpose. I haven't tried it, but saw it discussed in this article: Living in Emacs
This piece of code can roughly handle this problem. After insert command, just moving shell point to the current point.
(defun evil-collection-vterm-insert (count &optional vcount skip-empty-lines)
(interactive
(list (prefix-numeric-value current-prefix-arg)
(and (evil-visual-state-p)
(memq (evil-visual-type) '(line block))
(save-excursion
(let ((m (mark)))
;; go to upper-left corner temporarily so
;; `count-lines' yields accurate results
(evil-visual-rotate 'upper-left)
(prog1 (count-lines evil-visual-beginning evil-visual-end)
(set-mark m)))))
(evil-visual-state-p)))
(evil-insert count vcount skip-empty-lines)
(let ((p (point)))
(vterm-reset-cursor-point)
(while (< p (point))
(vterm-send-left)
(forward-char -1))
(while (> p (point))
(vterm-send-right)
(forward-char 1))))
(evil-collection-define-key 'normal 'vterm-mode-map "i" 'evil-collection-vterm-insert)
I don't think it's reasonable for vterm to support some vi mode keybindings for the shell. It's what the shell itself should do (bash, zsh, fish, etc. all supports some vi editing mode). It's like that it's not reasonable for iTerm2.app or urxvt to support vi mode keybindings. Vterm as a terminal emulator, does not (and should not) know anything about the content of it's program, which may not even be a shell.
vterm and shell works in two separated layers and evil works at the vterm layer. Vterm (maybe together with evil) provides raw keystroke input to shell and inspects the output of the shell.
Some good integration features between evil and vterm would be:
- evil command "p" (paste) will send the content in kill ring as raw keystrokes to vterm
- enter evil insert state (from normal state) will place the cursor at the correct position
- provide better ways to define custom keybindings for vterm with evil
Some bad integration features between evil and vterm that we probably should not implement:
- evil command "d" to delete current shell command line
- evil command "a" to go to the beginning of the line of current line editing
For these feature requirements, people should look for "vterm custom keybindings" instead of "vterm evil integration"
Hi, a solution that would work for alternative modal editing schemes, such as xah-fly-keys, would be much appreciated.
after #455 is merged, command d
c
a
I
should work with:
(defun vterm-evil-insert ()
(interactive)
(vterm-goto-char (point))
(call-interactively #'evil-insert))
(defun vterm-evil-append ()
(interactive)
(vterm-goto-char (1+ (point)))
(call-interactively #'evil-append))
(defun vterm-evil-delete ()
"Provide similar behavior as `evil-delete'."
(interactive)
(let ((inhibit-read-only t)
)
(cl-letf (((symbol-function #'delete-region) #'vterm-delete-region))
(call-interactively 'evil-delete))))
(defun vterm-evil-change ()
"Provide similar behavior as `evil-change'."
(interactive)
(let ((inhibit-read-only t))
(cl-letf (((symbol-function #'delete-region) #'vterm-delete-region))
(call-interactively 'evil-change))))
(defun my-vterm-hook()
(evil-local-mode 1)
(evil-define-key 'normal 'local "a" 'vterm-evil-append)
(evil-define-key 'normal 'local "d" 'vterm-evil-delete)
(evil-define-key 'normal 'local "i" 'vterm-evil-insert)
(evil-define-key 'normal 'local "c" 'vterm-evil-change))
(add-hook 'vterm-mode-hook 'my-vterm-hook)
EDIT: d
c
should not work when your evil
is byte compiled ,
see https://github.com/emacs-evil/evil-collection/pull/448#issuecomment-770144854
please use https://github.com/emacs-evil/evil-collection/blob/master/modes/vterm/evil-collection-vterm.el instead.
And vterm-delete-region
doesn't work for zsh user, you need put this in your .zshrc,
# bind DEL to delete-char make `vterm-send-delete` delete char
bindkey "\e[3~" delete-char
Hey, thanks for all the work.
I'm running master with evil-collection and @jixiuf 's snippets.
Some observations and problem reports:
- Insert command works as expected.
- Append command works as expected, but there is a cursor position issue.
- Normal mode: ab[c]de ->
- Press 'a' ->
- Cursor shows after 'd': abcd|e ->
- Start typing X -> - The cursor moves and the input in inserted in the correct position: abcXX|de
- Delete and change do not work.
- The visual selection is deleted
- But as soon as I start typing again the line is restored to the previous state and I'm typing at the end of the line.
- @mjlbach talks about the same issue in https://github.com/hlissner/doom-emacs/pull/4373#issuecomment-739464602, although they seem to have solved the issue (?) It doesn't work for me.
I've added the following to my configuration and it might be useful to others.
(defun vterm-evil-append-line ()
"Provide similar behavior as `evil-append-line'."
(interactive)
(let ((inhibit-read-only t))
(vterm-end-of-line)
(vterm-evil-append)))
and then add (evil-define-key 'normal 'local "A" 'vterm-evil-append-line)
to the hook.
I've tried to define vterm-evil-insert-line
too, but I can't get vterm-beggining-of-line
to work, not even in Emacs mode.
Thanks again everyone.
@cobac I haven't gotten it working, I instead am trying to merge these changes upstream in evil-collection https://github.com/emacs-evil/evil-collection/pull/448
Note, I have a minimum test-case now where delete-region works/doesn't work. See: https://github.com/emacs-evil/evil-collection/pull/448#issuecomment-768765408
Evil mode works quite well for me in vterm.
I bound a bunch of additional emacs-libvterm functions in evil collection: https://github.com/emacs-evil/evil-collection/pull/448
And there was recently a follow-up PR which was recently merged: https://github.com/emacs-evil/evil-collection/pull/461
I'm not sure what remains to be done?
I'll post here a tip for users like me who don't need evil on the command line, but really would like to have it in copy-mode, which is also the behaviour that I use in the copy modes in tmux/alacritty. The vterm-mopy-mode-hook
is called for for both entering or exiting the mode, so I came up with the following use-package declaration:
(use-package vterm
:hook
(vterm-mode . evil-emacs-state)
(vterm-copy-mode . meliache/evil-normal-in-vterm-copy-mode)
:config
(defun meliache/evil-normal-in-vterm-copy-mode ()
(if (bound-and-true-p vterm-copy-mode)
(evil-normal-state)
(evil-emacs-state))))
I still seem to have issues when I ssh to another host from within vterm. Haven't debugged or looked into it to much yet...
I just tried out shell-mode
for the first time in a while and the evil integration there is seamless! Anyone know how it works and if the same approach could be applied to vterm? Is it because it's comint
-derived?
@mjlbach I really appreciate your evil-collection contribution -- it allowed me to switch from ZSH's vi emulation. But I think re-implementing evil operators one by one is ultimately a losing battle: we'll always be lagging behind, missing features, duplicating effort, etc, and users' customized evil bindings don't carry over. I don't have a better idea though 😞 (unless, again, we can somehow do what comint
/shell
does, which seems unlikely but idk).
Some evil-mode user use the cursor's shape and color as evil-state indicator, for example:
(setq evil-insert-state-cursor '(bar "#00FF00") evil-visual-state-cursor '(box "#FF00FF") evil-normal-state-cursor '(box "#E2E8EF"))
will set the cursor as a green bar in
insert
state; a white box innormal
state; a magenta box invisual
state.The problem with vterm is, sometimes it dose not respect the cursor shape. I don't know how to reproduce it consistently but sometimes after I leaved the vterm buffer then re-visit it, the cursor will change to bar shape while it should be a box shape.
For me this is reproducible with a simple ls command. After ls I am still in insert mode but the cursor shows normal mode. Here is a fix I found:
(use-package vterm
:config
(advice-add #'vterm--redraw :after (lambda (&rest args) (evil-refresh-cursor evil-state)))
)
I hope this is helpful to some :)