I've written a function that will find a function or class definition among Python files. It generates an argument list to be used with vim. It works for the first argument / file, but fails for subsequent files since the trailing " gets added to the file name.
Despite the correct output generated, when passed to vim it does not work. However, it works when the same output is copy and pasted at the command line. The problem is that the closing " gets parsed as part of the file name when it should be the closing end of a command string:
vim +cmd1 file1 +"file2_cmd file2_cmd file2" +"file3_cmd file3_cmd file3"
I need the function to add a literal double quote (\") when adding the command, but then parse literal quote when used with vim. The odd thing is the first literal quote gets parsed but not the end literal quote.
vim +cmd file1 +" <-- this quote works, but this one doesn't --> "
Code:
function vpfd {
local args=''
find . -name "*.py" \
| xargs grep -En "(def|class) ${@}[(:]" \
| uniq \
| while read line; do
name=$(echo "${line}" | awk 'BEGIN { FS=":" }; { print $1 }')
num=$(echo "${line}" | awk 'BEGIN { FS=":" }; { print $2 }')
if [ ! "${args}" ]; then
args="+${num} ${name}"
else
args+=" +\"tabnew +${num} ${name}\""
fi
done
if [ "${args}" ]; then
echo "vim ${args}"
read p
vim $(echo ${args})
fi
Example:
$ vpfd main
vim +33 ./bar.py +"tabnew +15 ./foo.py"
If I copy and paste the above line it works just fine, however it does not work when the function tries to open vim and pass it ${args}.
Within vim:
- error message:
Vim: not an editor command: 33 ./bar.py +"tabnew +15 ./foo.py" - only empty file visible
- I exit empty file
- vim then opens
./bar.pyat correct line and on a second tab opens the incorrect file./foo.py"(trailing")
If I copy and paste the output line then it works correctly:
$ vim +33 ./bar.py +"tabnew +15 ./foo.py"
+"tabnew +15 ./foo.py"the double quotes are necessary so that vim recognizes that as a single command. Without the quotes vim interprets+tabnew +15 ./foo.pyas 3 separate commands.