07 Feb 2023Some of my vimscripts need to call external commands, through the shell CLI. I learned some quirks the hard way, and documenting them here
The basics
Calling an external command is done through system('external-command')
. If you need to pass arguments you must wrap them in shellescape(myArgument)
or it will mess up spaces and quotes.
The quirks
If you echom
the result and see it through :messages
, you might see some ^@
weird characters. Those are how vim displays new lines, but not how they are encoded in the result.
To split the result on new lines, you should run split(myResult, "\n")
and not split(myResult, '^@')
.
07 Feb 2023Vimscript Array
s are called List
s. They have a set of rules and functions that I'll document here for my own reference:
Basics
- They are defined with
let myArray=['one', 'two', 'three']
- They are zero-indexed:
echo myArray[0]
is one
- They can be accessed from the end
echo myArray[-1]
is three
Functions
add(myArray, 'four')
adds a new elements. myArray+=['four']
also worksget(myArray, 0, 'default value')
reads a value, with a fallbacklen(myArray)
returns 3
index(myArray, 'three')
returns 2
(or -1
if not found)join(myArray, '/')
returns one/two/three
split('one/two/three', '/')
creates ['one', 'two', 'three']
Source
06 Feb 2023I had a commandOptions
string variable that I wanted to use as arguments to fzf
. But commandOptions
had all kind of spaces and quoted strings in it and I had a hard time passing it as a set of distinct arguments and not one long string argument.
The best solution I found was to actually display this commandOptions
in a multiline format, where each line was an option. Then, using the ${(f)commandOptions}
modifier to read it.
get_options
#!/usr/bin/env zsh
local commandOptions=()
commandOptions+="--disabled"
commandOptions+="--delimiter= "
commandOptions+="--with-nth=3"
commandOptions+="--bind=change:reload:sleep 0.1;${sourceBinary} {q} || true"
for line in $commandOptions; do
echo $line
done
use_options
#!/usr/bin/env zsh
local myOptions="$(get_options)"
local selection="$(fzf ${(f)myOptions})"
03 Feb 2023Given an array with a lot of values, I want to keep only one occurence of each value. I want to make those values unique.
The (u)
modifier
local myArray=(a b c d a b b)
echo ${(u)myArray} # a b c d
Applied on an array, the (u)
(for u
nique) deduplicates the array.
The typeset -aU
definition
Somehow, I didn't work in my case and I'm still unsure why, so I found another way.
By defining my variable as an array with unique values from the get go, I don't need to deduplicate it manually, it will automatically refuse duplicate values.
typeset -aU myArray
local myArray=(a b c d a b b)
echo ${(u)myArray} # a b c d
02 Feb 2023Another one of those things I need to often do in zsh and never remember the syntax.
I had a multiline string (as returned by fzf
) and wanted to convert it into a single line, with spaces instead of spaces.
This was the right formula: selection=("${(f)selection}")