13a8e3d98aeeb4f5f0b98f92ace540067e58ba92

Author
Roeniss Moon <roeniss2@gmail.com>
Committer
GitHub <noreply@github.com>
Date

Message

feat(alias-finder): add cheaper option and apply zstyle options (#11773)

Diff

This diff is truncated to protect this page.

  1diff --git a/plugins/alias-finder/.zunit.yml b/plugins/alias-finder/.zunit.yml
  2new file mode 100644
  3index 0000000000000000000000000000000000000000..ae65f8ef2ff0f51ab403d8b8e304bfdd51aefc50
  4--- /dev/null
  5+++ b/plugins/alias-finder/.zunit.yml
  6@@ -0,0 +1,9 @@
  7+tap: false
  8+directories:
  9+  tests: tests
 10+  output: tests/_output
 11+  support: tests/_support
 12+time_limit: 0
 13+fail_fast: false
 14+allow_risky: false
 15+verbose: true
 16diff --git a/plugins/alias-finder/README.md b/plugins/alias-finder/README.md
 17index 409f4b6536210d74caa3efee77ffc5a930da728b..6c87c723a99b5e311b5f4b4c175b045281152cb9 100644
 18--- a/plugins/alias-finder/README.md
 19+++ b/plugins/alias-finder/README.md
 20@@ -2,45 +2,32 @@
 21 
 22 This plugin searches the defined aliases and outputs any that match the command inputted. This makes learning new aliases easier.
 23 
 24+## Usage
 25+
 26 To use it, add `alias-finder` to the `plugins` array of your zshrc file:
 27 ```
 28 plugins=(... alias-finder)
 29 ```
 30 
 31-## Usage
 32-To see if there is an alias defined for the command, pass it as an argument to `alias-finder`. This can also run automatically before each command you input - add `ZSH_ALIAS_FINDER_AUTOMATIC=true` to your zshrc if you want this.
 33+To enable it for every single command, set zstyle in your `~/.zshrc`.
 34 
 35-## Options
 36+```zsh
 37+# ~/.zshrc
 38 
 39-- Use `--longer` or `-l` to allow the aliases to be longer than the input (match aliases if they contain the input).
 40-- Use `--exact` or `-e` to avoid matching aliases that are shorter than the input.
 41-
 42-## Examples
 43-```
 44-$ alias-finder "git pull"
 45-gl='git pull'
 46-g=git
 47-```
 48-```
 49-$ alias-finder "web_search google oh my zsh"
 50-google='web_search google'
 51-```
 52-```
 53-$ alias-finder "git commit -v"
 54-gc="git commit -v"
 55-g=git
 56-```
 57-```
 58-$ alias-finder -e "git commit -v"
 59-gc='git commit -v'
 60-```
 61-```
 62-$ alias-finder -l "git commit -v"
 63-gc='git commit -v'
 64-'gc!'='git commit -v --amend'
 65-gca='git commit -v -a'
 66-'gca!'='git commit -v -a --amend'
 67-'gcan!'='git commit -v -a --no-edit --amend'
 68-'gcans!'='git commit -v -a -s --no-edit --amend'
 69-'gcn!'='git commit -v --no-edit --amend'
 70+zstyle ':omz:plugins:alias-finder' autoload yes # disabled by default
 71+zstyle ':omz:plugins:alias-finder' longer yes # disabled by default
 72+zstyle ':omz:plugins:alias-finder' exact yes # disabled by default
 73+zstyle ':omz:plugins:alias-finder' cheaper yes # disabled by default
 74 ```
 75+
 76+As you can see, options are also available with zstyle.
 77+
 78+### Options
 79+
 80+> In order to clarify, let's say `alias a=abc` has source 'abc' and destination 'a'.
 81+
 82+- Use `--longer` or `-l` to include aliases where the source is longer than the input (in other words, the source could contain the whole input).
 83+- Use `--exact` or `-e` to avoid aliases where the source is shorter than the input (in other words, the source must be the same with the input).
 84+- Use `--cheaper` or `-c` to avoid aliases where the destination is longer than the input (in other words, the destination must be the shorter than the input).
 85+
 86+
 87diff --git a/plugins/alias-finder/alias-finder.plugin.zsh b/plugins/alias-finder/alias-finder.plugin.zsh
 88index caee9b5a3bc43b2092cd6a7ab73e086dc664a8ed..5fdfbc835f9dec78c4ba45bc6e772112ff94a560 100644
 89--- a/plugins/alias-finder/alias-finder.plugin.zsh
 90+++ b/plugins/alias-finder/alias-finder.plugin.zsh
 91@@ -1,44 +1,59 @@
 92 alias-finder() {
 93-  local cmd="" exact="" longer="" wordStart="" wordEnd="" multiWordEnd=""
 94-  for i in $@; do
 95-    case $i in
 96+  local cmd=" " exact="" longer="" cheaper="" wordEnd="'{0,1}$" finder="" filter=""
 97+
 98+  # build command and options
 99+  for c in "$@"; do
100+    case $c in
101+      # TODO: Remove backward compatibility (other than zstyle form)
102+      # set options if exist
103       -e|--exact) exact=true;;
104       -l|--longer) longer=true;;
105-      *)
106-        if [[ -z $cmd ]]; then
107-          cmd=$i
108-        else
109-          cmd="$cmd $i"
110-        fi
111-        ;;
112+      -c|--cheaper) cheaper=true;;
113+      # concatenate cmd
114+      *) cmd="$cmd$c " ;;
115     esac
116   done
117-  cmd=$(sed 's/[].\|$(){}?+*^[]/\\&/g' <<< $cmd) # adds escaping for grep
118-  if (( $(wc -l <<< $cmd) == 1 )); then
119-    while [[ $cmd != "" ]]; do
120-      if [[ $longer = true ]]; then
121-        wordStart="'{0,1}"
122-      else
123-        wordEnd="$"
124-        multiWordEnd="'$"
125-      fi
126-      if [[ $cmd == *" "* ]]; then
127-        local finder="'$cmd$multiWordEnd"
128-      else
129-        local finder=$wordStart$cmd$wordEnd
130-      fi
131-      alias | grep -E "=$finder"
132-      if [[ $exact = true || $longer = true ]]; then
133-        break
134-      else
135-        cmd=$(sed -E 's/ {0,1}[^ ]*$//' <<< $cmd) # removes last word
136-      fi
137-    done
138+
139+  zstyle -t ':omz:plugins:alias-finder' longer && longer=true
140+  zstyle -t ':omz:plugins:alias-finder' exact && exact=true
141+  zstyle -t ':omz:plugins:alias-finder' cheaper && cheaper=true
142+
143+  # format cmd for grep
144+  ## - replace newlines with spaces
145+  ## - trim both ends
146+  ## - replace multiple spaces with one space
147+  ## - add escaping character to special characters
148+  cmd=$(echo -n "$cmd" | tr '\n' ' ' | xargs | tr -s '[:space:]' | sed 's/[].\|$(){}?+*^[]/\\&/g')
149+
150+  if [[ $longer == true ]]; then
151+    wordEnd="" # remove wordEnd to find longer aliases
152   fi
153+
154+  # find with alias and grep, removing last word each time until no more words
155+  while [[ $cmd != "" ]]; do
156+    finder="'{0,1}$cmd$wordEnd"
157+
158+    # make filter to find only shorter results than current cmd
159+    if [[ $cheaper == true ]]; then
160+      cmdLen=$(echo -n "$cmd" | wc -c)
161+      filter="^'{0,1}.{0,$((cmdLen - 1))}="
162+    fi
163+
164+    alias | grep -E "$filter" | grep -E "=$finder"
165+
166+    if [[ $exact == true ]]; then
167+      break # because exact case is only one
168+    elif [[ $longer = true ]]; then
169+      break # because above grep command already found every longer aliases during first cycle
170+    fi
171+
172+    cmd=$(sed -E 's/ {0,}[^ ]*$//' <<< "$cmd") # remove last word
173+  done
174 }
175 
176 preexec_alias-finder() {
177-  if [[ $ZSH_ALIAS_FINDER_AUTOMATIC = true ]]; then
178+  # TODO: Remove backward compatibility (other than zstyle form)
179+  zstyle -t ':omz:plugins:alias-finder' autoload && alias-finder $1 || if [[ $ZSH_ALIAS_FINDER_AUTOMATIC = true ]]; then
180     alias-finder $1
181   fi
182 }
183diff --git a/plugins/alias-finder/tests/_output/.gitkeep b/plugins/alias-finder/tests/_output/.gitkeep
184new file mode 100644
185index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
186--- /dev/null
187+++ b/plugins/alias-finder/tests/_output/.gitkeep
188diff --git a/plugins/alias-finder/tests/_support/.gitkeep b/plugins/alias-finder/tests/_support/.gitkeep
189new file mode 100644
190index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
191--- /dev/null
192+++ b/plugins/alias-finder/tests/_support/.gitkeep
193diff --git a/plugins/alias-finder/tests/_support/bootstrap b/plugins/alias-finder/tests/_support/bootstrap
194new file mode 100644
195index 0000000000000000000000000000000000000000..01076611e7e6da70c2ee97686d2f863a54293dad
196--- /dev/null
197+++ b/plugins/alias-finder/tests/_support/bootstrap
198@@ -0,0 +1,2 @@
199+#!/usr/bin/env zsh
200+# Write your bootstrap code here
201diff --git a/plugins/alias-finder/tests/test_run.sh b/plugins/alias-finder/tests/test_run.sh
202new file mode 100644
203index 0000000000000000000000000000000000000000..6b7abebb6ef254b24bd79a934040d3252a5e7237
204--- /dev/null
205+++ b/plugins/alias-finder/tests/test_run.sh
206@@ -0,0 +1,107 @@
207+#!/usr/bin/env zunit
208+
209+@setup {
210+  load ../alias-finder.plugin.zsh
211+
212+  set_git_aliases() {
213+    unalias -a # all
214+    alias g="git"
215+    alias gc="git commit"
216+    alias gcv="git commit -v"
217+    alias gcvs="git commit -v -S"
218+  }
219+}
220+
221+@test 'find aliases that contain input' {
222+  set_git_aliases
223+
224+  run alias-finder "git"
225+
226+  assert "${#lines[@]}" equals 1
227+  assert "${lines[1]}" same_as "g=git"
228+}
229+
230+@test 'find aliases that contain input with whitespaces at ends' {
231+  set_git_aliases
232+
233+  run alias-finder "   git     "
234+
235+  assert "${#lines[@]}" equals 1
236+  assert "${lines[1]}" same_as "g=git"
237+}
238+
239+@test 'find aliases that contain multiple words' {
240+  set_git_aliases
241+
242+  run alias-finder "git commit -v"
243+
244+  assert "${#lines[@]}" equals 3
245+  assert "${lines[1]}" same_as "gcv='git commit -v'"
246+  assert "${lines[2]}" same_as "gc='git commit'"
247+  assert "${lines[3]}" same_as "g=git"
248+}
249+
250+@test 'find alias that is the same with input when --exact option is set' {
251+  set_git_aliases
252+
253+  run alias-finder -e "git"
254+
255+  assert "${#lines[@]}" equals 1
256+  assert "${lines[1]}" same_as "g=git"
257+}
258+
259+@test 'find alias that is the same with multiple words input when --exact option is set' {
260+  set_git_aliases
261+
262+  run alias-finder -e "git commit -v"
263+
264+  assert "${#lines[@]}" equals 1
265+  assert "${lines[1]}" same_as "gcv='git commit -v'"
266+}
267+
268+@test 'find alias that is the same with or longer than input when --longer option is set' {
269+  set_git_aliases
270+
271+  run alias-finder -l "git"
272+
273+  assert "${#lines[@]}" equals 4
274+  assert "${lines[1]}" same_as "g=git"
275+  assert "${lines[2]}" same_as "gc='git commit'"
276+  assert "${lines[3]}" same_as "gcv='git commit -v'"
277+  assert "${lines[4]}" same_as "gcvs='git commit -v -S'"
278+}
279+
280+@test 'find alias that is the same with or longer than multiple words input when --longer option is set' {
281+  set_git_aliases
282+
283+  run alias-finder -l "git commit -v"
284+
285+  assert "${#lines[@]}" equals 2
286+  assert "${lines[1]}" same_as "gcv='git commit -v'"
287+  assert "${lines[2]}" same_as "gcvs='git commit -v -S'"
288+}
289+
290+@test 'find aliases including expensive (longer) than input' {
291+  set_git_aliases
292+  alias expensiveCommands="git commit"
293+
294+  run alias-finder "git commit -v"
295+
296+  assert "${#lines[@]}" equals 4
297+  assert "${lines[1]}" same_as "gcv='git commit -v'"
298+  assert "${lines[2]}" same_as "expensiveCommands='git commit'"
299+  assert "${lines[3]}" same_as "gc='git commit'"
300+  assert "${lines[4]}" same_as "g=git"
301+}
302+
303+@test 'find aliases excluding expensive (longer) than input when --cheap option is set' {
304+  set_git_aliases
305+  alias expensiveCommands="git commit"