Giter Site home page Giter Site logo

marlonrichert / zsh-edit Goto Github PK

View Code? Open in Web Editor NEW
112.0 5.0 7.0 117 KB

πŸ›  Better command line editing tools for Zsh

License: MIT License

Shell 100.00%
zsh widgets subword-editing clipboard-viewer zsh-plugin subwords keyboard-commands keyboard-shortcuts zsh-configuration zsh-plugins

zsh-edit's Introduction

Zsh Edit

Zsh Edit is a set of handy utilities for making life easier on the Zsh command line.

Requirements

Tested to work with Zsh 5.8 and newer.

Installating & updating

I recommend using Znap or installing the plugin manually. You can also install it using any 3rd-party framework or plugin manager you like, but I won't document that here.

Using Znap

Aust add this to your .zshrc file:

znap source marlonrichert/zsh-edit

To update, run znap pull.

Manually

  1. Clone the repo:
    % git clone --depth 1 https://github.com/marlonrichert/zsh-edit.git
  2. Source the plugin in your .zshrc file:
    source <your plugins dir>/zsh-edit/zsh-edit.plugin.zsh
  3. Restart your shell:
    exec zsh

To update:

% cd <your plugins dir>/zsh-edit
% git pull

bind Command

Bind shell commands directly to keyboard shortcuts. What's more, when using these, your current command line will be left intact.

bind  '^[:' 'cd ..'
bind  '^[-' 'pushd -1' \
      '^[=' 'pushd +0'

List duplicate keybindings in the main keymap or another one.

bind -d
bind -dM viins

List unused keybindings in the main keymap or another one.

bind -u
bind -uM emacs

Look up which combination of keys could generate an escape sequence listed by bind or bindkey.

% bind -n '^[[5~' '^[^[OA'
"^[[5~"    PageUp
"^[^[OA"   Alt-Up

Key Bindings

Zsh Edit adds the keyboard shortcuts below to your main and emacs keymaps.

  • By default, the emacs keymap is your main keymap.
  • However, if you use vi mode, then your main keymap will be the viins keymap.

All key bindings can be modified through Zsh's bindkey command, after sourcing Zsh Edit.

⚠️ Note:

  • Not all terminals support all key bindings.
  • In some terminals, instead of Alt, you'll have to press Esc or Ctrl[.
  • In many terminals, Home, End, PgUp and PgDn scroll the terminal buffer and don't send any keystrokes to the shell. To use these keys in the shell, you'll have to hold an additional modifier key, usually Shift. Refer to your terminal's documentation and/or settings for more info.
Command emacs keymap main keymap
Redo (reverse Undo) Alt/
Recover last line aborted with CtrlC or CtrlG CtrlAltG
Replace all Ctrl]
Reverse yank pop AltY
Repeat word up Alt.
Repeat word down Alt,
Repeat word left CtrlAlt-
Repeat word right AltShift-
Backward subword CtrlAltB Ctrl← CtrlAlt←
Forward subword CtrlAltF Ctrl→ CtrlAlt→
Backward shell word AltB Alt← Shift←
Forward shell word AltF Alt→ Shift→
Beginning of line CtrlA Home CtrlX ←
End of line CtrlE End CtrlX β†’
Beginning of buffer Alt< PgUp CtrlX ↑
End of buffer Alt> PgDn CtrlX ↓
Backward delete character ⌫
Forward delete character ⌦
Backward kill subword CtrlH Ctrl⌫ AltCtrl⌫
Forward kill subword CtrlAltD Ctrl⌦ AltCtrl⌦
Backward kill shell word CtrlW Alt⌫ Shift⌫
Forward kill shell word AltD Alt⌦ Shift⌦
Backward kill line CtrlU CtrlShift⌫ CtrlX ⌫
Forward kill line CtrlK CtrlShift⌦ CtrlX ⌦

Replace All Occurences of a Character

