vis
a vi-like editor based on Plan 9's structural regular expressions
git clone https://9o.is/git/vis.git
vis-complete
(1724B)
1 #!/bin/sh
2 set -e
3
4 fatal() {
5 echo "$@" >&2
6 exit 1
7 }
8
9 usage() {
10 fatal "Usage: $(basename "$0") [--file|--word] [--] pattern
11
12 Interactively complete file or word
13
14 Options:
15 --file expand pattern into a list of matching file names (default)
16 --word apply pattern to a list of words from standard input
17 pattern pattern to be completed"
18 }
19
20 basic_regex_quote() { printf "%s" "$1" | sed 's|[\\.*^$[]|\\&|g'; }
21 glob_quote () { printf "%s" "$1" | sed 's|[\\?*[]]|\\&|g'; }
22
23 COMPLETE_WORD=0
24 FIND_FILE_LIMIT="${FIND_FILE_LIMIT:-1000}"
25
26 while [ $# -gt 0 ]; do
27 case "$1" in
28 --file)
29 COMPLETE_WORD=0
30 shift
31 ;;
32 --word)
33 COMPLETE_WORD=1
34 shift
35 ;;
36 --)
37 shift
38 break
39 ;;
40 -*|'')
41 usage
42 ;;
43 *)
44 break
45 ;;
46 esac
47 done
48
49 [ "$#" -lt 1 ] && usage
50
51 PATTERN="$1"
52
53 if [ $COMPLETE_WORD = 1 ]; then
54 # shellcheck disable=SC1003
55 tr -s '\t {}()[],<>%^&.\\' '\n' |
56 grep "^$(basic_regex_quote "$PATTERN")." |
57 sort -u
58 else
59 # Expand to absolute path because of the -path option below.
60 # shellcheck disable=SC2088
61 case $PATTERN in
62 /*)
63 XPATTERN="$PATTERN"
64 ;;
65 '~'|'~/'*)
66 XPATTERN="$HOME$(echo "$PATTERN" | tail -c +2)"
67 ;;
68 *)
69 XPATTERN="$PWD/$PATTERN"
70 ;;
71 esac
72
73 # The first path condition rules out paths that start with "." unless
74 # they start with "..". That way, hidden paths should stay hidden, but
75 # non-normalised paths should still show up.
76 find "$(dirname "$XPATTERN")" \
77 -name '.*' -prune \
78 -o \( \
79 ! -name '.*' \
80 -a -path "$(glob_quote "$XPATTERN")*" \
81 -print \
82 \) 2>/dev/null |
83 head -n "$FIND_FILE_LIMIT" |
84 sort |
85 sed "s|^$(dirname "$XPATTERN")/||"
86 fi |
87 vis-menu -b |
88 sed "s|^$(basename "$PATTERN")$(echo "$PATTERN" | tail -c 2 | grep -F /)||" |
89 tr -d '\n'