Skip to content

Commit ca7a1e8

Browse files
committed
new file: .config/zew/zew.conf
new file: LICENSE new file: README.md new file: zew new file: zew-backward-kill-shell-word new file: zew-complete-shell-word new file: zew-history-complete-word new file: zew-process-buffer new file: zew-rotate-shell-words new file: zew-transpose-shell-words new file: zsh-editing-workbench.plugin.zsh
0 parents  commit ca7a1e8

11 files changed

+713
-0
lines changed

.config/zew/zew.conf

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# How should Ctrl-W (kill word) and Alt-r (transpose word)
2+
# recognize words. Possible values:
3+
#
4+
# bash Word characters are alphanumeric characters only.
5+
# normal As in normal shell operation: word characters are alphanumeric characters plus
6+
# any characters present in the string given by the parameter $WORDCHARS.
7+
# shell Words are complete shell command arguments, possibly including complete quoted strings, or
8+
# any tokens special to the shell.
9+
# whitespace Words are any set of characters delimited by whitespace.
10+
# default Restore the default settings; this is usually the same as `normal' with default $WORDCHARS.
11+
12+
local zew_word_style=bash

LICENSE

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
This software is licensed under MIT.
2+
3+
MIT License
4+
-----------
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in
14+
all copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
THE SOFTWARE.

README.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# `ZSH-EDITING-WORKBENCH`
2+
3+
## Introduction
4+
5+
Organized shortcuts for various command line editing operations, plus new
6+
operations (e.g. incremental history word completion).
7+
8+
Incremental history _word_ completing (started with `Alt-h/H` or `Option-h/H` on Mac):
9+
10+
## Installation With [Zinit](https://github.com/z-shell/zinit)
11+
12+
Add `zinit load z-shell/zsh-editing-workbench` to `.zshrc`. The config files will be available in `~/.config/zew`.
13+
14+
## Installation With Zgen
15+
16+
Add `zgen load z-shell/zsh-editing-workbench` to `.zshrc` and issue a `zgen reset` (this assumes that there is a proper `zgen save` construct in `.zshrc`).
17+
The config files will be available in `~/.config/zew`.
18+
19+
## Installation With Antigen
20+
21+
Add `antigen bundle z-shell/zsh-editing-workbench` to `.zshrc`. There also
22+
should be `antigen apply`. The config files will be in `~/.config/znt`.
23+
24+
## Manual Installation
25+
26+
After extracting `ZEW` to `{some-directory}` add following two lines
27+
to `~/.zshrc`:
28+
29+
```zsh
30+
fpath+=( {some-directory} )
31+
source "{some-directory}/zsh-editing-workbench.plugin.zsh"
32+
```
33+
34+
As you can see, no plugin manager is needed to use the `*.plugin.zsh`
35+
file. The above two lines of code are all that almost **all** plugin
36+
managers do. In fact, what's actually needed is only:
37+
38+
```zsh
39+
source "{some-directory}/zsh-editing-workbench.plugin.zsh"
40+
```
41+
42+
because `ZEW` detects if it is used by **any** plugin manager and can
43+
handle `$fpath` update by itself.
44+
45+
## Configuring terminals
46+
47+
### **XTerm**
48+
49+
To make `Alt` key work like expected under `XTerm` add `XTerm*metaSendsEscape: true` to your resource file, e.g.:
50+
51+
```zsh
52+
echo 'XTerm*metaSendsEscape: true' >> ~/.Xresources
53+
```