Press Ctrl] followed by two characters and each substring consisting of one or more occurences of the first character will be replaced entirely with the second character. This is useful, for example, if you pasted a list of files separated by line breaks into the command line, but you need them to be separated with spaces instead.

If you've just pasted something or the region is active, only the pasted or selected text is affected. This way, you can find-and-replace selectively. Otherwise, this widget always operates on the whole command line.

Clipboard Viewer

Whenever you use yank (^Y in emacs), vi-put-after (p in vicmd) or vi-put-after (P in vicmd) to paste a kill into the command line, Zsh Edit will list the contents of your kill ring (including the cut buffer) below your command line. In addition, Zsh Edit eliminates all duplicate kills from your kill ring. Thus, each entry listed is guaranteed to be unique.

Furthermore, after pasting, when you use yank-pop (^[y in emacs), Zsh Edit will show you which kill is currently selected, making it easier to cycle to the right one. To view your clipboard at any time – without modifying your command line – just press yank-pop by itself.

Finally, Zsh Edit adds a new widget reverse-yank-pop, which lets you cycle in the opposite direction. It is bound to ^[Y in the emacs keymap.

Subword Movement

Zsh's widgets forward-word, backward-word, kill-word and backward-kill-word fail to stop on many of the positions that we humans see as word boundaries:

# Zsh with default WORDCHARS='*?_-.[]~=/&;!#$%^(){}<>' moves/deletes way too much:
#              >       >             >             >          >
% ENV_VAR=value command --option-flag camelCaseWord ~/dir/*.ext
# <             <       <             <             <

# Zsh with  WORDCHARS='' is bit better, but skips punctuation clusters & doesn't find subWords:
#    >   >     >         >      >    >               >     >
% ENV_VAR=value command --option-flag camelCaseWord ~/dir/*.ext
# <   <   <     <         <      <    <               <     <

Zsh Edit adds new widgets with better parsing rules that can find all the word boundaries that matter to us as humans. Additionally, it adds smarter movement: If the cursor is inside a word, it will move to the beginning or end of that same word, not the next one. This way, you can quickly toggle between the beginning and the end of each word.

For example:

# Zsh Edit with WORDCHARS=''
#   >   >     >       >  >     >    >     >   >   >  >  >      >
% ENV_VAR=value command --option-flag camelCaseWord ~/dir/?*.ext
# <   <   <     <       < <      <    <    <   <    < <      <

To stop a character from being treated as a subword separator, simply add it to $WORDCHARS. For example, by treating ~, * and ? as word characters, you can get more precise subword movement in path strings:

# Zsh Edit with WORDCHARS='~*?'
#  > >   >  >   >
% cd ~/dir/?*.ext
# <  < <   <  <

If you don't want to change your $WORDCHARS globally, you can instead use the following:

zstyle ':edit:*' word-chars '~*?'

This will change $WORDCHARS only for the widgets provided by Zsh Edit.

Author

Β© 2020-2023 Marlon Richert

License

This project is licensed under the MIT License. See the LICENSE file for details.

zsh-edit's People

Contributors

knu avatar marlonrichert avatar quarticcat avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

zsh-edit's Issues

Using bindings results in "No such shell function `.edit.subword'" error

Describe the bug

When trying to use any binding provided by zsh-edit, I run into this error message:

No such shell function `.edit.subword'

Additionally, it seems that when trying to use zsh-edit on a fresh machine, I'm also seeing (or similar depending on which binding is used):

No such widget `.backward-shell-word'

Steps To Reproduce

I reproduced this on a fresh Ubuntu 20.04 VM with git and zsh packages installed.

  1. Put this in .zshrc
# Created by newuser for 5.8
source ~/zsh-snap/znap.zsh

znap source marlonrichert/zsh-edit
  1. Open zsh.
  2. Use Alt+Left/Right shortcut.
  3. See the issue

Expected behavior

I expected the bindings to move by a shell/subword as it did before.

Observed behavior

Using the key binding resulted in an error:

No such shell function `.edit.subword'

Environment:

  • OS: Ubuntu 20.04 and 22.04
  • Terminal: Gnome Terminal and kitty
  • Zsh version: 5.8 and 5.8.1
  • Repo version: * main 98ae841 Update GitHub tests to `ubuntu-latest`

Additional context

The issue seems to have been introduced by faf5a1e

fast-syntax-highlighting warning: "zsh-syntax-highlighting: unhandled ZLE widget 'reverse-yank-pop'"

Describe the bug

When enable plugins zsh-edit and fast-syntax-highlighting together, fast-syntax-highlight will display a warning about reverse-yank-pop:

zsh-syntax-highlighting: unhandled ZLE widget 'reverse-yank-pop'

I figured out this warning message is caused by doing bindkey <keys> reverse-yank-pop without creating the 'reverse-yank-pop' widget with zle -N or zle -C.), it can be fixed by add the following line:

  # File: https://github.com/marlonrichert/zsh-edit/blob/9eb286982f96f03371488e910e42afb23802bdfd/functions/zsh-edit#L108-L109
  bindkey -M emacs  '^[/' redo \
                    '^[Y' reverse-yank-pop
+ zle -N reverse-yank-pop .edit.visual-yank

I saw zsh-edit-precmd() will handle zle -N reverse-yank-pop .edit.visual-yank,
but it may must be executed before the plugin fast-syntax-highlighting is loaded.

Steps To Reproduce

Just install these two plugins with Oh My Zsh:

plugins=("fast-syntax-highlighting" "zsh-edit")
source "${HOME}/.oh-my-zsh/oh-my-zsh.sh"

Expected behavior

No warning message.

Observed behavior

Click to expand

Environment:

  • OS: macOS 14.2.1
  • Terminal: iTerm2
  • Zsh version: 5.9
  • Repo version: zsh-edit 113a0d5

Additional context

None

Error message 'no such keymap' after upgrading plugin

Just upgraded zsh-edit after a month or so and suddenly I receive the following message on load:

(anon):bindkey:26: no such keymap `menuselect'
(anon):bindkey:27: no such keymap `menuselect'

All used to work fine prior this update.

One character subwords are treated differently from two+ character subwords

Describe the bug

I'm not sure if this is intentional, but subword operations depend on the length and look inconsistent.

Steps To Reproduce

Example 1

# Given this behavior:

% ee foo
# _ <- cursor is at `e`
# Type M-x forward-subword
% ee foo
#   _ <- cursor stops at the space

# I'd expect the same if it was a one character subword:

% e foo
# _ <- cursor is at `e`
# Type M-x forward-subword

Example 2

# Given this behavior:

% anHour 60
# _ <- cursor is at `a`
# Type M-x kill-subword
% Hour 60
# _ <- Only `an` is deleted as one subword

# I'd expect the same if it was a one character subword:

% aMinute 60
# _ <- cursor is at `a`
# Type M-x kill-subword

Expected behavior

Example 1

% e foo
# _ <- cursor is at `e`
# M-x forward-subword
% e foo
#  _ <- cursor should stop at the space

Example 2

% aMinute 60
# _ <- cursor is at `a`
# M-x kill-subword
% Minute 60
# _ <- Only `a` should be deleted as one subword

Observed behavior

Example 1

% e foo
# _ <- cursor is at `e`
# M-x forward-subword
% e foo
#   _ <- cursor jumps over the space

Example 2

% aMinute 60
# _ <- cursor is at `a`
# M-x kill-subword
%  60
# _ <- `aMinute` is deleted as one subword

Environment:

  • OS: macOS
  • Terminal: iTerm
  • Zsh version: 5.9
  • Repo version: * main 4a8fa59 Improve "insert word" cycling logic

Additional context

WORDCHARS=''

Autoload of functions fails

In the plugin I can see autoload -Uz $fdir/* is used to autoload the functions used by this plugin. However, on my system it seems the use of an absolute path does not allow the functions to be found when needed. I get a No such shell function 'edit-subword' for example. I found if I were to remove the absolute path and simply autoload the functions with their names I could proceed to use the plugin. This is possible because of the earlier fpath modification done. autoload -Uz _show_clipboard edit-subword visual-yank

Insert key is absent from bind

Describe the bug

Insert key is absent from functions/bind.

Steps To Reproduce

Any bind command involving Insert key (^[[2~).

Expected behavior

❯ bind -n '^[[2~'
"^[[2~"   Insert

❯ bind -n '^[[2;2~'
"^[[2;2~"   Shift-Insert

etc.

Observed behavior

❯ bind -n '^[[2~'
"^[[2~"   Shift-

❯ bind -n '^[[2;2~'
"^[[2;2~"   Alt-[ + 2 + ; + 2 + ~

etc.

Environment:

  • OS: Pop!_OS 22.04 LTS x86_64
  • Terminal: kitty 0.24.1
  • Zsh version: 5.8.1
  • Repo version: * main 9eb2869 Don't overwrite Autosuggest's default ignore list

Additional context

Seems to be fairly simple to fix (add ( '[2;' ) name+='Insert' to the case-matches). Should i make a PR?
(I'm just not sure what does 1 mean here. Is this a typo? Also, all the regex magic in bind is so awesome it blows my mind).

Recent change removed `backward-kill-subword` functionality

After updating zsh-init the other week, suddently Alt-Backspace kills backwards to next space always.

It used to kill only $WORDCHARS like:

ls /my/path/here became ls /my/path

...but now it kills the whole (second) argument and only ls remains - which is not very convenient in most situations.

I checked the code but was unable to locate the specific change that caused this.

Can you merge the quote fix in dev branch?

What do you want?

Can you merge the quote fix in dev branch?

Why do you want this?

Binding commands with arguments doesn't work due to mishandled quotes.

Who else would benefit from this?

Everyone.

How should it work?

Given this situation:

When I perform these steps:

Then I expect this to happen:

Missing Install Instructions

What do you want?

Please provide installation instructions for vanilla ZSH as well as Oh-My-ZSH

Why do you want this?

To be able to properly install this

Who else would benefit from this?

Everyone else who wishes to use this project

How should it work?

Given this situation:
User reads the README.md

When I perform these steps:
Look for installation instructions

Then I expect this to happen:
Installation instructions should be present and easy to follow

Hide command output?

How do I hide the output of Keybindings shortcut?

ie. ctrl+[ to go back a directory, when I hit ctrl+[ it displays cd .. then runs it, how do I hide this ?

bind:zparseopts:10: no default array defined: -F

I upgraded to the latest version of zsh-edit a few days ago and since then I've been getting this error when a new zsh opens:

bind:zparseopts:10: no default array defined: -F
bind:zparseopts:10: no default array defined: -F

It doesn't seem to error on computers with zsh 5.8 but on my Debian server running 5.7.1-1 I get the above error. Not sure if that's coincidence or not.

How to use?

Hi there,

I asked the question on Stack Overflow about deleting words the same way as in bash. You suggested to use your project for this. However, I'm not getting it to work. How should this be used?

I tried to add it as a plugin with:

zplug "marlonrichert/zsh-edit"

But I don't seem to get extra bindkey commands, like backward-kill-subword.

I also tried sourcing the file:

source zsh-edit.plugin.zsh

But then I get these errors:

zsh-edit:69: bind: function definition file not found
zsh-edit:70: bind: function definition file not found

And then when I try any keybinding, like Ctrl+W, I get:

No such widget `.backward-kill-shell-word'
No such shell function `.edit.subword'

So, I'm not completely sure how I should use this, or if it should work.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.