153 lines
4.1 KiB
Diff
153 lines
4.1 KiB
Diff
|
From 37034a6549ca23f6d59deefae3d5f845c74683d1 Mon Sep 17 00:00:00 2001
|
||
|
From: =?UTF-8?q?Jo=C3=A3o=20Paulo=20G=2E=20Garcia?=
|
||
|
<joaopauloggarcia@gmail.com>
|
||
|
Date: Sun, 1 Aug 2021 15:22:01 -0300
|
||
|
Subject: [PATCH 1/3] complete-filename: allow shell expansions and escape
|
||
|
"spaces".
|
||
|
|
||
|
Enclose prefix within double quotes so that we can properly use
|
||
|
environment variables.
|
||
|
|
||
|
Force "tilda expansion" by replacind "~"
|
||
|
with "$HOME".
|
||
|
|
||
|
Escape occurrences of spaces in vis-open output.
|
||
|
---
|
||
|
lua/plugins/complete-filename.lua | 8 ++--
|
||
|
vis-complete | 76 ++++++++++++++++++--------------------
|
||
|
2 files changed, 41 insertions(+), 43 deletions(-)
|
||
|
|
||
|
--- a/lua/plugins/complete-filename.lua
|
||
|
+++ b/lua/plugins/complete-filename.lua
|
||
|
@@ -15,7 +15,8 @@ vis:map(vis.modes.INSERT, "<C-x><C-f>",
|
||
|
-- Strip leading delimiters for some languages
|
||
|
local _, j = string.find(prefix, "[[(<'\"]+")
|
||
|
if j then prefix = prefix:sub(j + 1) end
|
||
|
- local cmd = string.format("vis-complete --file '%s'", prefix:gsub("'", "'\\''"))
|
||
|
+ local cmd = string.format('vis-complete --file "%s"',
|
||
|
+ prefix:gsub("^~", "$HOME"):gsub("'", "'\\''"))
|
||
|
local status, out, err = vis:pipe(file, { start = 0, finish = 0 }, cmd)
|
||
|
if status ~= 0 or not out then
|
||
|
if err then vis:info(err) end
|
||
|
@@ -43,13 +44,14 @@ vis:map(vis.modes.INSERT, "<C-x><C-o>",
|
||
|
range.start = pos
|
||
|
range.finish = pos
|
||
|
end
|
||
|
- local cmd = string.format("vis-open -- '%s'*", prefix:gsub("'", "'\\''"))
|
||
|
+ local cmd = string.format('vis-open -- "%s"*',
|
||
|
+ prefix:gsub("^~", "$HOME"):gsub("'", "'\\''"))
|
||
|
local status, out, err = vis:pipe(file, { start = 0, finish = 0 }, cmd)
|
||
|
if status ~= 0 or not out then
|
||
|
if err then vis:info(err) end
|
||
|
return
|
||
|
end
|
||
|
- out = out:gsub("\n$", "")
|
||
|
+ out = out:gsub("\n$", ""):gsub(" ", "\\ ")
|
||
|
file:delete(range)
|
||
|
file:insert(range.start, out)
|
||
|
win.selection.pos = range.start + #out
|
||
|
--- a/vis-complete
|
||
|
+++ b/vis-complete
|
||
|
@@ -1,65 +1,61 @@
|
||
|
#!/bin/sh
|
||
|
set -e
|
||
|
|
||
|
-basic_regex_quote() { printf "%s" "$1" | sed 's|[\\.*^$[]|\\&|g'; }
|
||
|
-glob_quote () { printf "%s" "$1" | sed 's|[\\?*[]]|\\&|g'; }
|
||
|
+basic_regex_quote() { printf "%s" "$1" | sed 's/[|\\.*^$[]/\\&/g'; }
|
||
|
+
|
||
|
+print_completion() {
|
||
|
+ sort -u \
|
||
|
+ | vis-menu -b -i -l $VIS_MENU_LINES \
|
||
|
+ | sed "s|^$1||" \
|
||
|
+ | tr -d '\n'
|
||
|
+}
|
||
|
|
||
|
PATTERN=""
|
||
|
-COMPLETE_WORD=0
|
||
|
+COMPLETE_MODE='-' # -) stdin; w) split stdin in words; f) find(1) filenames
|
||
|
FIND_FILE_LIMIT=1000
|
||
|
+VIS_MENU_LINES=0
|
||
|
|
||
|
while [ $# -gt 0 ]; do
|
||
|
case "$1" in
|
||
|
-h|--help)
|
||
|
- echo "usage: $(basename "$0") [-h] [--file|--word] [pattern]"
|
||
|
+ echo "usage: $(basename "$0") [-h] [-l lines] [--file|--word] [pattern]"
|
||
|
exit 0;
|
||
|
;;
|
||
|
--file)
|
||
|
+ COMPLETE_MODE='f'
|
||
|
shift
|
||
|
;;
|
||
|
--word)
|
||
|
- COMPLETE_WORD=1
|
||
|
+ COMPLETE_MODE='w'
|
||
|
shift
|
||
|
;;
|
||
|
+ -l)
|
||
|
+ VIS_MENU_LINES=$2
|
||
|
+ shift 2
|
||
|
+ ;;
|
||
|
*)
|
||
|
PATTERN="$1"
|
||
|
+ QPATTERN=$(basic_regex_quote "$PATTERN") # Avoid problems with sed and grep.
|
||
|
break
|
||
|
;;
|
||
|
esac
|
||
|
done
|
||
|
|
||
|
-if [ $COMPLETE_WORD = 1 ]; then
|
||
|
- tr -s '[:blank:]_' '\n' |
|
||
|
- grep "^$(basic_regex_quote "$PATTERN")." |
|
||
|
- sort -u
|
||
|
-else
|
||
|
- # Expand to absolute path because of the -path option below.
|
||
|
- case $PATTERN in
|
||
|
- /*)
|
||
|
- XPATTERN=$PATTERN
|
||
|
- ;;
|
||
|
- '~'|'~/'*)
|
||
|
- XPATTERN=$HOME$(echo $PATTERN | tail -c +2)
|
||
|
- ;;
|
||
|
- *)
|
||
|
- XPATTERN=$PWD/$PATTERN
|
||
|
- ;;
|
||
|
- esac
|
||
|
-
|
||
|
- # The first path condition rules out paths that start with "." unless
|
||
|
- # they start with "..". That way, hidden paths should stay hidden, but
|
||
|
- # non-normalised paths should still show up.
|
||
|
- find $(dirname "$XPATTERN") \
|
||
|
- -name '.*' -prune \
|
||
|
- -o \( \
|
||
|
- ! -name '.*' \
|
||
|
- -a -path "$(glob_quote "$XPATTERN")*" \
|
||
|
- -print \
|
||
|
- \) 2>/dev/null |
|
||
|
- head -n $FIND_FILE_LIMIT |
|
||
|
- sort |
|
||
|
- sed "s|^$(dirname $XPATTERN)/||"
|
||
|
-fi |
|
||
|
- vis-menu -b |
|
||
|
- sed "s|^$(basename $PATTERN)$(echo $PATTERN | tail -c 2 | fgrep /)||" |
|
||
|
- tr -d '\n'
|
||
|
+case $COMPLETE_MODE in
|
||
|
+ -)
|
||
|
+ grep "^$QPATTERN." | print_completion "$QPATTERN"
|
||
|
+ ;;
|
||
|
+ w)
|
||
|
+ tr -cs '[:alnum:]_' '\n' \
|
||
|
+ | grep "^$PATTERN." \
|
||
|
+ | print_completion "$PATTERN"
|
||
|
+ ;;
|
||
|
+ f)
|
||
|
+ find "$PATTERN"* \
|
||
|
+ -name ".*" -prune \
|
||
|
+ -o -print 2> /dev/null \
|
||
|
+ | head -n $FIND_FILE_LIMIT \
|
||
|
+ | sed "s|^$(dirname "$QPATTERN".)/||" \
|
||
|
+ | print_completion "${QPATTERN##*/}"
|
||
|
+ ;;
|
||
|
+esac
|