In zsh, with emacs key mapping mode, Control + _ will cancel a completion.
Example:
echo $EDITOR[tab]
will be completed as:
echo vim
Pressing Control + _ will restore the editor to:
echo $EDITOR
I want to do the same thing with vi key mapping mode.
Is there a way to do it? Is there already a key mapping to do it?
Control + _ does not work neither in insert mode nor in normal mode.
The u (undo) will remove the entire line.
I finally found how to do it.
bindkey -l will print a list of existing keymap names.
bindkey -M <keymap> will list all bindings for a given keymap.
So I compared emacs and viins bindings and added the following line:
bindkey -M viins "$key_info[Control]_" undo
to the .zprezto/modules/editor/init.zsh. And it works.
I made a pull request to add this mapping to prezto:
https://github.com/sorin-ionescu/prezto/pull/1860
Related
I want to set vi in editing mode in zsh (I am using oh-my-zsh) at start automatically when I open my shell, so at the beginning of my .zshrc I have tried the following code:
set -o vi
or
bindkey -v
but when pressing enter in the shell I cannot enter the vi mode.
If I tried one of the two commands in the shell, it works.
Basically I want zsh to start in vi edit mode.
Any ideas how to solve this problem?
bindkey -v is enough to enable vi mode in ZSH. If you are worried the setting will be overwritten by another plugin, put the setting at the bottom of your ~/.zshrc.
After vi mode is enabled, you enter the "insert" mode by default. To enter "normal" mode, use Esc. And i or a to switch back to "insert" mode.
BTW, softmoth/zsh-vim-mode is the most powerful vim mode plugin I've ever used in ZSH.
Using bindkey -v may take over functionality such as history search with control+R and control+S. To restore that particular behavior, add the following lines after bindkey -v:
bindkey ^R history-incremental-search-backward
bindkey ^S history-incremental-search-forward
Other bindings can be found in the ZSH manual Standard Widgets section.
If you are using https://ohmyz.sh/ you can add vi-mode to the list of plugins in ~/.zshrc:
plugins=(git vi-mode)
If you don't mind to use a plugin for vi mode in zsh, here is a better choice for you to quickly reach it.
zsh-vi-mode: A better and friendly vi(vim) mode plugin for ZSH.
After adding this plugin, then you can input with vi-mode like this:
Features
Cursor movement (Navigation).
Insert & Replace (Insert mode).
Text Objects.
Searching text.
Undo, Redo, Cut, Copy, Paste, and Delete.
Surrounds (Add, Replace, Delete, and Move Around).
Switch keywords (Increase/Decrease Number, Boolean, etc. In progress).
...
I am using the vi-mode plugin of oh-my-zsh. In my .zshrc, I have
bindkey '^[[3~' delete-char
where ^[[3~ is the escape code of my delete key. However, this only works in insert mode, but not in command mode. When I type
$ abcd
move the cursor to the beginning of the line and hit del in command mode, I get
$ ABCd
so apparently the character sequence of the delete key is interpreted literally. How can I make the delete key actually delete a character in command mode?
bindkey -a '^[[3~' delete-char
Zsh has a variety of different keymaps and by default, bindkey will bind keys in the normal insert mode keymap. The command mode keymap is selected with -M vicmd. -a is a shortcut for that. You can list the keymaps with bindkey -l. You'll see that there is also viopp which is used for movements after a key like c or d. There's also visual for visual selection mode.
It's 2020 now, and I'm not sure if #okapi 's answer is out of date or just missing a piece, but for me, I had to use:
bindkey -a '^[[3~' vi-delete-char
delete-char without the vi- prefix didn't do the trick but adding it did.
after installing prezto when I press CTRL - RIGHTARROW I can see these characters
source python;5C;5C;5C;5C
Whereas emacs key bindings like ALT- f work fine.
I just want my default keybindings where I can navigate using CTRL keys.
My efforts:
Raised a issue on github + browsed other similar issues as well.
Couldnt figure out how their solution would help my case.
Tried setting zstyle ':prezto:module:editor' key-bindings '' but it did not
work.
I have also checked modeles/editor/init.zsh but the script is
too long n I dont wanna make random changes and later keep
maintaining those.
Can anyone suggest a way so that my keybindings remain "UNCHANGED" even after .zpreztorc is loaded ?
If you're using the prezto editor module, it will override your key bindings. If you have it set to emacs mode with
zstyle ':prezto:module:editor' key-bindings 'emacs'
you will need to add your key bindings to that named keymap. You can do that with
bindkey -M emacs '^[[1;5C' forward-word
bindkey -M emacs '^[[1;5D' backward-word
This will need to be run after the editor module is loaded. You can do that by adding it to the bottom of your .zshrc file. I use the vi keymap, so I need to add the key bindings to both the viins and vicmd keymaps.
for keymap in 'emacs' 'viins' 'vicmd'; do
# [Ctrl-RightArrow] - move forward one word
bindkey -M $keymap '^[[1;5C' forward-word
# [Ctrl-LeftArrow] - move backward one word
bindkey -M $keymap '^[[1;5D' backward-word
done
unset keymap
I'm wondering if it's possible to write a zsh script that will write a command to the prompt but NOT execute it, i.e. leave it there for me to edit and then execute when I'm ready. I can do something like this with keybindings by leaving off the final '\C-m'. eg:
bindkey -s "\e[1;3C" "howdy!"
... I press Alt+RightArrow and the text "howdy!" is printed at the prompt and just left there.
I can also do something like what I want by writing my command to the history file and then recalling it with the up arrow. I've tried 'echo -n sometext' but it doesn't work.
Can I write a script that would exit leaving (say) " howdy! " on the command line? In actual fact I want the script to build up a complex command based on several things, but I want the script to leave it on the CLI for final editing, so automatic execution must be prevented.
Thanks in advance.
Turns out the answer is simple:
print -z $string-to-print
If you mean a zsh function and not an external script, you can write a zle (short for zsh line editor) widget and bind it to some key.
# define to function to use
hello () {
BUFFER=hello
zle end-of-line
}
# create a zle widget, which will invoke the function.
zle -N hello
# bindkey Alt-a to that widget
bindkey "\ea" hello
You can learn more from A User's Guide to the Z-Shell, Chapter 4.
Sometimes I want a filename instead of what zsh guesses for me. For example, I have a PNG file without a proper .png suffix, which makes zsh think it isn't a picture and won't list it when I type Tab to complete arguments of display.
I am wondering if there is a key sequence that completes for a filename wherever the context is, like ^XC for _correct_filename, or how to configure zsh to do the thing?
You can add a key binding to do what you want:
zle -C complete complete-word complete-files
bindkey '^X\t' complete
complete-files () { compadd - $PREFIX* }
Edit: Added $PREFIX
You can add those lines to your ~/.zshrc file.
That makes the completion list all files when you press Ctrl-x Tab at each step instead of Tab. You could choose another keystroke combination that suits you.
Or to make ImageMagick completions always include all files, try editing (make a backup first) the file /usr/share/zsh/functions/Completion/Unix/_imagemagick (or similar) and change this to comment out the existing line that begins with _files and add the new one shown:
if (( $# )); then
# _files "$#" -g "*.(#i)(${~formats//:/|})(-.)"
_files "$#"
return
fi
Dennis' answer didn't expand tilde for me, so I would get stuff like complete-files: no matches found: ~/ma* when I tried to invoke it on foo ~/ma. I did find an alternate in the zsh FAQ that will expand them, though:
zle -C complete-file complete-word _generic
zstyle ':completion:complete-file::::' completer _files
bindkey '^xF' complete-file