From 2140ab51deed88e90eafebf9520fa5f9995dc7c9 Mon Sep 17 00:00:00 2001 From: twells46 <173561638+twells46@users.noreply.github.com> Date: Wed, 31 Dec 2025 13:28:05 -0600 Subject: Migrate from stow --- .../kak/autoload/rc/tools/autorestore.asciidoc | 13 + dot_config/kak/autoload/rc/tools/autorestore.kak | 93 +++ dot_config/kak/autoload/rc/tools/autowrap.kak | 50 ++ dot_config/kak/autoload/rc/tools/clang.kak | 196 +++++ dot_config/kak/autoload/rc/tools/comment.kak | 218 ++++++ dot_config/kak/autoload/rc/tools/ctags.kak | 168 +++++ dot_config/kak/autoload/rc/tools/doc.asciidoc | 45 ++ dot_config/kak/autoload/rc/tools/doc.kak | 195 +++++ dot_config/kak/autoload/rc/tools/fifo.kak | 35 + dot_config/kak/autoload/rc/tools/format.kak | 38 + dot_config/kak/autoload/rc/tools/git.kak | 787 +++++++++++++++++++++ dot_config/kak/autoload/rc/tools/go/gopls.kak | 98 +++ dot_config/kak/autoload/rc/tools/grep.kak | 66 ++ dot_config/kak/autoload/rc/tools/jump.kak | 70 ++ dot_config/kak/autoload/rc/tools/lint.asciidoc | 26 + dot_config/kak/autoload/rc/tools/lint.kak | 452 ++++++++++++ dot_config/kak/autoload/rc/tools/make.kak | 92 +++ dot_config/kak/autoload/rc/tools/man.kak | 139 ++++ dot_config/kak/autoload/rc/tools/menu.kak | 85 +++ dot_config/kak/autoload/rc/tools/patch-range.pl | 113 +++ dot_config/kak/autoload/rc/tools/patch.kak | 63 ++ dot_config/kak/autoload/rc/tools/python/jedi.kak | 77 ++ dot_config/kak/autoload/rc/tools/rust/racer.kak | 123 ++++ dot_config/kak/autoload/rc/tools/spell.kak | 184 +++++ 24 files changed, 3426 insertions(+) create mode 100644 dot_config/kak/autoload/rc/tools/autorestore.asciidoc create mode 100644 dot_config/kak/autoload/rc/tools/autorestore.kak create mode 100644 dot_config/kak/autoload/rc/tools/autowrap.kak create mode 100644 dot_config/kak/autoload/rc/tools/clang.kak create mode 100644 dot_config/kak/autoload/rc/tools/comment.kak create mode 100644 dot_config/kak/autoload/rc/tools/ctags.kak create mode 100644 dot_config/kak/autoload/rc/tools/doc.asciidoc create mode 100644 dot_config/kak/autoload/rc/tools/doc.kak create mode 100644 dot_config/kak/autoload/rc/tools/fifo.kak create mode 100644 dot_config/kak/autoload/rc/tools/format.kak create mode 100644 dot_config/kak/autoload/rc/tools/git.kak create mode 100644 dot_config/kak/autoload/rc/tools/go/gopls.kak create mode 100644 dot_config/kak/autoload/rc/tools/grep.kak create mode 100644 dot_config/kak/autoload/rc/tools/jump.kak create mode 100644 dot_config/kak/autoload/rc/tools/lint.asciidoc create mode 100644 dot_config/kak/autoload/rc/tools/lint.kak create mode 100644 dot_config/kak/autoload/rc/tools/make.kak create mode 100644 dot_config/kak/autoload/rc/tools/man.kak create mode 100644 dot_config/kak/autoload/rc/tools/menu.kak create mode 100644 dot_config/kak/autoload/rc/tools/patch-range.pl create mode 100644 dot_config/kak/autoload/rc/tools/patch.kak create mode 100644 dot_config/kak/autoload/rc/tools/python/jedi.kak create mode 100644 dot_config/kak/autoload/rc/tools/rust/racer.kak create mode 100644 dot_config/kak/autoload/rc/tools/spell.kak (limited to 'dot_config/kak/autoload/rc/tools') diff --git a/dot_config/kak/autoload/rc/tools/autorestore.asciidoc b/dot_config/kak/autoload/rc/tools/autorestore.asciidoc new file mode 100644 index 0000000..528fcf5 --- /dev/null +++ b/dot_config/kak/autoload/rc/tools/autorestore.asciidoc @@ -0,0 +1,13 @@ += Automatically restore unsaved work after a crash. + +When Kakoune crashes, it automatically writes out unsaved changes to backup +files with predictable names. When you edit a file, if such a backup file +exists, this plugin will automatically load the content of the backup file +instead. + +By default, backup files are deleted when restored. You can set the +`autorestore_purge_restored` option to `false` to prevent this. + +If you don't want backups to be restored automatically, use the +`autorestore-disable` command to disable the feature for the current session, +or put it in your `kakrc` to disable the feature forever. diff --git a/dot_config/kak/autoload/rc/tools/autorestore.kak b/dot_config/kak/autoload/rc/tools/autorestore.kak new file mode 100644 index 0000000..52febe3 --- /dev/null +++ b/dot_config/kak/autoload/rc/tools/autorestore.kak @@ -0,0 +1,93 @@ +declare-option -docstring %{ + Remove backups once they've been restored + + See `:doc autorestore` for details. + } \ + bool autorestore_purge_restored true + +## Insert the content of the backup file into the current buffer, if a suitable one is found +define-command autorestore-restore-buffer \ + -docstring %{ + Restore the backup for the current file if it exists + + See `:doc autorestore` for details. + } \ +%{ + evaluate-commands %sh{ + buffer_basename="${kak_buffile##*/}" + buffer_dirname=$(dirname "${kak_buffile}") + + if [ -f "${kak_buffile}" ]; then + newer=$(find "${buffer_dirname}"/".${buffer_basename}.kak."* -newer "${kak_buffile}" -exec ls -1t {} + 2>/dev/null | head -n 1) + older=$(find "${buffer_dirname}"/".${buffer_basename}.kak."* \! -newer "${kak_buffile}" -exec ls -1t {} + 2>/dev/null | head -n 1) + else + # New buffers that were never written to disk. + newer=$(ls -1t "${buffer_dirname}"/".${buffer_basename}.kak."* 2>/dev/null | head -n 1) + older="" + fi + + if [ -z "${newer}" ]; then + if [ -n "${older}" ]; then + printf %s\\n " + echo -debug Old backup file(s) found: will not restore ${older} . + " + fi + exit + fi + + printf %s\\n " + ## Replace the content of the buffer with the content of the backup file + echo -debug Restoring file: ${newer} + + execute-keys -draft %{%d!cat\"${newer}\"jd} + + ## If the backup file has to be removed, issue the command once + ## the current buffer has been saved + ## If the autorestore_purge_restored option has been unset right after the + ## buffer was restored, do not remove the backup + hook -group autorestore buffer BufWritePost '${kak_buffile}' %{ + nop %sh{ + if [ \"\${kak_opt_autorestore_purge_restored}\" = true ]; + then + rm -f \"${buffer_dirname}/.${buffer_basename}.kak.\"* + fi + } + } + " + } +} + +## Remove all the backups that have been created for the current buffer +define-command autorestore-purge-backups \ + -docstring %{ + Remove all the backups of the current buffer + + See `:doc autorestore` for details. + } \ +%{ + evaluate-commands %sh{ + [ ! -f "${kak_buffile}" ] && exit + + buffer_basename="${kak_bufname##*/}" + buffer_dirname=$(dirname "${kak_bufname}") + + rm -f "${buffer_dirname}/.${buffer_basename}.kak."* + + printf %s\\n " + echo -markup {Information}Backup files removed. + " + } +} + +## If for some reason, backup files need to be ignored +define-command autorestore-disable \ + -docstring %{ + Disable automatic backup recovering + + See `:doc autorestore` for details. + } \ +%{ + remove-hooks global autorestore +} + +hook -group autorestore global BufCreate .* %{ autorestore-restore-buffer } diff --git a/dot_config/kak/autoload/rc/tools/autowrap.kak b/dot_config/kak/autoload/rc/tools/autowrap.kak new file mode 100644 index 0000000..d742f6e --- /dev/null +++ b/dot_config/kak/autoload/rc/tools/autowrap.kak @@ -0,0 +1,50 @@ +declare-option -docstring "maximum amount of characters per line, after which a newline character will be inserted" \ + int autowrap_column 80 + +declare-option -docstring %{ + when enabled, paragraph formatting will reformat the whole paragraph in which characters are being inserted + This can potentially break formatting of documents containing markup (e.g. markdown) +} bool autowrap_format_paragraph no +declare-option -docstring %{ + command to which the paragraphs to wrap will be passed + all occurences of '%c' are replaced with `autowrap_column` +} str autowrap_fmtcmd 'fold -s -w %c' + +define-command -hidden autowrap-cursor %{ evaluate-commands -save-regs '/"|^@m' %{ + try %{ + ## if the line isn't too long, do nothing + execute-keys -draft "x^[^\n]{%opt{autowrap_column},}[^\n]" + + try %{ + reg m "%val{selections_desc}" + + ## if we're adding characters past the limit, just wrap them around + execute-keys -draft ".{%opt{autowrap_column}}\h*[^\s]*1s(\h+)[^\h]*\zc" + } catch %{ + ## if we're adding characters in the middle of a sentence, use + ## the `fmtcmd` command to wrap the entire paragraph + evaluate-commands %sh{ + if [ "${kak_opt_autowrap_format_paragraph}" = true ] \ + && [ -n "${kak_opt_autowrap_fmtcmd}" ]; then + format_cmd=$(printf %s "${kak_opt_autowrap_fmtcmd}" \ + | sed "s/%c/${kak_opt_autowrap_column}/g") + printf %s " + evaluate-commands -draft %{ + execute-keys 'px|${format_cmd}' + try %{ execute-keys s\h+$ d } + } + select '${kak_main_reg_m}' + " + fi + } + } + } +} } + +define-command autowrap-enable -docstring "Automatically wrap the lines in which characters are inserted" %{ + hook -group autowrap window InsertChar [^\n] autowrap-cursor +} + +define-command autowrap-disable -docstring "Disable automatic line wrapping" %{ + remove-hooks window autowrap +} diff --git a/dot_config/kak/autoload/rc/tools/clang.kak b/dot_config/kak/autoload/rc/tools/clang.kak new file mode 100644 index 0000000..41f6c55 --- /dev/null +++ b/dot_config/kak/autoload/rc/tools/clang.kak @@ -0,0 +1,196 @@ +hook -once global BufSetOption filetype=(c|cpp) %{ + require-module clang +} + +provide-module clang %[ + +declare-option -docstring "options to pass to the `clang` shell command" \ + str clang_options + +declare-option -docstring "directory from which to invoke clang" \ + str clang_directory + +declare-option -hidden completions clang_completions +declare-option -hidden line-specs clang_flags +declare-option -hidden line-specs clang_errors + +define-command -params ..1 \ + -docstring %{ + Parse the contents of the current buffer + The syntaxic errors detected during parsing are shown when auto-diagnostics are enabled + } clang-parse %{ + evaluate-commands %sh{ + dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-clang.XXXXXXXX) + mkfifo ${dir}/fifo + printf %s\\n " + evaluate-commands -no-hooks write -sync -method replace ${dir}/buf + evaluate-commands -draft %{ + edit! -fifo ${dir}/fifo -debug *clang-output* + set-option buffer filetype make + set-option buffer jump_current_line 0 + hook -once -always buffer BufCloseFifo .* %{ nop %sh{ rm -r ${dir} } } + }" + + # this runs in a detached shell, asynchronously, so that kakoune does + # not hang while clang is running. As completions references a cursor + # position and a buffer timestamp, only valid completions should be + # displayed. + (( + trap - INT QUIT + until [ -f ${dir}/buf ]; do :; done # wait for the buffer to be written + + if [ -n "$kak_opt_clang_directory" ]; then + cd "$kak_opt_clang_directory" + fi + case ${kak_opt_filetype} in + (c) ft=c ;; + (cpp) ft=c++ ;; + (obj-c) ft=objective-c ;; + (*) ft=c++ ;; + esac + + if [ "$1" = "-complete" ]; then + pos=-:${kak_cursor_line}:${kak_cursor_column} + header="${kak_cursor_line}.${kak_cursor_column}@${kak_timestamp}" + compl=$(clang++ -x ${ft} -fsyntax-only ${kak_opt_clang_options} \ + -Xclang -code-completion-brief-comments -Xclang -code-completion-at=${pos} - < ${dir}/buf 2> ${dir}/stderr | + awk -F ': ' ' + /^COMPLETION:/ && $2 !~ /[(,](Hidden|Inaccessible)[),]/ { + candidate=$3 + gsub(/[[<{]#[^#]*#[]>}]/, "", candidate) + gsub(/~/, "~~", candidate) + gsub(/\|/, "\\|", candidate) + + gsub(/[[{<]#|#[]}>]/, " ", $3) + gsub(/:: /, "::", $3) + gsub(/ ,/, ",", $3) + gsub(/^ +| +$/, "", $3) + docstring=$4 ? $3 "\n" $4 : $3 + + gsub(/~|!/, "&&", docstring) + gsub(/\|/, "\\|", docstring) + if (candidate in candidates) + candidates[candidate]=candidates[candidate] "\n" docstring + else + candidates[candidate]=docstring + } + END { + for (candidate in candidates) { + menu=candidate + gsub(/(^|[^[:alnum:]_])(operator|new|delete)($|[^{}_[:alnum:]]+)/, "{keyword}&{}", menu) + gsub(/(^|[[:space:]])(int|size_t|bool|char|unsigned|signed|long)($|[[:space:]])/, "{type}&{}", menu) + gsub(/[^{}_[:alnum:]]+/, "{operator}&{}", menu) + printf "%%~%s|info -style menu %!%s!|%s~ ", candidate, candidates[candidate], menu + } + }') + printf %s\\n "evaluate-commands -client ${kak_client} echo 'clang completion done' + set-option 'buffer=${kak_buffile}' clang_completions ${header} ${compl}" | kak -p ${kak_session} + else + clang++ -x ${ft} -fsyntax-only ${kak_opt_clang_options} - < ${dir}/buf 2> ${dir}/stderr + printf %s\\n "evaluate-commands -client ${kak_client} echo 'clang parsing done'" | kak -p ${kak_session} + fi + + flags=$(cat ${dir}/stderr | sed -Ene " + /^:[0-9]+:([0-9]+:)? (fatal )?error/ { s/^:([0-9]+):.*/'\1|{red}█'/; p } + /^:[0-9]+:([0-9]+:)? warning/ { s/^:([0-9]+):.*/'\1|{yellow}█'/; p } + " | paste -s -d ' ' -) + + errors=$(cat ${dir}/stderr | sed -Ene " + /^:[0-9]+:([0-9]+:)? ((fatal )?error|warning)/ { + s/'/''/g; s/^:([0-9]+):([0-9]+:)? (.*)/'\1|\3'/; p + }" | sort -n | paste -s -d ' ' -) + + sed -e "s||${kak_bufname}|g" < ${dir}/stderr > ${dir}/fifo + + printf %s\\n "set-option 'buffer=${kak_buffile}' clang_flags ${kak_timestamp} ${flags} + set-option 'buffer=${kak_buffile}' clang_errors ${kak_timestamp} ${errors}" | kak -p ${kak_session} + ) & ) > /dev/null 2>&1 < /dev/null + } +} + +define-command clang-complete -docstring "Complete the current selection" %{ clang-parse -complete } + +define-command -hidden clang-show-completion-info %[ try %[ + evaluate-commands -draft %[ + execute-keys ,{( ^\( b \A\w+\z + evaluate-commands %sh[ + desc=$(printf %s\\n "${kak_opt_clang_completions}" | sed -e "{ s/\([^\\]\):/\1\n/g }" | sed -ne "/^${kak_selection}|/ { s/^[^|]\+|//; s/|.*$//; s/\\\:/:/g; p }") + if [ -n "$desc" ]; then + printf %s\\n "evaluate-commands -client $kak_client %{info -anchor ${kak_cursor_line}.${kak_cursor_column} -style above %{${desc}}}" + fi + ] ] +] ] + +define-command clang-enable-autocomplete -docstring "Enable automatic clang completion" %{ + set-option window completers "option=clang_completions" %opt{completers} + hook window -group clang-autocomplete InsertIdle .* %{ + try %{ + execute-keys -draft (\.|->|::).\z + echo 'completing...' + clang-complete + } + clang-show-completion-info + } + alias window complete clang-complete +} + +define-command clang-disable-autocomplete -docstring "Disable automatic clang completion" %{ + evaluate-commands %sh{ printf "set-option window completers %s\n" $(printf %s "${kak_opt_completers}" | sed -e "s/'option=clang_completions'//g") } + remove-hooks window clang-autocomplete + unalias window complete clang-complete +} + +define-command -hidden clang-show-error-info %{ + update-option buffer clang_errors # Ensure we are up to date with buffer changes + evaluate-commands %sh{ + eval "set -- ${kak_quoted_opt_clang_errors}" + shift # skip timestamp + desc=$(for error in "$@"; do + if [ "${error%%|*}" = "$kak_cursor_line" ]; then + printf '%s\n' "${error##*|}" + fi + done) + if [ -n "$desc" ]; then + desc=$(printf %s "${desc}" | sed "s/'/''/g") + printf "info -anchor %d.%d '%s'\n" "${kak_cursor_line}" "${kak_cursor_column}" "${desc}" + fi + } } + +define-command clang-enable-diagnostics -docstring %{ + Activate automatic error reporting and diagnostics + Information about the analysis will be shown after the buffer has been parsed with the clang-parse function +} %{ + add-highlighter window/clang_flags flag-lines default clang_flags + hook window -group clang-diagnostics NormalIdle .* %{ clang-show-error-info } + hook window -group clang-diagnostics WinSetOption ^clang_errors=.* %{ info; clang-show-error-info } +} + +define-command clang-disable-diagnostics -docstring "Disable automatic error reporting and diagnostics" %{ + remove-highlighter window/clang_flags + remove-hooks window clang-diagnostics +} + +define-command clang-diagnostics-next -docstring "Jump to the next line that contains an error" %{ + update-option buffer clang_errors # Ensure we are up to date with buffer changes + evaluate-commands %sh{ + eval "set -- ${kak_quoted_opt_clang_errors}" + shift # skip timestamp + unset line + unset first_line + for error in "$@"; do + candidate=${error%%|*} + first_line=${first_line-$candidate} + if [ "$candidate" -gt $kak_cursor_line ]; then + line=$candidate + break + fi + done + line=${line-$first_line} + if [ -n "$line" ]; then + printf %s\\n "execute-keys ${line} g" + else + echo "fail no next clang diagnostic" + fi + } } + +] diff --git a/dot_config/kak/autoload/rc/tools/comment.kak b/dot_config/kak/autoload/rc/tools/comment.kak new file mode 100644 index 0000000..b610073 --- /dev/null +++ b/dot_config/kak/autoload/rc/tools/comment.kak @@ -0,0 +1,218 @@ +# Line comments +# If the language has no line comments, set to '' +declare-option -docstring "characters inserted at the beginning of a commented line" \ + str comment_line '#' + +# Block comments +declare-option -docstring "characters inserted before a commented block" \ + str comment_block_begin +declare-option -docstring "characters inserted after a commented block" \ + str comment_block_end + +# Default comments for all languages +hook global BufSetOption filetype=asciidoc %{ + set-option buffer comment_line '//' + set-option buffer comment_block_begin '////' + set-option buffer comment_block_end '////' +} + +hook global BufSetOption filetype=(c|cpp|dart|gluon|go|java|javascript|objc|odin|php|pony|protobuf|rust|sass|scala|scss|swift|typescript|groovy) %{ + set-option buffer comment_line '//' + set-option buffer comment_block_begin '/*' + set-option buffer comment_block_end '*/' +} + +hook global BufSetOption filetype=(cabal|haskell|moon|idris|elm|dhall|purescript) %{ + set-option buffer comment_line '--' + set-option buffer comment_block_begin '{-' + set-option buffer comment_block_end '-}' +} + +hook global BufSetOption filetype=clojure %{ + set-option buffer comment_line '#_' + set-option buffer comment_block_begin '(comment ' + set-option buffer comment_block_end ')' +} + +hook global BufSetOption filetype=janet %{ + set-option buffer comment_line '#' + set-option buffer comment_block_begin '(comment ' + set-option buffer comment_block_end ')' +} + +hook global BufSetOption filetype=coffee %{ + set-option buffer comment_block_begin '###' + set-option buffer comment_block_end '###' +} + +hook global BufSetOption filetype=conf %{ + set-option buffer comment_line '#' +} + +hook global BufSetOption filetype=css %{ + set-option buffer comment_line '' + set-option buffer comment_block_begin '/*' + set-option buffer comment_block_end '*/' +} + +hook global BufSetOption filetype=d %{ + set-option buffer comment_line '//' + set-option buffer comment_block_begin '/+' + set-option buffer comment_block_end '+/' +} + +hook global BufSetOption filetype=(fennel|gas|ini) %{ + set-option buffer comment_line ';' +} + +hook global BufSetOption filetype=haml %{ + set-option buffer comment_line '-#' +} + +hook global BufSetOption filetype=(html|xml) %{ + set-option buffer comment_line '' + set-option buffer comment_block_begin '' +} + +hook global BufSetOption filetype=(latex|mercury) %{ + set-option buffer comment_line '%' +} + +hook global BufSetOption filetype=ledger %{ + set-option buffer comment_line ';' +} + +hook global BufSetOption filetype=(lisp|scheme) %{ + set-option buffer comment_line ';' + set-option buffer comment_block_begin '#|' + set-option buffer comment_block_end '|#' +} + +hook global BufSetOption filetype=lua %{ + set-option buffer comment_line '--' + set-option buffer comment_block_begin '--[[' + set-option buffer comment_block_end ']]' +} + +hook global BufSetOption filetype=markdown %{ + set-option buffer comment_line '' + set-option buffer comment_block_begin '[//]: # "' + set-option buffer comment_block_end '"' +} + +hook global BufSetOption filetype=(ocaml|coq) %{ + set-option buffer comment_line '' + set-option buffer comment_block_begin '(* ' + set-option buffer comment_block_end ' *)' +} + +hook global BufSetOption filetype=((free|object)?pascal|delphi) %{ + set-option buffer comment_line '//' + set-option buffer comment_block_begin '{' + set-option buffer comment_block_end '}' +} + +hook global BufSetOption filetype=perl %{ + set-option buffer comment_block_begin '#[' + set-option buffer comment_block_end ']' +} + +hook global BufSetOption filetype=(pug|zig|cue|hare) %{ + set-option buffer comment_line '//' +} + +hook global BufSetOption filetype=python %{ + set-option buffer comment_block_begin "'''" + set-option buffer comment_block_end "'''" +} + +hook global BufSetOption filetype=r %{ + set-option buffer comment_line '#' +} + +hook global BufSetOption filetype=ragel %{ + set-option buffer comment_line '%%' + set-option buffer comment_block_begin '%%{' + set-option buffer comment_block_end '}%%' +} + +hook global BufSetOption filetype=ruby %{ + set-option buffer comment_block_begin '^begin=' + set-option buffer comment_block_end '^=end' +} + +hook global BufSetOption filetype=sql %{ + set-option buffer comment_line '--' + set-option buffer comment_block_begin '/*' + set-option buffer comment_block_end '*/' +} + +define-command comment-block -docstring '(un)comment selections using block comments' %{ + evaluate-commands %sh{ + if [ -z "${kak_opt_comment_block_begin}" ] || [ -z "${kak_opt_comment_block_end}" ]; then + echo "fail \"The 'comment_block' options are empty, could not comment the selection\"" + fi + } + evaluate-commands -save-regs '"/' -draft %{ + # Keep non-empty selections + execute-keys \A\s*\z + + try %{ + # Assert that the selection has been commented + set-register / "\A\Q%opt{comment_block_begin}\E.*\Q%opt{comment_block_end}\E\n*\z" + execute-keys "s" + # Uncomment it + set-register / "\A\Q%opt{comment_block_begin}\E|\Q%opt{comment_block_end}\E\n*\z" + execute-keys sd + } catch %{ + # Comment the selection + set-register '"' "%opt{comment_block_begin}" + execute-keys -draft P + set-register '"' "%opt{comment_block_end}" + execute-keys p + } + } +} + +define-command comment-line -docstring '(un)comment selected lines using line comments' %{ + evaluate-commands %sh{ + if [ -z "${kak_opt_comment_line}" ]; then + echo "fail \"The 'comment_line' option is empty, could not comment the line\"" + fi + } + evaluate-commands -save-regs '"/' -draft %{ + # Select the content of the lines, without indentation + execute-keys gi + + try %{ + # Keep non-empty lines + execute-keys \A\s*\z + } + + try %{ + set-register / "\A\Q%opt{comment_line}\E\h?" + + try %{ + # See if there are any uncommented lines in the selection + execute-keys -draft + + # There are uncommented lines, so comment everything + set-register '"' "%opt{comment_line} " + align-selections-left + execute-keys P + } catch %{ + # All lines were commented, so uncomment everything + execute-keys sd + } + } + } +} + +define-command align-selections-left -docstring 'extend selections to the left to align with the leftmost selected column' %{ + evaluate-commands %sh{ + leftmost_column=$(echo "$kak_selections_desc" | tr ' ' '\n' | cut -d',' -f1 | cut -d'.' -f2 | sort -n | head -n1) + aligned_selections=$(echo "$kak_selections_desc" | sed -E "s/\.[0-9]+,/.$leftmost_column,/g") + echo "select $aligned_selections" + } +} diff --git a/dot_config/kak/autoload/rc/tools/ctags.kak b/dot_config/kak/autoload/rc/tools/ctags.kak new file mode 100644 index 0000000..9ad9cbb --- /dev/null +++ b/dot_config/kak/autoload/rc/tools/ctags.kak @@ -0,0 +1,168 @@ +# Kakoune CTags support script +# +# This script requires the readtags command available in universal-ctags + +declare-option -docstring "minimum characters before triggering autocomplete" \ + int ctags_min_chars 3 + +declare-option -docstring "list of paths to tag files to parse when looking up a symbol" \ + str-list ctagsfiles 'tags' + +declare-option -hidden completions ctags_completions + +declare-option -docstring "shell command to run" str readtagscmd "readtags" + +define-command -params ..1 \ + -shell-script-candidates %{ + realpath() { ( cd "$(dirname "$1")"; printf "%s/%s\n" "$(pwd -P)" "$(basename "$1")" ) } + eval "set -- $kak_quoted_opt_ctagsfiles" + for candidate in "$@"; do + [ -f "$candidate" ] && realpath "$candidate" + done | awk '!x[$0]++;' | # remove duplicates + while read -r tags; do + namecache="${tags%/*}/.kak.${tags##*/}.namecache" + if [ -z "$(find "$namecache" -prune -newer "$tags")" ]; then + cut -f 1 "$tags" | grep -v '^!' | uniq > "$namecache" + fi + cat "$namecache" + done + } \ + -docstring %{ + ctags-search []: jump to a symbol's definition + If no symbol is passed then the current selection is used as symbol name + } \ + ctags-search %[ require-module menu; evaluate-commands %sh[ + realpath() { ( cd "$(dirname "$1")"; printf "%s/%s\n" "$(pwd -P)" "$(basename "$1")" ) } + export tagname="${1:-${kak_selection}}" + eval "set -- $kak_quoted_opt_ctagsfiles" + for candidate in "$@"; do + [ -f "$candidate" ] && realpath "$candidate" + done | awk '!x[$0]++' | # remove duplicates + while read -r tags; do + printf '!TAGROOT\t%s\n' "$(realpath "${tags%/*}")/" + ${kak_opt_readtagscmd} -t "$tags" "$tagname" + done | awk -F '\t|\n' ' + /^!TAGROOT\t/ { tagroot=$2 } + /[^\t]+\t[^\t]+\t\/\^.*\$?\// { + line = $0; sub(".*\t/\\^", "", line); sub("\\$?/$", "", line); + menu_info = line; gsub("!", "!!", menu_info); gsub(/^[\t ]+/, "", menu_info); gsub(/\t/, " ", menu_info); + keys = line; gsub(/", keys); gsub(/\t/, "", keys); gsub("!", "!!", keys); gsub("&", "&&", keys); gsub("#", "##", keys); gsub("\\|", "||", keys); gsub("\\\\/", "/", keys); + menu_item = $2; gsub("!", "!!", menu_item); + edit_path = path($2); gsub("&", "&&", edit_path); gsub("#", "##", edit_path); gsub("\\|", "||", edit_path); + select = $1; gsub(/", select); gsub(/\t/, "", select); gsub("!", "!!", select); gsub("&", "&&", select); gsub("#", "##", select); gsub("\\|", "||", select); + out = out "%!" menu_item ": " menu_info "! %!evaluate-commands %# try %& edit -existing %|" edit_path "|; execute-keys %|/\\Q" keys "vc| & catch %& fail unable to find tag &; try %& execute-keys %|s\\Q" select "| & # !" + } + /[^\t]+\t[^\t]+\t[0-9]+/ { + menu_item = $2; gsub("!", "!!", menu_item); + select = $1; gsub(/", select); gsub(/\t/, "", select); gsub("!", "!!", select); gsub("&", "&&", select); gsub("#", "##", select); gsub("\\|", "||", select); + menu_info = $3; gsub("!", "!!", menu_info); + edit_path = path($2); gsub("!", "!!", edit_path); gsub("#", "##", edit_path); gsub("&", "&&", edit_path); gsub("\\|", "||", edit_path); + line_number = $3; + out = out "%!" menu_item ": " menu_info "! %!evaluate-commands %# try %& edit -existing %|" edit_path "|; execute-keys %|" line_number "gx| & catch %& fail unable to find tag &; try %& execute-keys %|s\\Q" select "| & # !" + } + END { print ( length(out) == 0 ? "fail no such tag " ENVIRON["tagname"] : "menu -markup -auto-single " out ) } + # Ensure x is an absolute file path, by prepending with tagroot + function path(x) { return x ~/^\// ? x : tagroot x }' + ]] + +define-command ctags-complete -docstring "Complete the current selection" %{ + nop %sh{ + ( + header="${kak_cursor_line}.${kak_cursor_column}@${kak_timestamp}" + compl=$( + eval "set -- $kak_quoted_opt_ctagsfiles" + for ctagsfile in "$@"; do + ${kak_opt_readtagscmd} -p -t "$ctagsfile" ${kak_selection} + done | awk '{ uniq[$1]++ } END { for (elem in uniq) printf " %s||%s", elem, elem }' + ) + printf %s\\n "evaluate-commands -client ${kak_client} set-option buffer=${kak_bufname} ctags_completions ${header}${compl}" | \ + kak -p ${kak_session} + ) > /dev/null 2>&1 < /dev/null & + } +} + +define-command ctags-funcinfo -docstring "Display ctags information about a selected function" %{ + evaluate-commands -draft %{ + try %{ + execute-keys '[(;B[a-zA-Z_]+\(' + evaluate-commands %sh{ + f=${kak_selection%?} + sig='\tsignature:(.*)' + csn='\t(class|struct|namespace):(\S+)' + sigs=$(${kak_opt_readtagscmd} -e -Q '(eq? $kind "f")' "${f}" | sed -Ee "s/^.*${csn}.*${sig}$/\3 [\2::${f}]/ ;t ;s/^.*${sig}$/\1 [${f}]/") + if [ -n "$sigs" ]; then + printf %s\\n "evaluate-commands -client ${kak_client} %{info -anchor $kak_cursor_line.$kak_cursor_column -style above '$sigs'}" + fi + } + } + } +} + +define-command ctags-enable-autoinfo -docstring "Automatically display ctags information about function" %{ + hook window -group ctags-autoinfo NormalIdle .* ctags-funcinfo + hook window -group ctags-autoinfo InsertIdle .* ctags-funcinfo +} + +define-command ctags-disable-autoinfo -docstring "Disable automatic ctags information displaying" %{ remove-hooks window ctags-autoinfo } + +declare-option -docstring "shell command to run" \ + str ctagscmd "ctags -R --fields=+S" +declare-option -docstring "path to the directory in which the tags file will be generated" str ctagspaths "." + +define-command ctags-generate -docstring 'Generate tag file asynchronously' %{ + echo -markup "{Information}launching tag generation in the background" + nop %sh{ ( + trap - INT QUIT + while ! mkdir .tags.kaklock 2>/dev/null; do sleep 1; done + trap 'rmdir .tags.kaklock' EXIT + + if ${kak_opt_ctagscmd} -f .tags.kaktmp ${kak_opt_ctagspaths}; then + mv .tags.kaktmp tags + msg="tags generation complete" + else + msg="tags generation failed" + fi + + printf %s\\n "evaluate-commands -client $kak_client echo -markup '{Information}${msg}'" | kak -p ${kak_session} + ) > /dev/null 2>&1 < /dev/null & } +} + +define-command ctags-update-tags -docstring 'Update tags for the given file' %{ + nop %sh{ ( + trap - INT QUIT + while ! mkdir .tags.kaklock 2>/dev/null; do sleep 1; done + trap 'rmdir .tags.kaklock' EXIT + + if ${kak_opt_ctagscmd} -f .file_tags.kaktmp $kak_bufname; then + export LC_COLLATE=C LC_ALL=C # ensure ASCII sorting order + # merge the updated tags tags with the general tags (filtering out out of date tags from it) into the target file + grep -Fv "$(printf '\t%s\t' "$kak_bufname")" tags | grep -v '^!' | sort --merge - .file_tags.kaktmp >> .tags.kaktmp + rm .file_tags.kaktmp + mv .tags.kaktmp tags + msg="tags updated for $kak_bufname" + else + msg="tags update failed for $kak_bufname" + fi + + printf %s\\n "evaluate-commands -client $kak_client echo -markup '{Information}${msg}'" | kak -p ${kak_session} + ) > /dev/null 2>&1 < /dev/null & } +} + +define-command ctags-enable-autocomplete -docstring "Enable automatic ctags completion" %{ + set-option window completers "option=ctags_completions" %opt{completers} + hook window -group ctags-autocomplete InsertIdle .* %{ + try %{ + evaluate-commands -draft %{ # select previous word >= ctags_min_chars + execute-keys ",b_.{%opt{ctags_min_chars},}" + ctags-complete # run in draft context to preserve selection + } + } + } +} + +define-command ctags-disable-autocomplete -docstring "Disable automatic ctags completion" %{ + evaluate-commands %sh{ + printf "set-option window completers %s\n" $(printf %s "${kak_opt_completers}" | sed -e "s/'option=ctags_completions'//g") + } + remove-hooks window ctags-autocomplete +} diff --git a/dot_config/kak/autoload/rc/tools/doc.asciidoc b/dot_config/kak/autoload/rc/tools/doc.asciidoc new file mode 100644 index 0000000..bb2e262 --- /dev/null +++ b/dot_config/kak/autoload/rc/tools/doc.asciidoc @@ -0,0 +1,45 @@ += Kakoune's online documentation + +This is Kakoune's online documentation system. + +To see what documentation topics are available, type `:doc` and look at the +completion menu. To view a particular topic, type its name or select it +from the completion menu. Then hit Enter. + +Documentation will be displayed in the client named in the `docsclient` option. + +== Using the documentation browser + +Documentation buffers are like any other buffer, so you can scroll through +them as normal, search within a topic with `/`, etc. However, they can also +contain links: <>. Links can be followed +by moving the cursor onto them and pressing Enter. If a link takes you to +a different documentation topic, you can return to the original by using the +`:buffer` command. + +== Writing documentation + +Documentation must be in AsciiDoc format, with the extension `.asciidoc`. +It must be stored somewhere within <>. Kakoune's built-in documentation renderer does not necessarily +support every feature, so don't go overboard with formatting. + +To create a link to another documentation topic, the URL should be the topic's +name, just like `:doc` uses. Because topics are identified only by their +basename, you should take care that your topic's name does not conflict with +any of the names used either by other plugins or by Kakoune's standard library. + +== Sources + +The `:doc` command searches within the following locations for +documents in the AsciiDoc format (`*.asciidoc`): + +* The user plugin directory, `"%val{config}/autoload"` +* The system documentation directory, `"%val{runtime}/doc"` +* The system plugin directory, `"%val{runtime}/rc"` + +It searches recursively, and follows symlinks. + +== Demonstration target + +Well done! You can <>! diff --git a/dot_config/kak/autoload/rc/tools/doc.kak b/dot_config/kak/autoload/rc/tools/doc.kak new file mode 100644 index 0000000..4b6afe3 --- /dev/null +++ b/dot_config/kak/autoload/rc/tools/doc.kak @@ -0,0 +1,195 @@ +declare-option -docstring "name of the client in which documentation is to be displayed" \ + str docsclient + +declare-option -hidden range-specs doc_render_ranges +declare-option -hidden range-specs doc_links +declare-option -hidden range-specs doc_anchors + +define-command -hidden -params 4 doc-render-regex %{ + evaluate-commands -draft %{ try %{ + execute-keys s %arg{1} + execute-keys -draft s %arg{2} d + execute-keys "%arg{3}" + evaluate-commands %sh{ + face="$4" + eval "set -- $kak_quoted_selections_desc" + ranges="" + for desc in "$@"; do ranges="$ranges '$desc|$face'"; done + echo "update-option buffer doc_render_ranges" + echo "set-option -add buffer doc_render_ranges $ranges" + } + } } +} + +define-command -hidden doc-parse-links %{ + evaluate-commands -draft %{ try %{ + execute-keys s (.*?),.*? + execute-keys -draft s .*,| d + execute-keys H + set-option buffer doc_links %val{timestamp} + update-option buffer doc_render_ranges + evaluate-commands -itersel %{ + set-option -add buffer doc_links "%val{selection_desc}|%reg{1}" + set-option -add buffer doc_render_ranges "%val{selection_desc}|default+u" + } + } } +} + +define-command -hidden doc-parse-anchors %{ + evaluate-commands -draft %{ try %{ + set-option buffer doc_anchors %val{timestamp} + # Find sections as add them as imlicit anchors + execute-keys s ^={2,}\h+([^\n]+)$ + evaluate-commands -itersel %{ + set-option -add buffer doc_anchors "%val{selection_desc}|%sh{printf '%s' ""$kak_main_reg_1"" | tr '[A-Z ]' '[a-z-]'}" + } + + # Parse explicit anchors and remove their text + execute-keys s \[\[(.*?)\]\]\s* + evaluate-commands -itersel %{ + set-option -add buffer doc_anchors "%val{selection_desc}|%reg{1}" + } + execute-keys d + update-option buffer doc_anchors + } } +} + +define-command -hidden doc-jump-to-anchor -params 1 %{ + update-option buffer doc_anchors + evaluate-commands %sh{ + anchor="$1" + eval "set -- $kak_quoted_opt_doc_anchors" + + shift + for range in "$@"; do + if [ "${range#*|}" = "$anchor" ]; then + printf '%s\n' "select '${range%|*}'; execute-keys vv" + exit + fi + done + printf "fail No such anchor '%s'\n" "${anchor}" + } +} + +define-command -hidden doc-follow-link %{ + update-option buffer doc_links + evaluate-commands %sh{ + eval "set -- $kak_quoted_opt_doc_links" + for link in "$@"; do + printf '%s\n' "$link" + done | awk -v FS='[.,|#]' ' + BEGIN { + l=ENVIRON["kak_cursor_line"]; + c=ENVIRON["kak_cursor_column"]; + } + l >= $1 && c >= $2 && l <= $3 && c <= $4 { + if (NF == 6) { + print "doc " $5 + if ($6 != "") { + print "doc-jump-to-anchor %{" $6 "}" + } + } else { + print "doc-jump-to-anchor %{" $5 "}" + } + exit + } + ' + } +} + +define-command -params 1 -hidden doc-render %{ + edit! -scratch "*doc-%sh{basename $1 .asciidoc}*" + execute-keys "!cat '%arg{1}'gg" + + doc-parse-anchors + + # Join paragraphs together + try %{ + execute-keys -draft '%S\n{2,}|(?=\+)\n|^[^\n]+::\n|^\h*[*-]\h+' \ + ^\h*-{2,}(\n|\z) S\n\z \n + } + + # Remove some line end markers + try %{ execute-keys -draft s \h*(\+|:{2,})$ d } + + # Setup the doc_render_ranges option + set-option buffer doc_render_ranges %val{timestamp} + doc-render-regex \B(? s \\((?=\*)|(?=`)) d } + # Go to beginning of file + execute-keys 'gg' + + set-option buffer readonly true + add-highlighter buffer/ ranges doc_render_ranges + add-highlighter buffer/ wrap -word -indent + map buffer normal :doc-follow-link +} + +define-command doc -params 0..2 -docstring %{ + doc []: open a buffer containing documentation about a given topic + An optional keyword argument can be passed to the function, which will be automatically selected in the documentation + + See `:doc doc` for details. + } %{ + evaluate-commands %sh{ + topic="doc" + if [ $# -ge 1 ]; then + topic="$1" + fi + page=$( + find -L \ + "${kak_config}/autoload/" \ + "${kak_runtime}/doc/" \ + "${kak_runtime}/rc/" \ + -type f -name "$topic.asciidoc" 2>/dev/null | + head -1 + ) + if [ -f "${page}" ]; then + jump_cmd="" + if [ $# -eq 2 ]; then + jump_cmd="doc-jump-to-anchor '$2'" + fi + printf %s\\n "evaluate-commands -try-client %opt{docsclient} %{ doc-render ${page}; ${jump_cmd} }" + else + printf 'fail No such doc file: %s\n' "$topic.asciidoc" + fi + } +} + +complete-command -menu doc shell-script-candidates %{ + case "$kak_token_to_complete" in + 0) + find -L \ + "${kak_config}/autoload/" \ + "${kak_runtime}/doc/" \ + "${kak_runtime}/rc/" \ + -type f -name "*.asciidoc" 2>/dev/null | + sed 's,.*/,,; s/\.[^.]*$//';; + 1) + page=$( + find -L \ + "${kak_config}/autoload/" \ + "${kak_runtime}/doc/" \ + "${kak_runtime}/rc/" \ + -type f -name "$1.asciidoc" 2>/dev/null | + head -1 + ) + if [ -f "${page}" ]; then + awk ' + /^==+ +/ { sub(/^==+ +/, ""); print } + /^\[\[[^\]]+\]\]/ { sub(/^\[\[/, ""); sub(/\]\].*/, ""); print } + ' < $page | tr '[A-Z ]' '[a-z-]' + fi;; + esac | sort +} + +alias global help doc diff --git a/dot_config/kak/autoload/rc/tools/fifo.kak b/dot_config/kak/autoload/rc/tools/fifo.kak new file mode 100644 index 0000000..ea98c0e --- /dev/null +++ b/dot_config/kak/autoload/rc/tools/fifo.kak @@ -0,0 +1,35 @@ +provide-module fifo %{ + +define-command -params .. -docstring %{ + fifo [-name ] [-scroll] [-script