Open ismay opened 1 year ago
That's a fair point. For the current version, you can have a look at the test.kak
file which makes use of the basic functionality of the plugin.
For the older version of the plugin, there used to be a repository with extensive configurations at https://github.com/andreyorst/kakoune-snippet-collection. Note that I don't plan to support this anymore.
That's a fair point. For the current version, you can have a look at the test.kak file which makes use of the basic functionality of the plugin.
Thanks. Yeah I went through that. So based on this example:
set -add buffer snippets 'snip1' 'trig1' %{ snippets-insert %{foo bar} }
I suppose iterating over a list of snippets sourced from a directory, add running set -add
for each snippet would be the way to go right? I went through your dotfiles and that of others using this plugin, but most of what I could find used the older version, so I'm just thinking what would be the most convenient way to use the new setup.
Here is one example on how you might define some language-specific snippets
hook global BufSetOption filetype=cpp %{
set buffer snippets %opt{snippets} # keep global snippets (if any)
set -add buffer snippets 'while-loop' 'whib' %{ snippets-insert %{while (${}) {
${}
}}}
set -add buffer snippets 'for-loop' 'forb' \
%{ phantom-selection-clear ; snippets-insert %{for (${}; ${}; ${}) {
${}
}}; phantom-selection-add-selection ; phantom-selection-iterate-next }
}
the for-loop one has integration with https://github.com/occivink/kakoune-phantom-selection, the while-loop one is standalone. The need for line-breaks in the middle of a snippet is a bit annoying, I might add an escape for newlines.
Nice, thanks for the examples 🙏. I'll try it out a bit, see what I come up with.
So something like this works:
#!/bin/bash
# ~/.config/kak/scripts/load-snippets.sh
config="$1"
snippetsdir="$config/snippets"
# Exit if there is no snippets directory
if [ ! -d "$snippetsdir" ]; then
exit 0
fi
snippets=$(find "$snippetsdir" -type f)
# Exit if there are no snippets
if [ -z "$snippets" ]; then
exit 0
fi
filetypes=()
for snippet in $snippets; do
name=$(basename "$snippet" | cut -d. -f1)
filetype=$(head -1 "$snippet")
trigger=$(head -2 "$snippet" | tail -1)
contents=$(tail -n +3 "$snippet" | sed s/\'/\'\'\'\'/g)
# Check if option was already registered
registered=0
for type in "${filetypes[@]}"; do
if [[ $type = "$filetype" ]]; then
registered=1
break
fi
done
# Register option if necessary
if [[ $registered = 0 ]]; then
echo "declare-option str-list snippets_$filetype"
filetypes+=("$filetype")
fi
echo "set -add global 'snippets_$filetype' '$name' '$trigger' 'snippets-insert ''$contents'' '"
done
Combined with this in a kakrc:
hook global KakBegin .* %{
eval %sh{ "$kak_config"/scripts/load-snippets.sh "$kak_config" }
}
hook global BufSetOption filetype=javascript %{
set buffer snippets %opt{snippets_javascript}
}
Snippets go in ~/.config/kak/snippets
and can be nested in subdirectories. Example javascript snippet:
javascript
trigger-here
console.log("Contents go here")
File name is used as the snippet name. First line is the filetype, second line the trigger (can be omitted) and third line and on the snippet.
Humble rewrite with POSIX script:
#!/bin/sh
config="$1"
snippetsdir="$config/snippets"
# Exit if there is no snippets directory
if [ ! -d "$snippetsdir" ]; then
exit 0
fi
find "$snippetsdir" -type f -exec head -1 {} \; |
sort -u |
xargs -n1 printf "declare-option str-list snippets_%s\n"
find "$snippetsdir" -type f | while read -r snippet; do
name="$(basename "$snippet" | cut -d. -f1)"
filetype="$(head -1 "$snippet")"
trigger="$(head -2 "$snippet" | tail -1)"
contents="$(tail -n +3 "$snippet" | sed s/\'/\'\'\'\'/g)"
printf "set -add global 'snippets_%s' '%s' '%s' 'snippets-insert ''%b'' '\n" \
"$filetype" \
"$name" \
"$trigger" \
"$contents"
done
Thanks @stacyharper! I'm currently using cheat. I use this script to insert the snippets in kakoune (sorry, bash again 😅):
#!/bin/bash
session="$1"
client="$2"
filetype="$3"
has_filetype=0
# Check if there are snippets tagged with filetype
if [ -n "$filetype" ] && cheat -p snippets -T | grep -q "^$filetype\$"; then
has_filetype=1
fi
if [ "$has_filetype" == "1" ]; then
selection=$(
cheat -p snippets -t "$filetype" -l | tail -n +2 | awk '{print $1}' |
fzf --preview "cheat -c -p snippets -t $filetype {}"
)
else
selection=$(
cheat -p snippets -l | tail -n +2 | awk '{print $1}' |
fzf --preview "cheat -c -p snippets {}"
)
fi
# Exit if there is no selection
if [ -z "$selection" ]; then
exit 1
fi
if [ "$has_filetype" == "1" ]; then
snippet=$(cheat -p snippets -t "$filetype" "$selection")
else
snippet=$(cheat -p snippets "$selection")
fi
snippet="${snippet//\'/\'\'}"
# Copy snippet to s register
echo "reg s '$snippet'" | kak -p "$session"
# Paste snippet from s register
echo "exec -client $client '\"'sP" | kak -p "$session"
Snippets can then be defined in the format cheat expects, so for js for example:
---
syntax: javascript
tags: [ javascript ]
---
array.forEach(element => {
});
The docs mention:
While this is descriptive, I'm still having a bit of trouble figuring out how I'd configure this plugin if I have, say, a directory of snippets somewhere. A real world configuration example for the snippets option would be appreciated!