Add zsh anything.el plugin
[zsh.git] / .zsh / zaw / functions / fill-vars-or-accept
1 #
2 # fill-vars-or-accept
3 #
4
5 # by default, pattern match "${:-variable_name}"
6 FILL_VARS_PATTERN='${:-[a-z_][a-z0-9_]#}'
7
8 function fill-vars-or-accept() {
9 # TODO: tab completion
10
11 local REPLY
12 local -a orig_region_highlight
13
14 if ! _buffer_has_vars; then
15 zle accept-line
16 fi
17
18 bindkey -N fillvars main
19 bindkey -M fillvars '^i' go-to-next-var
20
21 CURSOR=0
22
23 _get-current-var
24 if [[ -z "${REPLY}" ]]; then
25 go-to-next-var
26 fi
27
28 local POSTDISPLAY=$'\n''[press tab key to move cursor to next variable]'
29
30 while _buffer_has_vars && (( CURSOR < ${#BUFFER} )); do
31 orig_region_highlight=("${(@)region_highlight}")
32 _highlight-right-vars
33 zle -Rc
34 #zle -R '[press tab key to move next variable]'
35
36 zle read-command -K fillvars
37 reply="$?"
38 cmd_name="${REPLY}"
39
40 region_highlight=("${(@)orig_region_highlight}")
41
42 if [[ "${reply}" != 0 ]]; then
43 return 1
44 fi
45
46 if [[ "${cmd_name}" == accept* ]]; then
47 zle "${cmd_name}"
48 return
49
50 else
51 _get-current-var
52 if [[ -n "${REPLY}" ]]; then
53 if [[ "${cmd_name}" == self-insert* ]]; then
54 # remove current var
55 RBUFFER="${RBUFFER[$(( ${#REPLY} + 1)),-1]}"
56 elif [[ "${cmd_name}" == (*-delete-*|*-kill-*) ]]; then
57 # remove current var and continue
58 RBUFFER="${RBUFFER[$(( ${#REPLY} + 1)),-1]}"
59 continue
60 fi
61 fi
62 fi
63
64 zle "${cmd_name}"
65 done
66 }
67
68 function _highlight-right-vars() {
69 emulate -L zsh
70 setopt local_options extended_glob
71
72 local nl=$'\n' rbuffer="${RBUFFER}" REPLY
73 local -a match mbegin mend
74 integer offset="${#LBUFFER}"
75
76 if _buffer_has_vars; then
77 _get-current-var
78 if [[ -n "${REPLY}" ]]; then
79 region_highlight+=( "${offset} $(( offset + ${#REPLY} )) standout" )
80 rbuffer="${rbuffer[$(( ${#REPLY} )),-1]}"
81 (( offset += ${#REPLY} - 1 ))
82 fi
83
84 region_highlight+=( "${(f)${(S)rbuffer//*(#b)(${~FILL_VARS_PATTERN})/$(( offset + mbegin[1] - 1 )) $(( offset + mend[1] )) fg=yellow,standout${nl}}%$nl*}" )
85 fi
86 }
87
88 function _buffer_has_vars() {
89 emulate -L zsh
90 setopt local_options extended_glob
91 [[ "${BUFFER}" == *${~FILL_VARS_PATTERN}* ]]
92 }
93
94 function go-to-next-var() {
95 emulate -L zsh
96 setopt local_options extended_glob
97
98 local -a match mbegin mend
99 local rrbuffer="${RBUFFER[2,-1]}"
100 if [[ "${rrbuffer}" == *${~FILL_VARS_PATTERN}* ]]; then
101 # to match shortest, use variable expantion
102 : "${(S)rrbuffer/*(#b)(${~FILL_VARS_PATTERN})}"
103 (( CURSOR += ${mbegin[1]} ))
104 else
105 (( CURSOR = ${#BUFFER} ))
106 fi
107 }
108
109 zle -N go-to-next-var
110
111 function _get-current-var() {
112 emulate -L zsh
113 setopt local_options extended_glob
114
115 REPLY=""
116 if [[ "${RBUFFER}" == (#b)(${~FILL_VARS_PATTERN})* ]]; then
117 REPLY="${match[1]}"
118 fi
119 }
120
121 fill-vars-or-accept "$@"