zew

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Displays help on Zew provided actions. Lines are 72 characters long
2+
3+
autoload colors
4+
colors
5+
6+
local h1="$fg_bold[magenta]"
7+
local h2="$fg_bold[green]"
8+
local h3="$fg_bold[blue]"
9+
local h4="$fg_bold[yellow]"
10+
local rst="$reset_color"
11+
12+
local LESS_bkp="$LESS"
13+
export LESS="-iRX"
14+
15+
less <<<"
16+
${h1}Key Bindings${rst}
17+
18+
Zew provides organized key bindings for various command line editing
19+
features, and also provides some of the features (not existing in all
20+
Zsh versions, or having limitations or bugs). Original features are used
21+
to make user not depart from mainstream Zsh.
22+
23+
The key bindings are below. Original features are marked by
24+
blue color set on the key shortcut:
25+
26+
1. ${h2}Alt-w${rst} - delete a ${h4}shell word${rst} (what's a shell word is explained in
27+
following section)
28+
2. ${h2}Alt-t${rst} - transpose (swap) ${h4}shell words${rst}
29+
3. ${h3}Alt-m${rst} - copy previous ${h4}shell word${rst}, or word before that, etc. when
30+
used multiple times
31+
4. ${h3}Alt-M${rst} - just copy previous ${h4}shell word${rst} without iterating to
32+
previous ones
33+
5. ${h3}Alt-.${rst} - copy last ${h4}shell word${rst} from previous line, or line before
34+
that, etc. when used multiple times; can be combined with
35+
${h3}Alt-m${rst}
36+
6. ${h3}Ctrl-W${rst} - delete word according to configured ${h4}word style${rst} (what's the
37+
style is explained in following section)
38+
7. ${h3}Alt-r${rst} - transpose (swap) words according to configured ${h4}word style${rst}
39+
(cursor needs to be placed on beginning of word to swap)
40+
8. ${h3}Alt-/${rst} - complete ${h4}some word${rst} from history (explained in next section)
41+
9. ${h2}Alt-h/H${rst} - complete ${h4}shell word${rst} from history (custom version)
42+
10. ${h3}Ctrl-J${rst} - break line
43+
11. ${h3}Ctrl-_${rst} - undo
44+
45+
46+
${h1}Definitions${rst}
47+
48+
A ${h4}shell word${rst} is a text that Zsh would see as single segment. For example
49+
\$(( i + 1 )) is a single shell word.
50+
51+
A ${h4}word style${rst} defines a way Zsh recognizes segments (words) of text in
52+
commands that want to use the style information. The style can be
53+
configured in zew.conf to be one of:
54+
55+
- bash words are built up of alphanumeric characters only
56+
- normal as in normal shell operation: word characters are
57+
alphanumeric characters plus any characters present in the
58+
string given by the parameter \$WORDCHARS
59+
- shell words are complete shell command arguments, possibly
60+
including complete quoted strings, or any tokens special to
61+
the shell
62+
- whitespace words are any set of characters delimited by whitespace
63+
- default restore the default settings; this is the same as 'normal'
64+
with default \$WORDCHARS
65+
66+
${h4}Some word${rst} is in general a sophisticated word, but not a shell word,
67+
because of limitations in Zsh history word completion. ${h4}Some word${rst} is
68+
rather not build from special characters, it works well for normal
69+
characters.
70+
"
71+
72+
export LESS="$LESS_bkp"
73+

zew-backward-kill-shell-word

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#
2+
# Copyright (c) 2016 Daniel Shahaf
3+
#
4+
# MIT License
5+
# -----------
6+
#
7+
# Permission is hereby granted, free of charge, to any person obtaining a copy
8+
# of this software and associated documentation files (the "Software"), to deal
9+
# in the Software without restriction, including without limitation the rights
10+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
# copies of the Software, and to permit persons to whom the Software is
12+
# furnished to do so, subject to the following conditions:
13+
#
14+
# The above copyright notice and this permission notice shall be included in
15+
# all copies or substantial portions of the Software.
16+
#
17+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
# THE SOFTWARE.
24+
#
25+
# Modifications Copyright (c) 2016 Sebastian Gniazdowski
26+
#
27+
28+
local MATCH; integer MBEGIN MEND
29+
integer start end_of_word end_of_cut=$CURSOR
30+
31+
# Walk backwards to an end-of-word
32+
[[ $LBUFFER =~ '[[:space:]]*$' ]] || : # sets $MATCH
33+
(( end_of_word = CURSOR - $#MATCH ))
34+
35+
# Find the start of the shell word ending at $BUFFER[end_of_word]
36+
() {
37+
local l="$PREBUFFER$LBUFFER[1,end_of_word]"
38+
local -a a
39+
if [[ -o interactive_comments ]]; then
40+
a=( ${(zZ+c+)l} )
41+
else
42+
a=( ${(z)l} )
43+
fi
44+
(( start = end_of_word - ${#a[-1]} + 1 ))
45+
}
46+
47+
# Standard kill-widget behaviour
48+
autoload -Uz is-at-least
49+
if is-at-least 5.2; then
50+
zle -f 'kill'
51+
fi
52+
53+
if [[ $LASTWIDGET == *'kill'* ]]; then
54+
CUTBUFFER=${BUFFER[start,end_of_cut]}$CUTBUFFER
55+
else
56+
zle copy-region-as-kill -- "${BUFFER[start,end_of_cut]}"
57+
fi
58+
59+
# Delete the last shell word from $LBUFFER
60+
LBUFFER[start,end_of_cut]=""

zew-complete-shell-word

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Renamed to zew-history-complete-word

zew-history-complete-word

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
emulate -LR zsh
2+
setopt typesetsilent extendedglob noshortloops
3+
4+
# When an error, then no cursor keys bindings
5+
zmodload zsh/terminfo 2>/dev/null
6+
zmodload zsh/termcap 2>/dev/null
7+
8+
# Prepare output variables for zew-process-buffer
9+
local ZEW_PB_WORDS ZEW_PB_WORDS_BEGINNINGS ZEW_PB_SPACES
10+
local ZEW_PB_SELECTED_WORD ZEW_PB_LEFT ZEW_PB_RIGHT
11+
12+
typeset -g __zew_hcw_index __zew_hcw_left __zew_hcw_right
13+
typeset -g __zew_hcw_widget_name __zew_hcw_restart __zew_hcw_call_count
14+
typeset -gaU __zew_hcw_found
15+
16+
(( __zew_hcw_call_count ++ ))
17+
18+
_zhcw_main() {
19+
20+
autoload zew-process-buffer
21+
zew-process-buffer "$BUFFER" "$CURSOR"
22+
23+
# First call or restart?
24+
if [[ "$__zew_hcw_call_count" -le 1 || "$__zew_hcw_restart" = "1" ]]; then
25+
# '0' will get changed into $to_display limit
26+
[[ "$WIDGET" != *-backwards ]] && __zew_hcw_index="1" || __zew_hcw_index="0"
27+
__zew_hcw_widget_name="${WIDGET%-backwards}"
28+
__zew_hcw_left="$ZEW_PB_LEFT"
29+
__zew_hcw_right="$ZEW_PB_RIGHT"
30+
__zew_hcw_found=( )
31+
__zew_hcw_finished="0"
32+
__zew_hcw_restart="0"
33+
else
34+
# Consecutive call
35+
[[ "$WIDGET" != *-backwards ]] && (( __zew_hcw_index ++ )) || (( __zew_hcw_index -- ))
36+
fi
37+
38+
# Find history words matching $left ... $right
39+
if [ "$#__zew_hcw_found" -eq "0" ]; then
40+
repeat 1; do
41+
__zew_hcw_found=( "${(@M)historywords:#(#i)$__zew_hcw_left*$__zew_hcw_right}" )
42+
done
43+
44+
# The first result should be always $__zew_hcw_left$__zew_hcw_right
45+
if [ "$__zew_hcw_found[1]" != "$__zew_hcw_left$__zew_hcw_right" ]; then
46+
__zew_hcw_found=( "$__zew_hcw_left$__zew_hcw_right" "$__zew_hcw_found[@]" )
47+
fi
48+
fi
49+
50+
if [ "$#__zew_hcw_found" -le "0" ]; then
51+
zle -M "No matches found"
52+
return 0
53+
fi
54+
55+
# Pagination, index value guards
56+
integer page_size=$(( LINES / 2 ))
57+
integer max_index="$#__zew_hcw_found"
58+
[ "$page_size" -gt "$max_index" ] && page_size="$max_index"
59+
[ "$__zew_hcw_index" -le 0 ] && __zew_hcw_index="$max_index"
60+
[ "$__zew_hcw_index" -gt "$max_index" ] && __zew_hcw_index=1
61+
integer page_start_idx=$(( ((__zew_hcw_index-1)/page_size)*page_size+1 ))
62+
integer on_page_idx=$(( (__zew_hcw_index-1) % page_size + 1 ))
63+
64+
# Display matches
65+
typeset -a disp_list
66+
disp_list=( "${(@)__zew_hcw_found[page_start_idx,page_start_idx+page_size-1]}" )
67+
68+
# Add two spaces before every element
69+
disp_list=( "${(@)disp_list/(#m)*/ ${MATCH}}" )
70+
71+
# Add > before active element
72+
local entry="${disp_list[on_page_idx]}"
73+
entry[1]='>'
74+
disp_list[on_page_idx]="$entry"
75+
76+
zle -M -- \
77+
"Searching for '${__zew_hcw_left}_${__zew_hcw_right}'. "\
78+
"Element #$__zew_hcw_index of $max_index"$'\n'"${(F)disp_list}"
79+
80+
# Regenerate command line
81+
local buf=""
82+
integer nwords="${#ZEW_PB_WORDS}"
83+
for (( i=1; i<=nwords; i++ )); do
84+
if [ "$i" = "$ZEW_PB_SELECTED_WORD" ]; then
85+
buf+="${ZEW_PB_SPACES[i]}${__zew_hcw_found[__zew_hcw_index]}"
86+
else
87+
buf+="${ZEW_PB_SPACES[i]}${ZEW_PB_WORDS[i]}"
88+
fi
89+
done
90+
91+
if [[ "$nwords" = "0" && "$ZEW_PB_SELECTED_WORD" = "0" ]]; then
92+
buf+="${__zew_hcw_found[__zew_hcw_index]}"
93+
fi
94+
95+
# Add trailing spaces
96+
buf+="$ZEW_PB_SPACES[i]"
97+
98+
# Set command line
99+
BUFFER="$buf"
100+
101+
}
102+
103+
_zhcw_self_insert() {
104+
LBUFFER+="${KEYS[-1]}"
105+
__zew_hcw_restart="1"
106+
_zhcw_main
107+
}
108+
109+
_zhcw_backward_delete_char() {
110+
LBUFFER="${LBUFFER%?}"
111+
__zew_hcw_restart="1"
112+
_zhcw_main
113+
}
114+
115+
_zhcw_delete_char() {
116+
RBUFFER="${RBUFFER#?}"
117+
__zew_hcw_restart="1"
118+
_zhcw_main
119+
}
120+
121+
_zhcw_main
122+
123+
if [ "$__zew_hcw_call_count" -eq "1" ]; then
124+
# Make the zhcw keymap a copy of the current main
125+
bindkey -N zhcw emacs
126+
127+
local down_widget="${WIDGET%-backwards}"
128+
local up_widget="${down_widget}-backwards"
129+
130+
# Manual, termcap, terminfo
131+
bindkey -M zhcw '^[OA' "$up_widget"
132+
bindkey -M zhcw '^[OB' "$down_widget"
133+
bindkey -M zhcw '^[[A' "$up_widget"
134+
bindkey -M zhcw '^[[B' "$down_widget"
135+
[ -n "$termcap[ku]" ] && bindkey -M zhcw "$termcap[ku]" "$up_widget"
136+
[ -n "$termcap[kd]" ] && bindkey -M zhcw "$termcap[kd]" "$down_widget"
137+
[ -n "$termcap[kD]" ] && bindkey -M zhcw "$termcap[kD]" delete-char
138+
[ -n "$terminfo[kcuu1]" ] && bindkey -M zhcw "$terminfo[kcuu1]" "$up_widget"
139+
[ -n "$terminfo[kcud1]" ] && bindkey -M zhcw "$terminfo[kcud1]" "$down_widget"
140+
[ -n "$terminfo[kdch1]" ] && bindkey -M zhcw "$terminfo[kdch1]" delete-char
141+
142+
# Needed for Fedora 23, zsh-5.1.1
143+
bindkey -M zhcw ' ' self-insert
144+
145+
# Substitute self-insert, backward-delete-char, delete-char
146+
zle -A self-insert saved-self-insert
147+
zle -A backward-delete-char saved-backward-delete-char
148+
zle -A delete-char saved-delete-char
149+
150+
zle -N self-insert _zhcw_self_insert
151+
zle -N backward-delete-char _zhcw_backward_delete_char
152+
zle -N delete-char _zhcw_delete_char
153+
154+
zle recursive-edit -K zhcw
155+
zle -M ""
156+
157+
zle -A saved-self-insert self-insert
158+
zle -A saved-backward-delete-char backward-delete-char
159+
zle -A saved-delete-char delete-char
160+
zle -D saved-self-insert saved-backward-delete-char saved-delete-char
161+
162+
# Full reinitialisation at next call
163+
__zew_hcw_call_count="0"
164+
fi
165+
166+
# vim:ft=zsh

0 commit comments

Comments
 (0)