├── README.md ├── UNLICENSE ├── autodownload.asciidoc ├── autodownload.kak ├── autosplit.asciidoc ├── autosplit.kak ├── cdmenu.asciidoc ├── cdmenu.kak ├── comnotes.kak ├── dictcomplete.asciidoc ├── dictcomplete.kak ├── dvtm.kak ├── filetype ├── bitbake.kak ├── clearsilver.kak ├── django-template.kak ├── git.kak ├── mutt.kak ├── openelec.kak ├── pkgbuild.kak ├── riotjs.kak └── sdl.kak ├── fzf.asciidoc ├── fzf.kak ├── fzy.asciidoc ├── fzy.kak ├── games ├── minesweeper.kak └── sokoban.kak ├── grepmenu.asciidoc ├── grepmenu.kak ├── hatch_terminal.asciidoc ├── hatch_terminal.kak ├── idsession.asciidoc ├── idsession.kak ├── lineindent.asciidoc ├── lineindent.kak ├── overstrike.asciidoc ├── overstrike.kak ├── readline.kak ├── searchmarks.asciidoc ├── searchmarks.kak ├── syntastic.asciidoc ├── syntastic.kak ├── tldr.asciidoc ├── tldr.kak ├── utils.kak ├── vcs.asciidoc ├── vcs.kak ├── versioncheck.asciidoc ├── versioncheck.kak └── widgets ├── git-branch.kak └── percent.kak /README.md: -------------------------------------------------------------------------------- 1 | # Archived 2 | 3 | This repository is not being maintained any more, and doesn't accept further 4 | user contributions. 5 | 6 | The highlighters have been moved to the 7 | [kakoune-extra-filetypes](https://github.com/kakoune-editor/kakoune-extra-filetypes) 8 | repository, which is bigger, maintained and accept user contributions. 9 | 10 | Commands remain here for the sake of posterity. Feel free to 11 | grave dig any files and make them work with more recent version of 12 | [kakoune]("https://github.com/mawww/kakoune"). 13 | 14 | # kakoune-extra 15 | 16 | This repository contains several scripts for the 17 | [kakoune]("https://github.com/mawww/kakoune") code editor that were not 18 | eligible to be merged with the core scripts that kakoune ships with, but 19 | still implement useful experimental features or allow highlighting of custom 20 | file formats. 21 | 22 | Scripts are all fairly well commented, but those whose use require more 23 | than a quick sentence in an inlined comment have their own `.asciidoc` 24 | documentation file (e.g. `fzf.asciidoc`). 25 | 26 | ## Versioning 27 | 28 | The `master` branch is compatible with the latest stable version of the 29 | editor, while the `dev` branch targets the latest `HEAD`, for users who 30 | use the Git version. 31 | 32 | ## How to use the scripts 33 | 34 | ### System wide availability 35 | 36 | Drop the scripts relevant to your interest in the `/usr/share/kak/rc` 37 | directory. They will be automatically loaded everytime a new `kak` process 38 | is started. 39 | 40 | ### Per user availability 41 | 42 | Copy the scripts you want to have autoloaded in the `$XDG_CONFIG_HOME/kak/rc` 43 | directory. They will be automatically loaded everytime a new `kak` process 44 | is started. 45 | 46 | ### Keeping scripts up to date 47 | 48 | If you want to be able to update the scripts easily, clone this repository 49 | and create symbolic links to the scripts you want to have loaded automatically 50 | in the system/user rc directory (c.f. previous points). 51 | 52 | ## Categories 53 | 54 | The scripts that are in the root directory of the repository are general 55 | purpose, while the following categories hold scripts with particular uses. 56 | 57 | ### Filetypes 58 | 59 | Support for filetypes that are not handled by the upstream version. 60 | 61 | ### Games 62 | 63 | Small games to pass time, with minimal dependencies. 64 | 65 | ### Widgets 66 | 67 | Placed in the `widgets` directory, those scripts store information in 68 | variables whose prefix is `modeline_`. As their name suggest, they are aimed 69 | at being used in the `modelinefmt` variable, and hold specific information. 70 | 71 | Example: the `percent` widget will update the `modeline_pos_percent` 72 | option with the relative position of the cursor in the buffer (using a 73 | percentage). You can use it by either inserting `%opt{modeline_pos_percent}%` 74 | variable in `modelinefmt`, or directly in a script or yours. 75 | 76 | ## Contributing 77 | 78 | Feel free to create a pull request if you want to share a useful script. 79 | 80 | ## License 81 | 82 | All the scripts in this repository are UNLICENSE'd. 83 | -------------------------------------------------------------------------------- /UNLICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /autodownload.asciidoc: -------------------------------------------------------------------------------- 1 | autodownload.kak 2 | ================ 3 | 4 | This script allows the editor to automatically download and display the file pointed to by URLs. 5 | 6 | Whenever a URL is passed as argument to `kak` or to the `buffer` command, a hook will be triggered and try to download the file and display it into 7 | a new buffer using a command line download utility (`wget` by default). 8 | The most common compression formats (zip, rar, gzip, bzip etc) are supported, granted that a single file is pointed to by the URL 9 | (i.e. compressed archives are not supported). 10 | 11 | Additionally, a buffer showing the progress of the download is created and will remain visible until the file has finished being downloaded. 12 | 13 | Variables 14 | --------- 15 | 16 | autodownload_keep_log 17 | ~~~~~~~~~~~~~~~~~~~~~ 18 | 19 | Boolean variable that allows the buffer that shows the output of the download command to be removed once the download has completed. 20 | 21 | autodownload_format 22 | ~~~~~~~~~~~~~~~~~~~ 23 | 24 | This string variable contains a template of the command to use to download URLs passed as buffer names. Several variables in the markup 25 | format (`{var}`) wil be replaced by the following respective values: 26 | 27 | * `{url}`: address pointing to the file to download, the buffer name 28 | * `{progress}`: path to the FIFO file to which the download progress should be written 29 | * `{output}`: path to the file that should be overwritten with the downloaded file 30 | 31 | There are three downloaders supported by the script by default: 32 | 33 | * `wget` 34 | * `aria2` 35 | * `curl` 36 | 37 | The default downloader is `wget`, and it can be changed by setting the `autodownload_format` option accordingly: 38 | 39 | ``` 40 | ## Set the default downloader to be wget 41 | set global autodownload_format %opt{autodownload_format_wget} 42 | 43 | ## or set the default downloader to be aria2 44 | set global autodownload_format %opt{autodownload_format_aria2} 45 | 46 | ## or set the default downloader to be curl 47 | set global autodownload_format %opt{autodownload_format_curl} 48 | ``` 49 | -------------------------------------------------------------------------------- /autodownload.kak: -------------------------------------------------------------------------------- 1 | ## 2 | ## autodownload.kak by lenormf 3 | ## Download a remote file when a URL is used as a buffer name 4 | ## 5 | 6 | declare-option -docstring "when enabled, the buffer containing the download logs will not be removed" \ 7 | bool autodownload_keep_log no 8 | 9 | ## Format of the download string that will be used to fetch the file 10 | ## Defaults to autodownload_format_wget 11 | declare-option -docstring %{formatted shell command used to download a file 12 | The following mustache variables are expanded: 13 | - {progress}: path to the named pipe to which the download progress is written 14 | - {output}: path to the output file 15 | - {url}: address of the file to download 16 | Defaults to the `autodownload_format_wget` format} \ 17 | str autodownload_format 18 | 19 | ## Pre-defined formats for different popular download tools 20 | declare-option -docstring "default formatted command for the `wget` utility" \ 21 | str autodownload_format_wget "wget -o '{progress}' -O '{output}' '{url}'" 22 | declare-option -docstring "default formatted command for the `aria2c` utility" \ 23 | str autodownload_format_aria2 "aria2c -o $(basename '{output}') -d $(dirname '{output}') '{url}' > '{progress}'" 24 | declare-option -docstring "default formatted command for the `curl` utility" \ 25 | str autodownload_format_curl "curl -o '{output}' '{url}' 2> '{progress}'" 26 | 27 | ## Set the default downloader to be wget 28 | set-option global autodownload_format %opt{autodownload_format_wget} 29 | 30 | hook global BufNewFile .* %{ evaluate-commands %sh{ 31 | { 32 | readonly netproto_url="${kak_bufname}" 33 | readonly netproto_ext="${netproto_url##*.}" 34 | readonly netproto_proto="${netproto_url%:*}" 35 | 36 | ## Check that the downloader used is reachable from this shell 37 | command -v "${kak_opt_autodownload_format%% *}" >/dev/null || exit 38 | 39 | ## Check that a url was passed to kakoune 40 | if ! printf %s "${netproto_url}" | grep -q '^[a-zA-Z][a-zA-Z]*://.' >/dev/null; then 41 | exit 42 | fi 43 | 44 | ## Create a temporary directory in which we will download the file 45 | readonly path_dir_tmp=$(mktemp -d "${TMPDIR:-/tmp}"/kak-autodownload.XXXXXXXX) 46 | if [ -z "${path_dir_tmp}" ]; then 47 | echo "echo -debug Unable to create temporary directory" | kak -p "${kak_session}" 48 | exit 2 49 | fi 50 | 51 | readonly netproto_buffer="${path_dir_tmp}/buffer" 52 | readonly netproto_fifo="${path_dir_tmp}/fifo" 53 | 54 | ## Create a named pipe that will print the download status 55 | if ! mkfifo "${netproto_fifo}"; then 56 | rm -rf "${path_dir_tmp}" 57 | echo "echo -debug Unable to create named pipe" | kak -p "${kak_session}" 58 | exit 2 59 | fi 60 | 61 | readonly buffer_basename="${netproto_url##*/}" 62 | 63 | ## Start downloading the file to a temporary directory 64 | { 65 | download_str=$(printf %s "${kak_opt_autodownload_format}" | \ 66 | sed -e "s/{url}/${netproto_url//\//\\\/}/g" \ 67 | -e "s/{progress}/${netproto_fifo//\//\\\/}/g" \ 68 | -e "s/{output}/${netproto_buffer//\//\\\/}/g") 69 | eval "${download_str}" 70 | } 2>&1 >/dev/null /dev/null; then 84 | case \"${netproto_ext}\" in 85 | zip|rar|lha|lzh|7z|alz|ace|arj|arc|gz|bz|bz2|Z|lzma|lzo|lz|xz|rz|lrz|7z|cpio) 86 | readonly path_tmp_file=\$(mktemp \"\${TMPDIR:-/tmp}\"/kak-autodownload.XXXXXXXX) 87 | atool -F \"${netproto_ext}\" -X \"\${path_tmp_file}\" \"${netproto_buffer}\" 2>/dev/null 88 | mv \"\${path_tmp_file}\" \"${netproto_buffer}\" 89 | ;; 90 | esac 91 | fi 92 | } 93 | edit '${buffer_basename}' 94 | exec '%d!cat \"${netproto_buffer}\"d' 95 | 96 | evaluate-commands %sh{ 97 | rm -rf '${path_dir_tmp}' 98 | if [ '${kak_opt_autodownload_keep_log}' != true ]; then 99 | printf %s ' 100 | delete-buffer! 'download:${netproto_url}' 101 | buffer '${buffer_basename}' 102 | ' 103 | fi 104 | } 105 | } 106 | } 107 | " | kak -p "${kak_session}" 108 | } 2>&1 >/dev/null []]: split the current view according to the terminal size 8 | Available layouts: 9 | - vstack: vertical stack with a left hand side main view 10 | - hstack: horizontal stack with a top main view 11 | - grid: array of equally sized tiles 12 | 13 | Available sizes: 14 | - large 15 | - medium 16 | - small 17 | 18 | The default layout is `vstack`, and the size is autodetected if unspecified 19 | } %{ evaluate-commands %sh{ 20 | readonly WIDTH_BASE=70 21 | readonly HEIGHT_BASE=20 22 | 23 | fatal() { 24 | printf 'echo -color Error %s' "$*" 25 | exit 1 26 | } 27 | 28 | layout="${1:-vstack}" 29 | case "${layout}" in 30 | vstack|hstack|grid);; 31 | *) fatal "Invalid layout name: ${layout}";; 32 | esac 33 | 34 | if [ $# -lt 2 ]; then 35 | if [ "${kak_window_width}" -ge $((WIDTH_BASE * 2)) ] && [ "${kak_window_height}" -ge $((HEIGHT_BASE * 3)) ]; then 36 | size=large 37 | elif [ "${kak_window_width}" -ge "${WIDTH_BASE}" ] && [ "${kak_window_height}" -ge $((HEIGHT_BASE)) ]; then 38 | size=medium 39 | else 40 | size=small 41 | fi 42 | else 43 | size="${2}" 44 | fi 45 | 46 | case "${size}" in 47 | small|medium|large);; 48 | *) fatal "Invalid size name: ${size}";; 49 | esac 50 | 51 | multiplexer="none" 52 | if [ -n "${DVTM_CMD_FIFO}" ]; then 53 | multiplexer="dvtm" 54 | elif [ -n "${TMUX}" ]; then 55 | multiplexer="tmux" 56 | fi 57 | 58 | case "${multiplexer}" in 59 | dvtm|tmux);; 60 | *) fatal "Unsupported multiplexer: ${multiplexer}" 61 | esac 62 | 63 | setup_multiplexer_dvtm() { 64 | layout="${1}" 65 | size="${2}" 66 | 67 | setup_size_large() { 68 | layout="${1}" 69 | 70 | case "${layout}" in 71 | vstack) 72 | echo " 73 | rename-client '%opt{toolsclient}' 74 | dvtm-new-window 'rename-client \"%opt{jumpclient}\"' 75 | dvtm-new-window 'rename-client \"%opt{docsclient}\"' 76 | dvtm-new-window 77 | " 78 | ;; 79 | hstack|grid) fatal "unimplemented";; 80 | esac 81 | } 82 | 83 | setup_size_medium() { 84 | layout="${1}" 85 | 86 | case "${layout}" in 87 | vstack) 88 | echo " 89 | rename-client \"%opt{jumpclient}\" 90 | dvtm-new-window 'rename-client \"%opt{docsclient}\"' 91 | dvtm-new-window 92 | " 93 | ;; 94 | hstack|grid) fatal "unimplemented";; 95 | esac 96 | } 97 | 98 | setup_size_small() { 99 | layout="${1}" 100 | 101 | case "${layout}" in 102 | vstack) 103 | echo " 104 | rename-client \"%opt{docsclient}\" 105 | dvtm-new-window 106 | " 107 | ;; 108 | hstack|grid) fatal "unimplemented";; 109 | esac 110 | } 111 | 112 | eval "setup_size_${size} '${layout}'" 113 | } 114 | 115 | setup_multiplexer_tmux() { 116 | layout="${1}" 117 | size="${2}" 118 | 119 | setup_size_large() { 120 | layout="${1}" 121 | 122 | case "${layout}" in 123 | vstack) 124 | printf ' 125 | tmux-new-horizontal rename-client "%%opt{docsclient}" 126 | tmux-new-vertical rename-client "%%opt{jumpclient}" 127 | tmux-new-vertical rename-client "%%opt{toolsclient}" 128 | try %%{ focus "%s" } 129 | nop %%sh{ 130 | env TMUX="%s" tmux select-layout main-vertical \; resize-pane -x %d 131 | } 132 | ' "${kak_client}" "${TMUX}" $((kak_window_width / 2)) 133 | ;; 134 | hstack) 135 | printf ' 136 | tmux-new-vertical rename-client "%%opt{docsclient}" 137 | tmux-new-horizontal rename-client "%%opt{jumpclient}" 138 | tmux-new-horizontal rename-client "%%opt{toolsclient}" 139 | try %%{ focus "%s" } 140 | nop %%sh{ 141 | env TMUX="%s" tmux select-layout main-horizontal \; resize-pane -y %d 142 | } 143 | ' "${kak_client}" "${TMUX}" $((kak_window_height / 2)) 144 | ;; 145 | grid) 146 | printf ' 147 | tmux-new-horizontal rename-client "%%opt{docsclient}" 148 | tmux-new-horizontal rename-client "%%opt{jumpclient}" 149 | tmux-new-horizontal rename-client "%%opt{toolsclient}" 150 | try %%{ focus "%s" } 151 | nop %%sh{ 152 | env TMUX="%s" tmux select-layout tiled 153 | } 154 | ' "${kak_client}" "${TMUX}" 155 | ;; 156 | esac 157 | } 158 | 159 | setup_size_medium() { 160 | layout="${1}" 161 | 162 | case "${layout}" in 163 | vstack) 164 | printf ' 165 | tmux-new-horizontal rename-client "%%opt{docsclient}" 166 | tmux-new-vertical rename-client "%%opt{jumpclient}" 167 | try %%{ focus "%s" } 168 | nop %%sh{ 169 | env TMUX="%s" tmux select-layout main-vertical \; resize-pane -x %d 170 | } 171 | ' "${kak_client}" "${TMUX}" $((kak_window_width / 2)) 172 | ;; 173 | hstack) 174 | printf ' 175 | tmux-new-vertical rename-client "%%opt{docsclient}" 176 | tmux-new-horizontal rename-client "%%opt{jumpclient}" 177 | try %%{ focus "%s" } 178 | nop %%sh{ 179 | env TMUX="%s" tmux select-layout main-horizontal \; resize-pane -y %d 180 | } 181 | ' "${kak_client}" "${TMUX}" $((kak_window_height / 2)) 182 | ;; 183 | grid) 184 | printf ' 185 | rename-client "%%opt{docsclient}" 186 | tmux-new-vertical rename-client "%%opt{jumpclient}" 187 | tmux-new-vertical 188 | try %%{ focus "%s" } 189 | nop %%sh{ 190 | env TMUX="%s" tmux select-layout tiled 191 | } 192 | ' "${kak_client}" "${TMUX}" 193 | ;; 194 | esac 195 | } 196 | 197 | setup_size_small() { 198 | layout="${1}" 199 | 200 | case "${layout}" in 201 | vstack) 202 | printf ' 203 | tmux-new-horizontal rename-client "%%opt{docsclient}" 204 | try %%{ focus "%s" } 205 | ' "${kak_client}" 206 | ;; 207 | hstack) 208 | printf ' 209 | tmux-new-vertical rename-client "%%opt{docsclient}" 210 | try %%{ focus "%s" } 211 | ' "${kak_client}" 212 | ;; 213 | grid) 214 | printf ' 215 | rename-client "%%opt{docsclient}" 216 | tmux-new-vertical 217 | try %%{ focus "%s" } 218 | nop %%sh{ 219 | env TMUX="%s" tmux select-layout tiled 220 | } 221 | ' "${kak_client}" "${TMUX}" 222 | ;; 223 | esac 224 | } 225 | 226 | eval "setup_size_${size} '${layout}'" 227 | } 228 | 229 | eval "setup_multiplexer_${multiplexer} '${layout}' '${size}'" 230 | } } 231 | -------------------------------------------------------------------------------- /cdmenu.asciidoc: -------------------------------------------------------------------------------- 1 | cdmenu.kak 2 | ========== 3 | 4 | Spawn a menu that allows jumping to a predetermined directory. 5 | 6 | Commands 7 | -------- 8 | 9 | cdmenu 10 | ~~~~~~ 11 | 12 | The `cdmenu` command, without any parameter passed to it, displays a menu 13 | showing all the available "indexes" that can be used to jump to a given 14 | directory. Indexes are simply the key that needs to be hit in order for 15 | the jump to be made (it's a simple custom user mode). 16 | 17 | A supported index can also be passed to the command directly, in which case 18 | no menu will be displayed. 19 | 20 | Options 21 | ------- 22 | 23 | cdmenu_paths 24 | ~~~~~~~~~~~~ 25 | 26 | This option is a string map whose keys are the indexes used to perform the 27 | jump, and containing values formatted as follows: 28 | 29 | ``` 30 | documentation string:path 31 | ``` 32 | 33 | Due to the way parsing is performed, *documentation string* may contain colon 34 | `:` characters. 35 | 36 | The *path* part can be a simple UNIX path, e.g. `/tmp`, but it can also be 37 | a bit of shell code that will be evaluated at the time of jump. Paths 38 | that need be evaluated dynamically have to be surrounded by backtick ``` 39 | characters. 40 | 41 | Example: 42 | 43 | ``` 44 | set-option global cdmenu_paths "g=git root:`git rev-parse --show-toplevel`" 45 | ``` 46 | 47 | Upon calling `:cdmenu g` (or hitting the `g` index if calling `:cdmenu` 48 | without arguments), the `git` command will be executed, returning the path 49 | that should be jumped to. 50 | 51 | Note that, due to an implementation restriction on shell scopes, in order for 52 | `$kak_*` environment variables to be expanded by `:cdmenu`, the variable's 53 | name should be hardcoded in the implementation of `:cdmenu`. The command's 54 | definition already uses that mechanism for `kak_client_env_HOME`, you can 55 | add your own expansions after it. 56 | -------------------------------------------------------------------------------- /cdmenu.kak: -------------------------------------------------------------------------------- 1 | ## 2 | ## cdmenu.kak for kakoune-extra 3 | ## by lenormf 4 | ## 5 | 6 | declare-user-mode cdmenu 7 | 8 | declare-option str-to-str-map cdmenu_paths \ 9 | "/=/:/" \ 10 | "e=/etc:/etc" \ 11 | "g=git root:`git rev-parse --show-toplevel`" \ 12 | "h=client $HOME:`printenv kak_client_env_HOME`" \ 13 | "H=server $HOME:`printenv HOME`" \ 14 | "p=client pwd:`printenv kak_client_env_PWD`" \ 15 | "P=server pwd:`printenv PWD`" \ 16 | "t=/tmp:/tmp" 17 | 18 | define-command -docstring %{ 19 | cdmenu []: quickly jump to a pre-defined path 20 | 21 | Without the argument, a menu listing all available indexes is displayed that allows the user to pick a path interactively. 22 | 23 | An index can also be passed directly to the function. 24 | } cdmenu -params ..1 %{ evaluate-commands %sh{ 25 | : # kak_client_env_HOME, kak_client_env_PWD 26 | 27 | _do() { 28 | action="$1"; shift 29 | args="$*" 30 | 31 | eval set -- "${kak_opt_cdmenu_paths}" 32 | 33 | for i in "$@"; do 34 | key="${i%%=*}" 35 | 36 | case "${action}" in 37 | get) 38 | if [ "${args}" != "${key}" ]; then 39 | continue 40 | fi 41 | 42 | path="${i#*:}" 43 | 44 | if printf %s "${path}" | grep -q '^`.*`$'; then 45 | path="${path#\`}"; path="${path%\`}" 46 | path=$(eval "${path}") 47 | fi 48 | 49 | printf %s\\n "${path}";; 50 | map) 51 | doc=$(printf "${i}" | sed 's/^[^=]*=//; s/:[^:]*$//; s/~/~~/g') 52 | printf 'map -docstring %%~%s~ global cdmenu %s %%{: cdmenu %s}\n' \ 53 | "${doc}" "${key}" "${key}";; 54 | esac 55 | done 56 | } 57 | 58 | get_path_index() { 59 | _do "get" "$1" 60 | } 61 | 62 | map_indexes() { 63 | _do "map" 64 | } 65 | 66 | if [ $# -eq 1 ]; then 67 | path=$(get_path_index "$1") 68 | 69 | if [ -z "${path}" ]; then 70 | printf 'echo -markup {Error}Invalid index: %s' "${1}" 71 | exit 1 72 | fi 73 | 74 | printf 'cd %%~%s~\n' "$(printf %s "${path}" | sed s/~/~~/g)" 75 | printf 'echo -markup {Information}Path changed to: %s\n' "${path}" 76 | else 77 | map_indexes 78 | echo enter-user-mode cdmenu 79 | fi 80 | } } 81 | -------------------------------------------------------------------------------- /comnotes.kak: -------------------------------------------------------------------------------- 1 | ## 2 | ## comnotes.kak by lenormf 3 | ## Highlight TODO, FIXME, NOTE and XXX comments 4 | ## 5 | 6 | add-highlighter global/ regex \b(TODO|FIXME|XXX|NOTE)\b 0:default+rb 7 | -------------------------------------------------------------------------------- /dictcomplete.asciidoc: -------------------------------------------------------------------------------- 1 | dictcomplete.kak 2 | ================ 3 | 4 | This script enables completion using a dictionary in buffers that 5 | usually contain lots of plain text (e.g. `asciidoc`). After a certain 6 | minimal amount of alpha-numerical letters has been typed (c.f. the 7 | `dict_min_chars` variable below), the completion will kick in a try to 8 | propose several candidates fetched using the system's `aspell` utility. 9 | 10 | A completion menu will pop up under the current word assuming the 11 | conditions for the completion to be triggered were fulfilled (and no 12 | candidate is available from the builtin engine), listing all 13 | possibilities with the `value` face. 14 | 15 | Variables 16 | --------- 17 | 18 | dict_min_chars 19 | ~~~~~~~~~~~~~~ 20 | 21 | Integer variable that controls the minimum amount of characters that 22 | have to be typed in an alpha-numerical word to trigger the completion. 23 | 24 | This value is inclusive and defaults to `3`. 25 | 26 | dict_lang 27 | ~~~~~~~~~ 28 | 29 | String that contains the language of the dictionary to use when fetching 30 | candidates, as per `aspell`'s standard (e.g. `en`, `en-US`). 31 | 32 | The default language is `en`. 33 | 34 | dict_size 35 | ~~~~~~~~~ 36 | 37 | Integer variable that holds the size of the dictionary to be queried, as 38 | per `aspell`'s definition. A generic implementation of this tool usually 39 | defines the following values: 40 | 41 | * `10`: tiny 42 | * `20`: really small 43 | * `30`: small 44 | * `40`: med-small 45 | * `50`: med 46 | * `60`: med-large 47 | * `70`: large 48 | * `80`: huge 49 | * `90`: insane 50 | 51 | The default value is `30` (small). 52 | -------------------------------------------------------------------------------- /dictcomplete.kak: -------------------------------------------------------------------------------- 1 | ## 2 | ## dictcomplete.kak by lenormf 3 | ## Dictionary completion based on `aspell` in text-based buffers 4 | ## 5 | 6 | declare-option -docstring "minimum amount of characters in a word necessary to trigger completion" int dict_min_chars 3 7 | declare-option -docstring "language identifier passed to `aspell` when loading a dictionary" str dict_lang "en" 8 | declare-option -docstring %{ 9 | size of the dictionary to load, as per `aspell` conventions: 10 | - 10: tiny 11 | - 20: really small 12 | - 30: small 13 | - 40: med-small 14 | - 50: med 15 | - 60: med-large 16 | - 70: large 17 | - 80: huge 18 | - 90: insane 19 | } \ 20 | int dict_size 30 21 | 22 | declare-option -hidden completions dict_completions 23 | 24 | define-command -hidden -params 1 dict-complete %{ evaluate-commands %sh{ 25 | { 26 | candidates=$( 27 | printf %s "${1}" | aspell -a \ 28 | -l "${kak_opt_dict_lang:-en}" \ 29 | --size "${kak_opt_dict_size:-30}" \ 30 | | awk -F ", " \ 31 | -v y="${kak_cursor_line}" \ 32 | -v x="${kak_cursor_column}" \ 33 | -v ts="${kak_timestamp}" ' 34 | BEGIN { 35 | prefix = y "." x "@" ts 36 | candidates = "" 37 | } 38 | END { 39 | if (length(candidates)) 40 | print prefix candidates 41 | } 42 | /^&/ { 43 | sub(/^&[^:]+: /, "", $0) 44 | 45 | for (i = 1; i <= NF; i++) { 46 | gsub(/\|/, "\\|", $i) 47 | gsub("~", "~~", $i) 48 | candidates = candidates " %~" $i "||{value}" $i "~" 49 | } 50 | } 51 | ') 52 | 53 | if [ -n "${candidates}" ]; then 54 | printf 'set %%{buffer=%s} dict_completions %s' "${kak_buffile}" "${candidates}" | kak -p "${kak_session}" 55 | fi 56 | } >/dev/null 2>&1 "[^\n]{%opt{dict_min_chars},}" 67 | dict-complete %val{selection} 68 | } 69 | } catch %{ 70 | set-option buffer dict_completions 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /dvtm.kak: -------------------------------------------------------------------------------- 1 | ## 2 | ## dvtm.kak by lenormf 3 | ## Support for client creation/tagging/focusing from a kakoune client 4 | ## 5 | 6 | # http://www.brain-dump.org/projects/dvtm/ 7 | # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 8 | 9 | hook global KakBegin .* %{ 10 | evaluate-commands %sh{ 11 | if [ -n "${DVTM}" ]; then 12 | echo " 13 | alias global new dvtm-new-window 14 | alias global focus dvtm-focus 15 | " 16 | fi 17 | } 18 | } 19 | 20 | define-command -params .. -command-completion -docstring "Create a new window" \ 21 | dvtm-new-window %{ evaluate-commands %sh{ 22 | params="" 23 | if [ $# -gt 0 ]; then 24 | ## `dvtm` requires those simple quotes to be escaped even within double quotes 25 | params="-e \\'$@\\'" 26 | fi 27 | 28 | ## The FIFO command pipe has to be created using the `-c` flag 29 | if [ -p "${DVTM_CMD_FIFO}" ]; then 30 | printf %s\\n "create \"kak -c ${kak_session} ${params}\"" > "${DVTM_CMD_FIFO}" 31 | else 32 | printf %s\\n 'echo -color Error No command socket available' 33 | fi 34 | } } 35 | 36 | define-command -params 0..1 -client-completion -docstring %{dvtm-focus [] focus a client 37 | If no client is passed, then the current client is used} \ 38 | dvtm-focus %{ evaluate-commands %sh{ 39 | if [ $# -eq 1 ]; then 40 | printf %s\\n "eval -client '$1' focus" 41 | elif [ -p "${DVTM_CMD_FIFO}" ]; then 42 | printf %s\\n "focus ${kak_client_env_DVTM_WINDOW_ID}" > "${DVTM_CMD_FIFO}" 43 | else 44 | printf %s\\n "echo -color Error No command socket available" 45 | fi 46 | } } 47 | 48 | define-command -params 1.. -docstring %{dvtm-cmd : interact with dvtm using the dvtm-cmd utility 49 | The command argument is a command supported by dvtm-cmd 50 | The tags arguments is a list of one or more tags to assign to the given client} \ 51 | dvtm-cmd %{ evaluate-commands %sh{ 52 | if [ -p "${DVTM_CMD_FIFO}" ]; then 53 | readonly command="$1"; shift 54 | readonly output=$(dvtm-cmd "${command}" "$@" 2>&1) 55 | 56 | if [ -n "${output}" ]; then 57 | printf %s\\n "echo -color Error %{ ${output} }" 58 | fi 59 | else 60 | printf %s\\n "echo -color Error No command socket available" 61 | fi 62 | } } 63 | -------------------------------------------------------------------------------- /filetype/bitbake.kak: -------------------------------------------------------------------------------- 1 | ## 2 | ## bitbake.kak by lenormf 3 | ## 4 | 5 | # http://www.yoctoproject.org/docs/1.8/bitbake-user-manual/bitbake-user-manual.html 6 | # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 7 | 8 | # Detection 9 | # ‾‾‾‾‾‾‾‾‾ 10 | 11 | hook global BufCreate .+\.bb(class|append)? %{ 12 | set-option buffer filetype bitbake 13 | } 14 | 15 | # Highlighters 16 | # ‾‾‾‾‾‾‾‾‾‾‾‾ 17 | 18 | add-highlighter shared/bitbake regions 19 | add-highlighter shared/bitbake/code default-region group 20 | add-highlighter shared/bitbake/double_string region %{(?' regions 21 | add-highlighter shared/clearsilver/inline_cs/code default-region group 22 | 23 | add-highlighter shared/clearsilver/code/ ref html 24 | 25 | add-highlighter shared/clearsilver/inline_cs/string_double region '"' (?)' 0:magenta 29 | add-highlighter shared/clearsilver/inline_cs/code/ regex \b[+-]?(0x\w+|#?\d+)\b 0:value 30 | add-highlighter shared/clearsilver/inline_cs/code/ regex \b(subcount|name|first|last|abs|max|min|string.slice|string.find|string.length|_)\( 1:keyword 31 | add-highlighter shared/clearsilver/inline_cs/code/ regex \b(var|evar|lvar|include|linclude|set|name|if|else|elif|alt|each|loop|with|def|call): 1:attribute 32 | add-highlighter shared/clearsilver/inline_cs/code/ regex /if\b 0:attribute 33 | 34 | # Initialization 35 | # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 36 | 37 | hook global WinSetOption filetype=clearsilver %{ 38 | add-highlighter window/clearsilver ref clearsilver 39 | } 40 | hook global WinSetOption filetype=(?!clearsilver).* %{ 41 | remove-highlighter window/clearsilver 42 | } 43 | -------------------------------------------------------------------------------- /filetype/django-template.kak: -------------------------------------------------------------------------------- 1 | ## 2 | ## django-template.kak by lenormf 3 | ## 4 | 5 | # https://docs.djangoproject.com/en/dev/ref/templates/language/ 6 | # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 7 | 8 | # Detection 9 | # ‾‾‾‾‾‾‾‾‾ 10 | 11 | hook global BufCreate .+\.html %[ 12 | try %[ 13 | execute-keys \%s \{\%|\{\{ 14 | set-option buffer filetype django-template 15 | ] 16 | ] 17 | 18 | # Highlighters 19 | # ‾‾‾‾‾‾‾‾‾‾‾‾ 20 | 21 | add-highlighter shared/django-template regions 22 | add-highlighter shared/django-template/code default-region group 23 | add-highlighter shared/django-template/scope region '\{%' '%\}' group 24 | add-highlighter shared/django-template/expansion region '\{\{' '\}\}' group 25 | add-highlighter shared/django-template/comment region '\{#' '#\}' fill comment 26 | 27 | add-highlighter shared/django-template/code/ ref html 28 | add-highlighter shared/django-template/scope/ ref python 29 | add-highlighter shared/django-template/expansion/ ref python 30 | add-highlighter shared/django-template/scope/ regex \A\{%|%\}\z 0:meta 31 | add-highlighter shared/django-template/expansion/ regex \A\{\{|\}\}\z 0:meta 32 | add-highlighter shared/django-template/scope/ regex \A\{%\s+((end)?(autoescape|block|comment|csrf_token|cycle|debug|empty|extends|filter|firstof|for|if|ifequal|ifnotequal|ifchanged|include|load|lorem|now|regroup|resetcycle|spaceless|templatetag|url|verbatim|widthratio|with))\b 1:keyword 33 | add-highlighter shared/django-template/expansion/ regex \|(add|addslashes|capfirst|center|cut|date|default|default_if_none|dictsort|dictsortreversed|divisibleby|escape|escapejs|filesizeformat|first|floatformat|force_escape|get_digit|iriencode|join|last|length|length_is|linebreaks|linebreaksbr|linenumbers|ljust|lower|make_list|phone2numeric|pluralize|pprint|random|rjust|safe|safeseq|slice|slugify|stringformat|striptags|time|timesince|timeuntil|title|truncatechars|truncatechars_html|truncatewords|truncatewords_html|unordered_list|upper|urlencode|urlize|urlizetrunc|wordcount|wordwrap|yesno)\b 1:builtin 34 | 35 | # Initialization 36 | # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 37 | 38 | hook global WinSetOption filetype=django-template %{ 39 | add-highlighter window/django-template ref django-template 40 | } 41 | hook global WinSetOption filetype=(?!django-template).* %{ 42 | remove-highlighter window/django-template 43 | } 44 | -------------------------------------------------------------------------------- /filetype/git.kak: -------------------------------------------------------------------------------- 1 | ## 2 | ## git.kak by lenormf 3 | ## 4 | 5 | # http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html 6 | # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 7 | 8 | # Faces that highlight text that overflows the following limits: 9 | # - title: 50 characters 10 | # - body: 72 characters 11 | set-face global GitOverflowTitle yellow 12 | set-face global GitOverflowBody yellow 13 | 14 | hook -group git-commit-highlight global WinSetOption filetype=git-(commit|rebase) %{ 15 | add-highlighter window/git-commit-highlight/ regex "^\h*[^#\s][^\n]{71}([^\n]+)" 1:GitOverflowBody 16 | add-highlighter window/git-commit-highlight/ regex "\A[\s\n]*[^#\s][^\n]{49}([^\n]+)" 1:GitOverflowTitle 17 | } 18 | -------------------------------------------------------------------------------- /filetype/mutt.kak: -------------------------------------------------------------------------------- 1 | ## 2 | ## mutt.kak by lenormf 3 | ## Highlight temporary mail files at the default location 4 | ## 5 | 6 | # http://www.mutt.org/ 7 | # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 8 | 9 | hook global BufCreate /tmp/mutt-.* %{ 10 | set-option buffer filetype mail 11 | } 12 | 13 | -------------------------------------------------------------------------------- /filetype/openelec.kak: -------------------------------------------------------------------------------- 1 | ## 2 | ## openelec.kak by lenormf 3 | ## Highlight package files in an OpenElec file tree 4 | ## 5 | 6 | hook global BufCreate .*/?package\.mk %{ evaluate-commands %sh{ 7 | path=$(readlink -f "${kak_buffile}") 8 | if printf %s "${path}" | grep -q "/packages/"; then 9 | echo 'set buffer filetype sh' 10 | fi 11 | } } 12 | -------------------------------------------------------------------------------- /filetype/pkgbuild.kak: -------------------------------------------------------------------------------- 1 | ## 2 | ## pkgbuild.kak by lenormf 3 | ## Highlight Archlinux package files 4 | ## 5 | 6 | hook global BufCreate .*/?PKGBUILD %{ 7 | set-option buffer filetype sh 8 | } 9 | -------------------------------------------------------------------------------- /filetype/riotjs.kak: -------------------------------------------------------------------------------- 1 | ## 2 | ## riotjs.kak by lenormf 3 | ## 4 | 5 | # http://www.riotjs.com/ 6 | # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 7 | 8 | # Detection 9 | # ‾‾‾‾‾‾‾‾‾ 10 | 11 | hook global BufCreate .+\.tag %{ 12 | set-option buffer filetype riotjs 13 | } 14 | 15 | # Highlighters 16 | # ‾‾‾‾‾‾‾‾‾‾‾‾ 17 | 18 | add-highlighter shared/riotjs regions 19 | add-highlighter shared/riotjs/partial region '^\s+<' '$' ref html 20 | add-highlighter shared/riotjs/model region '^\s+[^<]' '$' ref javascript 21 | 22 | # Initialization 23 | # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 24 | 25 | hook global WinSetOption filetype=riotjs %{ 26 | add-highlighter window/riotjs ref riotjs 27 | } 28 | 29 | hook global WinSetOption filetype=(?!riotjs).* %{ 30 | remove-highlighter window/riotjs 31 | } 32 | -------------------------------------------------------------------------------- /filetype/sdl.kak: -------------------------------------------------------------------------------- 1 | ## 2 | ## sdl.kak by lenormf 3 | ## 4 | 5 | # https://github.com/Abscissa/SDLang-D/wiki/Language-Guide 6 | # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 7 | 8 | # Detection 9 | # ‾‾‾‾‾‾‾‾‾ 10 | 11 | hook global BufCreate .*/?.+\.sdl %{ 12 | set-option buffer filetype sdl 13 | } 14 | 15 | # Highlighters 16 | # ‾‾‾‾‾‾‾‾‾‾‾‾ 17 | 18 | # Regions 19 | 20 | add-highlighter shared/sdl regions 21 | add-highlighter shared/sdl/code default-region group 22 | add-highlighter shared/sdl/double_string region %{(?[_\w][\w_$.-]*):)?(?[_\w][\w_$.-]*) namespace:attribute identifier:keyword 29 | add-highlighter shared/sdl/code/ regex ((?[_\w][\w_$.-]*):)?(?[_\w][\w_$.-]*)(?=) namespace:attribute identifier:attribute equal:operator 30 | add-highlighter shared/sdl/code/ regex (\d*\.?\d+)([lL]|[fF]|[bB]?[dD])? 0:value 31 | add-highlighter shared/sdl/code/ regex \b(true|false|null)\b 0:value 32 | add-highlighter shared/sdl/code/ regex \b\d{4}/(0\d|1[0-2])/([0-2]\d|3[0-1])(\h([0-1]\d|2[0-3]):[0-5]\d(:([0-5]\d))?(\.\d{3})?(-[A-Z]+(\+([0-1]\d|2[0-3])(:[0-5]\d)?)?)?)?\b 0:value 33 | add-highlighter shared/sdl/code/ regex \b(\d+d:)?([0-1]\d|2[0-3]):([0-5]\d):[0-5]\d(\.\d{3})?\b 0:value 34 | add-highlighter shared/sdl/code/ regex \[[^\]]+\] 0:value 35 | 36 | # Initialization 37 | # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 38 | 39 | hook global WinSetOption filetype=sdl %{ 40 | add-highlighter window/sdl ref sdl 41 | } 42 | hook global WinSetOption filetype=(?!sdl).* %{ 43 | remove-highlighter window/sdl 44 | } 45 | -------------------------------------------------------------------------------- /fzf.asciidoc: -------------------------------------------------------------------------------- 1 | fzf.kak 2 | ======= 3 | 4 | :fzf-website: https://github.com/junegunn/fzf 5 | 6 | {fzf-website} 7 | 8 | `fzf` is a command line fuzzy finder that allows fast search and selection of strings within a big collection. It's a good replacement for the builtin 9 | file completion menu in kakoune, particularly when opening files several directory levels afar from the current working directory, or looking for a file 10 | whose location is unknown. 11 | 12 | The script requires kakoune to have been started within a `tmux` session, as `fzf` will be run into 13 | a seperate pane whenever needed. The `utils.kak` also have to have been loaded by kakoune in order for the `fzf-cached` command to work. 14 | 15 | Variables 16 | --------- 17 | 18 | fzf_filesearch_cmd 19 | ~~~~~~~~~~~~~~~~~~ 20 | 21 | Command to use to get a list to select from. Defaults to an `ag` command (the `%s` string in the variable's value will be replaced with the path to search), 22 | but other classical tools can be used as well, e.g. `find '%s' -type f`. 23 | 24 | fzf_options 25 | ~~~~~~~~~~~ 26 | 27 | Options that will be passed to `fzf-tmux` after the candidates list has been generated/read. Defaults to `-m` to allow multiple selections. 28 | 29 | fzf_cache_filename 30 | ~~~~~~~~~~~~~~~~~~ 31 | 32 | Name of the file that contains the cached candidates that `fzf` will allow the user to select from. 33 | 34 | fzf_cache_path 35 | ~~~~~~~~~~~~~~ 36 | 37 | This variable is hidden, and contains the path to the latest cache file (whose base name is stored in the `fzf_cache_filename` variable) that was used by 38 | `fzf` to generate the list of candidates. 39 | 40 | Commands 41 | -------- 42 | 43 | fzf 44 | ~~~ 45 | 46 | This function takes a list of directory paths as argument (if no argument is passed, then the current working directory of the buffer is used instead), 47 | spawns a `tmux` pane containing the candidates list handled by `fzf`, and then opens the selected paths as kakoune buffers. The list of candidates is 48 | generated by running the content of the `fzf_filesearch_cmd` variable, whose output will be passed unfiltered to `fzf-tmux` (multiple selections are 49 | enabled within the `fzf` selection menu). 50 | 51 | If no path is selected (e.g. hitting `^D` in the `fzf` selection menu), then no buffer is opened. 52 | 53 | Example: opening a `main.c` file located somewhere in the remote `~/work/test` directory 54 | 55 | -------------------------------------------------------------------- 56 | :fzf ~/work/test 57 | type 'main.c$' 58 | hit return on the path to select, moving up/down with the arrow keys 59 | -------------------------------------------------------------------- 60 | 61 | fzf-cached 62 | ~~~~~~~~~~ 63 | 64 | This function works similarly to the `fzf` function, except that it will use the paths passed as arguments as starting points, and then look upward for a 65 | file whose name is stored in the `fzf_cache_filename` variable. Once that file has been found, the function feeds its content to `fzf-tmux` to allow the 66 | user to select entries from the list. 67 | 68 | This function avoids spawning a process (e.g. `ag` or `find`) that will make a list of all the files within the directories passed as argument, which can 69 | hurt performance very harshly when coding over a network filesystem, or in a directory containing a big amount of subdirectories. 70 | 71 | Example: caching files for selection, and using the cache file to open a `main.c` file 72 | 73 | -------------------------------------------------------------------- 74 | ag -g '' > ~/work/test/paths 75 | cd ~/work/test/some/sub/dir 76 | :fzf-cached 77 | type 'main.c$' 78 | hit return on the path to select, moving up/down with the arrow keys 79 | -------------------------------------------------------------------- 80 | -------------------------------------------------------------------------------- /fzf.kak: -------------------------------------------------------------------------------- 1 | ## 2 | ## fzf.kak by lenormf 3 | ## Support function for the `fzf` utility 4 | ## https://github.com/junegunn/fzf 5 | ## 6 | 7 | # `fzf-cached` requires `find-parent-file` in `utils.kak` 8 | 9 | declare-option -docstring %{formatted shell command whose output is passed to `fzf` to generate a list of tokens 10 | Each occurence of the `%s` string will be replaced with the directory to list} \ 11 | str fzf_filesearch_cmd 'ag -g "" "%s"' 12 | declare-option -docstring "options passed to `fzf` when listing a directory" \ 13 | str fzf_options '-m' 14 | declare-option -docstring "name of the cache filename looked for by the `fzf-cached` command" \ 15 | str fzf_cache_filename 'paths' 16 | 17 | declare-option -hidden str fzf_cache_path 18 | 19 | define-command -params .. -file-completion \ 20 | -docstring %{fzf []: open a file in the given directories 21 | If no directories are given then the directory in which the current buffer was saved is used} \ 22 | fzf %{ evaluate-commands %sh{ 23 | if [ -z "${TMUX}" ]; then 24 | printf 'echo -color Error This function must be run in a `tmux` session\n' 25 | exit 26 | fi 27 | 28 | if [ $# -ge 1 ]; then 29 | cwd=$(printf %s "$@" | sed 's/\//\\\//g') 30 | else 31 | cwd=$(dirname "${kak_buffile}" | sed 's/\//\\\//g') 32 | fi 33 | filesearch_cmd=$(printf %s "${kak_opt_fzf_filesearch_cmd}" | sed "s/%s/${cwd}/g") 34 | eval "${filesearch_cmd}" | eval "fzf-tmux ${kak_opt_fzf_options}" | while read path; do 35 | printf "eval -try-client '%s' edit '%s'" "${kak_client}" "${path}" \ 36 | | kak -p "${kak_session}" 37 | done 38 | } } 39 | 40 | define-command -params .. -file-completion \ 41 | -docstring %{fzf-cached [] open a file in the given cached directories 42 | If no directories are given then the directory in which the current buffer was saved is used} \ 43 | fzf-cached %{ 44 | evaluate-commands %sh{ 45 | if [ -z "${TMUX}" ]; then 46 | printf 'echo -color Error This function must be run in a `tmux` session\n' 47 | exit 48 | fi 49 | 50 | if [ $# -lt 0 ]; then 51 | printf %s\\n "find-parent-file %opt{fzf_cache_filename} global:fzf_cache_path 0 $@" 52 | else 53 | basedir=$(dirname "${kak_buffile}") 54 | printf %s\\n "find-parent-file %opt{fzf_cache_filename} global:fzf_cache_path 0 ${basedir}" 55 | fi 56 | } 57 | 58 | evaluate-commands %sh{ 59 | if [ -z "${kak_opt_fzf_cache_path}" ]; then 60 | exit 61 | fi 62 | paths_dir=$(dirname "${kak_opt_fzf_cache_path}") 63 | eval "fzf-tmux ${kak_opt_fzf_options}" < "${kak_opt_fzf_cache_path}" | while read path; do 64 | printf "eval -try-client '%s' edit '%s'" "${kak_client}" "${paths_dir}/${path}" \ 65 | | kak -p "${kak_session}" 66 | done 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /fzy.asciidoc: -------------------------------------------------------------------------------- 1 | fzy.kak 2 | ======= 3 | 4 | :fzy-website: https://github.com/jhawthorn/fzy 5 | 6 | {fzy-website} 7 | 8 | `fzy` is a command line fuzzy finder that allows fast search and selection of strings within a big collection. It's a good replacement for the builtin 9 | file completion menu in kakoune, particularly when opening files several directory levels afar from the current working directory, or looking for a file 10 | whose location is unknown. 11 | 12 | The script requires kakoune to have been started within a `tmux` or a `dvtm` session, as `fzy` will be run into 13 | a seperate pane/window whenever needed. The `utils.kak` also have to have been loaded by kakoune in order for the `fzy-cached` command to work. 14 | 15 | Variables 16 | --------- 17 | 18 | fzf_filesearch_cmd 19 | ~~~~~~~~~~~~~~~~~~ 20 | 21 | Command to use to get a list to select from. Defaults to an `ag` command (the `%s` string in the variable's value will be replaced with the path to search), 22 | but other classical tools can be used as well, e.g. `find '%s' -type f`. 23 | 24 | fzf_options 25 | ~~~~~~~~~~~ 26 | 27 | Options that will be passed to `fzy-tmux` or `fzy-dvtm` after the candidates list has been generated/read. Defaults to `-l $(tput lines)` to allow 28 | the entire window/pane newly created to be used, as opposed to the 10 lines that `fzy` uses by default. 29 | 30 | fzf_cache_filename 31 | ~~~~~~~~~~~~~~~~~~ 32 | 33 | Name of the file that contains the cached candidates that `fzy` will allow the user to select from. 34 | 35 | fzf_cache_path 36 | ~~~~~~~~~~~~~~ 37 | 38 | This variable is hidden, and contains the path to the latest cache file (whose base name is stored in the `fzf_cache_filename` variable) that was used by 39 | `fzy` to generate the list of candidates. 40 | 41 | Commands 42 | -------- 43 | 44 | fzy 45 | ~~~ 46 | 47 | This function takes a list of directory paths as argument (if no argument is passed, then the current working directory of the buffer is used instead), 48 | spawns a `tmux` pane or `dvtm` window containing the candidates list handled by `fzy`, and then opens the selected paths as kakoune buffers. The list of candidates is 49 | generated by running the content of the `fzf_filesearch_cmd` variable, whose output will be passed unfiltered to `fzy-tmux`/`fzy-dvtm`. 50 | 51 | If no path is selected (e.g. hitting `^D` in the `fzy` selection menu), then no buffer is opened. 52 | 53 | Example: opening a `main.c` file located somewhere in the remote `~/work/test` directory 54 | 55 | -------------------------------------------------------------------- 56 | :fzy ~/work/test 57 | type 'main.c$' 58 | hit return on the path to select, moving up/down with the arrow keys 59 | -------------------------------------------------------------------- 60 | 61 | fzy-cached 62 | ~~~~~~~~~~ 63 | 64 | This function works similarly to the `fzy` function, except that it will use the paths passed as arguments as starting points, and then look upward for a 65 | file whose name is stored in the `fzf_cache_filename` variable. Once that file has been found, the function feeds its content to `fzy-tmux`/`fzy-dvtm` to allow the 66 | user to select entries from the list. 67 | 68 | This function avoids spawning a process (e.g. `ag` or `find`) that will make a list of all the files within the directories passed as argument, which can 69 | hurt performance very harshly when coding over a network filesystem, or in a directory containing a big amount of subdirectories. 70 | 71 | Example: caching files for selection, and using the cache file to open a `main.c` file 72 | 73 | -------------------------------------------------------------------- 74 | ag -g '' > ~/work/test/paths 75 | cd ~/work/test/some/sub/dir 76 | :fzy-cached 77 | type 'main.c$' 78 | hit return on the path to select, moving up/down with the arrow keys 79 | -------------------------------------------------------------------- 80 | -------------------------------------------------------------------------------- /fzy.kak: -------------------------------------------------------------------------------- 1 | ## 2 | ## fzy.kak by lenormf 3 | ## Support function for the `fzy` utility 4 | ## https://github.com/jhawthorn/fzy 5 | ## 6 | 7 | # `fzy-cached` requires `find-parent-file` in `utils.kak` 8 | 9 | declare-option -docstring %{formatted shell command whose output is passed to `fzy` to generate a list of tokens 10 | Each occurence of the `%s` string will be replaced with the directory to list} \ 11 | str fzy_filesearch_cmd 'ag -g "" "%s"' 12 | declare-option -docstring "options passed to `fzy` when listing a directory" \ 13 | str fzy_options '-l $(tput lines)' 14 | declare-option -docstring "name of the cache filename looked for by the `fzy-cached` command" \ 15 | str fzy_cache_filename 'paths' 16 | 17 | declare-option -hidden str fzy_cache_path 18 | 19 | define-command -params .. -file-completion \ 20 | -docstring %{fzy []: open a file in the given directories 21 | If no directories are given then the directory in which the current buffer was saved is used} \ 22 | fzy %{ evaluate-commands %sh{ 23 | cmd_multiplexer="" 24 | if [ -n "${DVTM_CMD_FIFO}" ]; then 25 | cmd_multiplexer="fzy-dvtm" 26 | elif [ -n "${TMUX}" ]; then 27 | cmd_multiplexer="fzy-tmux" 28 | else 29 | printf 'echo -color Error This function must be run in a `dvtm` or `tmux` session\n' 30 | exit 1 31 | fi 32 | 33 | if [ $# -ge 1 ]; then 34 | cwd=$(printf %s "$*" | sed 's/\//\\\//g') 35 | else 36 | cwd=$(dirname "${kak_buffile}" | sed 's/\//\\\//g') 37 | fi 38 | filesearch_cmd=$(printf %s "${kak_opt_fzy_filesearch_cmd}" | sed "s/%s/${cwd}/g") 39 | eval "${filesearch_cmd}" | eval "'${cmd_multiplexer}' ${kak_opt_fzy_options}" | while read path; do 40 | printf "eval -try-client '%s' edit '%s'" "${kak_client}" "${path}" \ 41 | | kak -p "${kak_session}" 42 | done 43 | } } 44 | 45 | define-command -params .. -file-completion \ 46 | -docstring %{fzy-cached [] open a file in the given cached directories 47 | If no directories are given then the directory in which the current buffer was saved is used} \ 48 | fzy-cached %{ 49 | %sh{ 50 | if [ -z "${DVTM_CMD_FIFO}" ] && [ -z "${TMUX}" ]; then 51 | printf 'echo -color Error This function must be run in a `dvtm` or `tmux` session\n' 52 | exit 1 53 | fi 54 | 55 | if [ $# -lt 0 ]; then 56 | printf %s\\n "find-parent-file %opt{fzy_cache_filename} global:fzy_cache_path 0 $@" 57 | else 58 | basedir=$(dirname "${kak_buffile}") 59 | printf %s\\n "find-parent-file %opt{fzy_cache_filename} global:fzy_cache_path 0 ${basedir}" 60 | fi 61 | } 62 | 63 | %sh{ 64 | if [ -z "${kak_opt_fzy_cache_path}" ]; then 65 | exit 66 | fi 67 | cmd_multiplexer="" 68 | if [ -n "${DVTM_CMD_FIFO}" ]; then 69 | cmd_multiplexer="fzy-dvtm" 70 | elif [ -n "${TMUX}" ]; then 71 | cmd_multiplexer="fzy-tmux" 72 | fi 73 | 74 | paths_dir=$(dirname "${kak_opt_fzy_cache_path}") 75 | eval "'${cmd_multiplexer}' ${kak_opt_fzy_options}" < "${kak_opt_fzy_cache_path}" | while read path; do 76 | printf "eval -try-client '%s' edit '%s'" "${kak_client}" "${paths_dir}/${path}" \ 77 | | kak -p "${kak_session}" 78 | done 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /games/minesweeper.kak: -------------------------------------------------------------------------------- 1 | # kakoune implementation of the minesweeper game 2 | 3 | def -params 3 -docstring %{minesweeper : play a game of minesweeper in a grid of size x containing mines 4 | press to uncover a square 5 | press f to flag it} \ 6 | minesweeper %{ 7 | minesweeper_quit 8 | edit -scratch *minesweeper_solution* 9 | # create $1*$2 lines made of ' \n' 10 | exec %sh{ printf %d $(($1 * $2)) }ogkd 11 | # replace the first $3 with 'x\n' 12 | exec %arg{3} Crx 13 | # shuffle them, POSIX-compliant style (;_;) 14 | exec %{ %|awk 'BEGIN {srand(); OFMT="%.17f"} {print rand(), $0}' "$@"|sort -k1,1n|cut -d ' ' -f2-} 15 | # join them in a $1x$2 grid 16 | exec \%s(.\n){ %arg{2} }Kld 17 | # surround them by # 18 | exec '%i#a#xypxHr#LygkP' 19 | 20 | eval %{ 21 | # copy that layout to the play buffer 22 | exec -save-regs '' '%y' 23 | edit -scratch *minesweeper* 24 | # but remove all 'x' here 25 | exec -draft 'pd%sxr' 26 | exec jl 27 | } 28 | 29 | add-highlighter shared group minesweeper 30 | add-highlighter shared/minesweeper regex '\d' 0:black,green 31 | add-highlighter shared/minesweeper regex 'x' 0:black,red 32 | add-highlighter shared/minesweeper regex '!' 0:black,yellow 33 | map buffer normal ':minesweeper_check' 34 | map buffer normal f ':minesweeper_toggle_flag' 35 | } 36 | 37 | def -hidden minesweeper_quit %{ 38 | try %{ remove-highlighter shared/minesweeper } 39 | try %{ delete-buffer *minesweeper_solution* } 40 | try %{ delete-buffer *minesweeper* } 41 | } 42 | 43 | def -hidden minesweeper_toggle_flag %{ 44 | try %{ 45 | exec 'sr!' 46 | } catch %{ 47 | try %{ 48 | exec 's!r' 49 | } 50 | } 51 | } 52 | 53 | decl -hidden str minesweeper_save_position 54 | 55 | # this command is meant to be called only on a blank squre 56 | def -hidden minesweeper_uncover_current %{ 57 | set global minesweeper_save_position %val{selection_desc} 58 | # go to the solution buffer at the same position 59 | buffer *minesweeper_solution* 60 | select %opt{minesweeper_save_position} 61 | # after this block, register " will contain what we uncover 62 | try %{ 63 | exec x 64 | # we're on a mine 65 | reg '"' x 66 | } catch %{ 67 | # not on a mine 68 | # expand in a circle around the current position 69 | exec hkCCLL 70 | try %{ 71 | # select mines 72 | exec sx 73 | # count them 74 | reg '"' %reg{#} 75 | } catch %{ 76 | # no mines -> 0 77 | reg '"' 0 78 | } 79 | } 80 | # go back to the minesweeper buffer 81 | buffer *minesweeper* 82 | select %opt{minesweeper_save_position} 83 | # and replace the checked position with what we found 84 | exec R 85 | } 86 | 87 | def -hidden minesweeper_check_won %{ 88 | exec '%s[ !]' 89 | set global minesweeper_save_position %val{selections_desc} 90 | buffer *minesweeper_solution* 91 | select %opt{minesweeper_save_position} 92 | exec ' ' 93 | } 94 | 95 | def -hidden minesweeper_check_recursive %{ 96 | try %{ 97 | # find all safe squares 98 | exec '%s0' 99 | # that are surrounded by at least one covered square 100 | exec 'hkCCLLs ' 101 | # and uncover them independently 102 | eval -itersel minesweeper_uncover_current 103 | # recursively because we may have uncovered other 0 104 | minesweeper_check_recursive 105 | } 106 | } 107 | 108 | def -hidden minesweeper_check %{ 109 | try %{ 110 | # ensure we're trying to check a space 111 | exec '; ' 112 | eval minesweeper_uncover_current 113 | # check surroundings if we just uncovered a 0 114 | try %{ 115 | exec 0 116 | eval -draft minesweeper_check_recursive 117 | } 118 | # check winning/losing condition 119 | try %{ 120 | exec x 121 | info 'You lost, better luck next time.' 122 | } catch %{ 123 | try %{ 124 | eval -draft minesweeper_check_won 125 | } catch %{ 126 | info 'You won, congratulations!' 127 | } 128 | } 129 | } 130 | } 131 | 132 | -------------------------------------------------------------------------------- /games/sokoban.kak: -------------------------------------------------------------------------------- 1 | ## 2 | ## sokoban.kak by lenormf 3 | ## Opens a game of sokoban in a new buffer, using one of the 90 hardcoded levels 4 | ## 5 | 6 | # Selections description of all the holes on the map 7 | declare-option -hidden str _sokoban_holes 8 | 9 | # Colorize the levels 10 | add-highlighter shared/sokoban group 11 | add-highlighter shared/sokoban/ regex @ 0:string 12 | add-highlighter shared/sokoban/ regex '#' 0:comment 13 | add-highlighter shared/sokoban/ regex O 0:variable 14 | 15 | define-command -params 1 -docstring %{sokoban : play a game of sokoban on the level passed as parameter 16 | level is an integer between 1 and 90 included} \ 17 | sokoban %{ eval -save-regs '/"|^@m' %{ 18 | evaluate-commands %sh{ 19 | readonly id_level=$(($1)) 20 | 21 | ## FIXME: find a way to get this variable dynamically 22 | case ${id_level} in 23 | 0) printf %s "reg m '${kak_opt__sokoban_level_0}'";; 24 | 1) printf %s "reg m '${kak_opt__sokoban_level_1}'";; 25 | 2) printf %s "reg m '${kak_opt__sokoban_level_2}'";; 26 | 3) printf %s "reg m '${kak_opt__sokoban_level_3}'";; 27 | 4) printf %s "reg m '${kak_opt__sokoban_level_4}'";; 28 | 5) printf %s "reg m '${kak_opt__sokoban_level_5}'";; 29 | 6) printf %s "reg m '${kak_opt__sokoban_level_6}'";; 30 | 7) printf %s "reg m '${kak_opt__sokoban_level_7}'";; 31 | 8) printf %s "reg m '${kak_opt__sokoban_level_8}'";; 32 | 9) printf %s "reg m '${kak_opt__sokoban_level_9}'";; 33 | 10) printf %s "reg m '${kak_opt__sokoban_level_10}'";; 34 | 11) printf %s "reg m '${kak_opt__sokoban_level_11}'";; 35 | 12) printf %s "reg m '${kak_opt__sokoban_level_12}'";; 36 | 13) printf %s "reg m '${kak_opt__sokoban_level_13}'";; 37 | 14) printf %s "reg m '${kak_opt__sokoban_level_14}'";; 38 | 15) printf %s "reg m '${kak_opt__sokoban_level_15}'";; 39 | 16) printf %s "reg m '${kak_opt__sokoban_level_16}'";; 40 | 17) printf %s "reg m '${kak_opt__sokoban_level_17}'";; 41 | 18) printf %s "reg m '${kak_opt__sokoban_level_18}'";; 42 | 19) printf %s "reg m '${kak_opt__sokoban_level_19}'";; 43 | 20) printf %s "reg m '${kak_opt__sokoban_level_20}'";; 44 | 21) printf %s "reg m '${kak_opt__sokoban_level_21}'";; 45 | 22) printf %s "reg m '${kak_opt__sokoban_level_22}'";; 46 | 23) printf %s "reg m '${kak_opt__sokoban_level_23}'";; 47 | 24) printf %s "reg m '${kak_opt__sokoban_level_24}'";; 48 | 25) printf %s "reg m '${kak_opt__sokoban_level_25}'";; 49 | 26) printf %s "reg m '${kak_opt__sokoban_level_26}'";; 50 | 27) printf %s "reg m '${kak_opt__sokoban_level_27}'";; 51 | 28) printf %s "reg m '${kak_opt__sokoban_level_28}'";; 52 | 29) printf %s "reg m '${kak_opt__sokoban_level_29}'";; 53 | 30) printf %s "reg m '${kak_opt__sokoban_level_30}'";; 54 | 31) printf %s "reg m '${kak_opt__sokoban_level_31}'";; 55 | 32) printf %s "reg m '${kak_opt__sokoban_level_32}'";; 56 | 33) printf %s "reg m '${kak_opt__sokoban_level_33}'";; 57 | 34) printf %s "reg m '${kak_opt__sokoban_level_34}'";; 58 | 35) printf %s "reg m '${kak_opt__sokoban_level_35}'";; 59 | 36) printf %s "reg m '${kak_opt__sokoban_level_36}'";; 60 | 37) printf %s "reg m '${kak_opt__sokoban_level_37}'";; 61 | 38) printf %s "reg m '${kak_opt__sokoban_level_38}'";; 62 | 39) printf %s "reg m '${kak_opt__sokoban_level_39}'";; 63 | 40) printf %s "reg m '${kak_opt__sokoban_level_40}'";; 64 | 41) printf %s "reg m '${kak_opt__sokoban_level_41}'";; 65 | 42) printf %s "reg m '${kak_opt__sokoban_level_42}'";; 66 | 43) printf %s "reg m '${kak_opt__sokoban_level_43}'";; 67 | 44) printf %s "reg m '${kak_opt__sokoban_level_44}'";; 68 | 45) printf %s "reg m '${kak_opt__sokoban_level_45}'";; 69 | 46) printf %s "reg m '${kak_opt__sokoban_level_46}'";; 70 | 47) printf %s "reg m '${kak_opt__sokoban_level_47}'";; 71 | 48) printf %s "reg m '${kak_opt__sokoban_level_48}'";; 72 | 49) printf %s "reg m '${kak_opt__sokoban_level_49}'";; 73 | 50) printf %s "reg m '${kak_opt__sokoban_level_50}'";; 74 | 51) printf %s "reg m '${kak_opt__sokoban_level_51}'";; 75 | 52) printf %s "reg m '${kak_opt__sokoban_level_52}'";; 76 | 53) printf %s "reg m '${kak_opt__sokoban_level_53}'";; 77 | 54) printf %s "reg m '${kak_opt__sokoban_level_54}'";; 78 | 55) printf %s "reg m '${kak_opt__sokoban_level_55}'";; 79 | 56) printf %s "reg m '${kak_opt__sokoban_level_56}'";; 80 | 57) printf %s "reg m '${kak_opt__sokoban_level_57}'";; 81 | 58) printf %s "reg m '${kak_opt__sokoban_level_58}'";; 82 | 59) printf %s "reg m '${kak_opt__sokoban_level_59}'";; 83 | 60) printf %s "reg m '${kak_opt__sokoban_level_60}'";; 84 | 61) printf %s "reg m '${kak_opt__sokoban_level_61}'";; 85 | 62) printf %s "reg m '${kak_opt__sokoban_level_62}'";; 86 | 63) printf %s "reg m '${kak_opt__sokoban_level_63}'";; 87 | 64) printf %s "reg m '${kak_opt__sokoban_level_64}'";; 88 | 65) printf %s "reg m '${kak_opt__sokoban_level_65}'";; 89 | 66) printf %s "reg m '${kak_opt__sokoban_level_66}'";; 90 | 67) printf %s "reg m '${kak_opt__sokoban_level_67}'";; 91 | 68) printf %s "reg m '${kak_opt__sokoban_level_68}'";; 92 | 69) printf %s "reg m '${kak_opt__sokoban_level_69}'";; 93 | 70) printf %s "reg m '${kak_opt__sokoban_level_70}'";; 94 | 71) printf %s "reg m '${kak_opt__sokoban_level_71}'";; 95 | 72) printf %s "reg m '${kak_opt__sokoban_level_72}'";; 96 | 73) printf %s "reg m '${kak_opt__sokoban_level_73}'";; 97 | 74) printf %s "reg m '${kak_opt__sokoban_level_74}'";; 98 | 75) printf %s "reg m '${kak_opt__sokoban_level_75}'";; 99 | 76) printf %s "reg m '${kak_opt__sokoban_level_76}'";; 100 | 77) printf %s "reg m '${kak_opt__sokoban_level_77}'";; 101 | 78) printf %s "reg m '${kak_opt__sokoban_level_78}'";; 102 | 79) printf %s "reg m '${kak_opt__sokoban_level_79}'";; 103 | 80) printf %s "reg m '${kak_opt__sokoban_level_80}'";; 104 | 81) printf %s "reg m '${kak_opt__sokoban_level_81}'";; 105 | 82) printf %s "reg m '${kak_opt__sokoban_level_82}'";; 106 | 83) printf %s "reg m '${kak_opt__sokoban_level_83}'";; 107 | 84) printf %s "reg m '${kak_opt__sokoban_level_84}'";; 108 | 85) printf %s "reg m '${kak_opt__sokoban_level_85}'";; 109 | 86) printf %s "reg m '${kak_opt__sokoban_level_86}'";; 110 | 87) printf %s "reg m '${kak_opt__sokoban_level_87}'";; 111 | 88) printf %s "reg m '${kak_opt__sokoban_level_88}'";; 112 | 89) printf %s "reg m '${kak_opt__sokoban_level_89}'";; 113 | 90) printf %s "reg m '${kak_opt__sokoban_level_90}'";; 114 | *) exit 1;; 115 | esac 116 | } 117 | 118 | evaluate-commands %sh{ 119 | if [ -z "${kak_reg_m}" ]; then 120 | printf %s " 121 | echo -markup '{Error}No such level: $1!' 122 | " 123 | exit 1 124 | fi 125 | 126 | ## We try to cleanup hooks and highlighters before opening the buffer, 127 | ## in case they were already set in a previous game 128 | printf %s " 129 | try %{ _sokoban-quit } 130 | edit -scratch *sokoban* 131 | exec \\%cm 132 | exec \\%s\\. 133 | set-option buffer _sokoban_holes %val{selections_desc} 134 | _sokoban-set-hooks 135 | add-highlighter window/sokoban ref sokoban 136 | exec /@ 137 | " 138 | } 139 | } } 140 | 141 | define-command -hidden _sokoban-quit %{ 142 | remove-highlighter window/sokoban 143 | remove-hooks buffer sokoban-input 144 | } 145 | 146 | define-command -hidden _sokoban-left %{ eval -save-regs '/"|^@' %{ 147 | exec l 148 | try %{ 149 | ## is the player against a wall? 150 | exec -draft h # 151 | 152 | try %{ 153 | ## is the player against a boulder? 154 | exec -draft h o|O 155 | 156 | try %{ 157 | ## is the boulder against another boulder or a wall? 158 | exec -draft 2h o|O|# 159 | 160 | ## push the boulder 161 | exec Hai l 162 | } 163 | } catch %{ 164 | exec hd a h 165 | } 166 | } 167 | } } 168 | 169 | define-command -hidden _sokoban-right %{ eval -save-regs '/"|^@' %{ 170 | exec h 171 | try %{ 172 | ## is the player against a wall? 173 | exec -draft l # 174 | 175 | try %{ 176 | ## is the player against a boulder? 177 | exec -draft l o|O 178 | 179 | try %{ 180 | ## is the boulder against another boulder or a wall? 181 | exec -draft 2l o|O|# 182 | 183 | ## push the boulder 184 | exec L a i \; 185 | } 186 | } catch %{ 187 | exec a i 188 | } 189 | } 190 | } } 191 | 192 | define-command -hidden _sokoban-up %{ eval -save-regs '/"|^@' %{ 193 | exec j 194 | try %{ 195 | ## is the player against a wall? 196 | exec -draft k # 197 | 198 | try %{ 199 | ## is the player against a boulder? 200 | exec -draft k o|O 201 | 202 | try %{ 203 | ## is the boulder against another boulder or a wall? 204 | exec -draft 2k o|O|# 205 | 206 | ## push the boulder 207 | exec r 2kro jr@ 208 | } 209 | } catch %{ 210 | exec r kr@ 211 | } 212 | } 213 | } } 214 | 215 | define-command -hidden _sokoban-down %{ eval -save-regs '/"|^@' %{ 216 | exec k 217 | try %{ 218 | ## is the player against a wall? 219 | exec -draft j # 220 | 221 | try %{ 222 | ## is the player against a boulder? 223 | exec -draft j o|O 224 | 225 | try %{ 226 | ## is the boulder against another boulder or a wall? 227 | exec -draft 2j o|O|# 228 | 229 | ## push the boulder 230 | exec r 2jro kr@ 231 | } 232 | } catch %{ 233 | exec rjr@ 234 | } 235 | } 236 | } } 237 | 238 | define-command -hidden _sokoban-on-move %{ eval -draft %{ 239 | ## If all the holes have been covered with boulders, the game is over 240 | #select %opt{_sokoban_holes} 241 | 242 | ## Change the character of boulders in the holes 243 | try %{ 244 | ## FIXME: this should be superseeded by the call above 245 | select %opt{_sokoban_holes} 246 | exec -draft so~ 247 | } 248 | ## Restore the holes that were erased (player going over them) 249 | try %{ 250 | ## FIXME: this should be superseeded by the call above 251 | select %opt{_sokoban_holes} 252 | exec -draft O|@r. 253 | } 254 | 255 | try %{ 256 | ## FIXME: the replace operation above modifies this selection, 257 | ## so we have to restore the points a second time 258 | select %opt{_sokoban_holes} 259 | exec -draft O 260 | } catch %{ 261 | eval -client %val{client} echo -markup "{Information}You win!" 262 | } 263 | } } 264 | 265 | define-command -hidden _sokoban-set-hooks %{ 266 | hook buffer BufClose \*sokoban\* _sokoban-quit 267 | 268 | hook -group sokoban-input buffer NormalKey (|h) _sokoban-left 269 | hook -group sokoban-input buffer NormalKey (|l) _sokoban-right 270 | hook -group sokoban-input buffer NormalKey (|k) _sokoban-up 271 | hook -group sokoban-input buffer NormalKey (|j) _sokoban-down 272 | hook -group sokoban-input buffer NormalKey (||||[hjkl]) _sokoban-on-move 273 | } 274 | 275 | declare-option -hidden str _sokoban_level_0 " 276 | ##### 277 | #@o.# 278 | #####" 279 | 280 | declare-option -hidden str _sokoban_level_1 " 281 | ##### 282 | # # 283 | #o # 284 | ### o## 285 | # o o # 286 | ### # ## # ###### 287 | # # ## ##### ..# 288 | # o o ..# 289 | ##### ### #@## ..# 290 | # ######### 291 | #######" 292 | 293 | declare-option -hidden str _sokoban_level_2 " 294 | ############ 295 | #.. # ### 296 | #.. # o o # 297 | #.. #o#### # 298 | #.. @ ## # 299 | #.. # # o ## 300 | ###### ##o o # 301 | # o o o o # 302 | # # # 303 | ############" 304 | 305 | declare-option -hidden str _sokoban_level_3 " 306 | ######## 307 | # @# 308 | # o#o ## 309 | # o o# 310 | ##o o # 311 | ######### o # ### 312 | #.... ## o o # 313 | ##... o o # 314 | #.... ########## 315 | ########" 316 | 317 | declare-option -hidden str _sokoban_level_4 " 318 | ######## 319 | # ....# 320 | ############ ....# 321 | # # o o ....# 322 | # ooo#o o # ....# 323 | # o o # ....# 324 | # oo #o o o######## 325 | # o # # 326 | ## ######### 327 | # # ## 328 | # o ## 329 | # oo#oo @# 330 | # # ## 331 | ###########" 332 | 333 | declare-option -hidden str _sokoban_level_5 " 334 | ##### 335 | # ##### 336 | # #o## # 337 | # o # 338 | ######### ### # 339 | #.... ## o o### 340 | #.... o oo ## 341 | #.... ##o o @# 342 | ######### o ## 343 | # o o # 344 | ### ## # 345 | # # 346 | ######" 347 | 348 | declare-option -hidden str _sokoban_level_6 " 349 | ###### ### 350 | #.. # ##@## 351 | #.. ### # 352 | #.. oo # 353 | #.. # # o # 354 | #..### # o # 355 | #### o #o # 356 | # o# o # 357 | # o o # 358 | # ## # 359 | #########" 360 | 361 | declare-option -hidden str _sokoban_level_7 " 362 | ##### 363 | ####### ## 364 | ## # @## oo # 365 | # o # 366 | # o ### # 367 | ### #####o### 368 | # o ### ..# 369 | # o o o ...# 370 | # ###...# 371 | # oo # #...# 372 | # ### ##### 373 | ####" 374 | 375 | declare-option -hidden str _sokoban_level_8 " 376 | #### 377 | # ########### 378 | # o o o # 379 | # o# o # o # 380 | # o o # # 381 | ### o# # #### # 382 | #@#o o o ## # 383 | # o #o# # # 384 | # o o o o # 385 | ##### ######### 386 | # # 387 | # # 388 | #......# 389 | #......# 390 | #......# 391 | ########" 392 | 393 | declare-option -hidden str _sokoban_level_9 " 394 | ####### 395 | # ...# 396 | ##### ...# 397 | # . .# 398 | # ## ...# 399 | ## ## ...# 400 | ### ######## 401 | # ooo ## 402 | ##### o o ##### 403 | ## #o o # # 404 | #@ o o o o # 405 | ###### oo o ##### 406 | # # 407 | ########" 408 | 409 | declare-option -hidden str _sokoban_level_10 " 410 | ### ############# 411 | ##@#### # # 412 | # oo oo o o ...# 413 | # ooo# o #...# 414 | # o # oo oo #...# 415 | ### # o #...# 416 | # # o o o #...# 417 | # ###### ###...# 418 | ## # # o o #...# 419 | # ## # oo o o##..# 420 | # ..# # o #.# 421 | # ..# # ooo ooo #.# 422 | ##### # # #.# 423 | # ######### #.# 424 | # #.# 425 | ###############" 426 | 427 | declare-option -hidden str _sokoban_level_11 " 428 | #### 429 | #### # # 430 | ### @###o # 431 | ## o # 432 | ## o oo## ## 433 | # #o## # 434 | # # o oo # ### 435 | # o # # o ##### 436 | #### # oo # # 437 | #### ## o # 438 | #. ### ######## 439 | #.. ..# #### 440 | #...#.# 441 | #.....# 442 | #######" 443 | 444 | declare-option -hidden str _sokoban_level_12 " 445 | ################ 446 | # # 447 | # # ###### # 448 | # # o o o o# # 449 | # # o@o ## ## 450 | # # o o o###...# 451 | # # o o ##...# 452 | # ###ooo o ##...# 453 | # # ## ##...# 454 | ##### ## ##...# 455 | ##### ### 456 | # # 457 | #######" 458 | 459 | declare-option -hidden str _sokoban_level_13 " 460 | ######### 461 | ## ## ##### 462 | ### # # ### 463 | # o #o # # ... # 464 | # # o#@o## # #.#. # 465 | # # #o # . . # 466 | # o o # # #.#. # 467 | # ## ##o o . . # 468 | # o # # #o#.#. # 469 | ## o o o o... # 470 | #o ###### ## # 471 | # # ########## 472 | ####" 473 | 474 | declare-option -hidden str _sokoban_level_14 " 475 | ####### 476 | ####### # 477 | # # o@o # 478 | #oo # ######### 479 | # ###......## # 480 | # o......## # # 481 | # ###...... # 482 | ## #### ### #o## 483 | # #o # o # # 484 | # o ooo # o## # 485 | # o o ###oo # # 486 | ##### o # # 487 | ### ### # # 488 | # # # 489 | ######## # 490 | ####" 491 | 492 | declare-option -hidden str _sokoban_level_15 " 493 | ######## 494 | # # # 495 | # o # 496 | ### #o #### 497 | # o ##o # 498 | # # @ o # o# 499 | # # o #### 500 | ## ####o## # 501 | # o#.....# # # 502 | # o..OO. o# ### 503 | ## #.....# # 504 | # ### ####### 505 | # oo # # 506 | # # # 507 | ###### # 508 | #####" 509 | 510 | declare-option -hidden str _sokoban_level_16 " 511 | ##### 512 | # ## 513 | # # #### 514 | # o #### # 515 | # oo o o# 516 | ###@ #o ## 517 | # ## o o ## 518 | # o ## ## .# 519 | # #o##o #.# 520 | ### o..##.# 521 | # #.O...# 522 | # oo #.....# 523 | # ######### 524 | # # 525 | ####" 526 | 527 | declare-option -hidden str _sokoban_level_17 " 528 | ########## 529 | #.. # # 530 | #.. # 531 | #.. # #### 532 | ####### # ## 533 | # # 534 | # # ## # # 535 | #### ## #### ## 536 | # o ##### # # 537 | # # o o # o # 538 | # @o o # ## 539 | #### ## ####### 540 | # # 541 | ######" 542 | 543 | declare-option -hidden str _sokoban_level_18 " 544 | ########### 545 | # . # # 546 | # #. @ # 547 | ##### ##..# #### 548 | ## # ..### ### 549 | # o #... o # o # 550 | # .. ## ## ## # 551 | ####o##o# o # # # 552 | ## # #o oo # # 553 | # o # # # o## # 554 | # # 555 | # ########### # 556 | #### ####" 557 | 558 | declare-option -hidden str _sokoban_level_19 " 559 | ###### 560 | # @#### 561 | ##### o # 562 | # ## #### 563 | # o # ## # 564 | # o # ##### # 565 | ## o o # # 566 | ## o o ### # # 567 | ## # o # # # 568 | ## # #o# # # 569 | ## ### # # ###### 570 | # o #### # #....# 571 | # o o ..#.# 572 | ####o o# o ....# 573 | # # ## ....# 574 | ###################" 575 | 576 | declare-option -hidden str _sokoban_level_20 " 577 | ########## 578 | ##### #### 579 | # # o #@ # 580 | # #######o#### ### 581 | # # ## # #o ..# 582 | # # o # # #.# 583 | # # o # #o ..# 584 | # # ### ## #.# 585 | # ### # # #o ..# 586 | # # # #### #.# 587 | # #o o o #o ..# 588 | # o # o o # #.# 589 | #### o### #o ..# 590 | # oo ###....# 591 | # ## ###### 592 | ########" 593 | 594 | declare-option -hidden str _sokoban_level_21 " 595 | ######### 596 | # # 597 | # #### 598 | ## #### # # 599 | ## #@## # 600 | # ooo o oo# 601 | # # ## o # 602 | # # ## o #### 603 | #### ooo o# # 604 | # ## ....# 605 | # # # #.. .# 606 | # # # ##...# 607 | ##### o #...# 608 | ## ##### 609 | #####" 610 | 611 | declare-option -hidden str _sokoban_level_22 " 612 | ###### #### 613 | # ####### ##### 614 | # o# # o # # 615 | # o o o # o o # 616 | ##o o # @# o # 617 | # o ########### ## 618 | # # #.......# o# 619 | # ## # ......# # 620 | # # o........o # 621 | # # o #.... ..# # 622 | # o o####o#### o# 623 | # o ### o o ## 624 | # o o o o # 625 | ## ###### o ##### # 626 | # # # 627 | ###################" 628 | 629 | declare-option -hidden str _sokoban_level_23 " 630 | ####### 631 | # # #### 632 | ##### o#o # ## 633 | #.. # # # # 634 | #.. # o#o # o#### 635 | #. # #o # # 636 | #.. o# # o # 637 | #..@# #o #o # # 638 | #.. # o# o# # 639 | #.. # #oo#o # ## 640 | #.. # o# # o#o # 641 | #.. # # # # # 642 | ##. #### ##### # 643 | #### #### #####" 644 | 645 | declare-option -hidden str _sokoban_level_24 " 646 | ############### 647 | #.......... .#### 648 | #..........oo.# # 649 | ###########o # ## 650 | # o o o # 651 | ## #### # o # # 652 | # # ## # ## 653 | # o# # ## ### ## 654 | # o #o### ### ## 655 | ### o # # ### ## 656 | ### o ## # # ## 657 | # o # o o o # 658 | # o o#ooo # # 659 | # # o ##### 660 | # @## # # # 661 | ##############" 662 | 663 | declare-option -hidden str _sokoban_level_25 " 664 | #### 665 | # ############## 666 | # # ..#......# 667 | # # # ##### ...# 668 | ##o# ........# 669 | # ##o###### #### 670 | # o # ######@ # 671 | ##o # o ###### # 672 | # o #ooo## # 673 | # # #o#o### 674 | # #### #ooooo # 675 | # # o # # 676 | # # ## ### 677 | # ######o###### o # 678 | # # # # 679 | ########## #####" 680 | 681 | declare-option -hidden str _sokoban_level_26 " 682 | ####### 683 | # # ##### 684 | ## # #...### 685 | # o# #... # 686 | # o #oo ... # 687 | # o# #... .# 688 | # # o######## 689 | ##o o o # 690 | ## # oo # # 691 | ###### ##oo@# 692 | # ## 693 | ########" 694 | 695 | declare-option -hidden str _sokoban_level_27 " 696 | ################# 697 | #... # # ## 698 | ##..... o## # #o # 699 | #......# o # # 700 | #......# # # # # 701 | ######### o o o # 702 | # #o##o ##o## 703 | ## o # o # 704 | # ## ### # ##o # 705 | # o oo o o # 706 | # o o##o ###### 707 | ####### @ ## 708 | ######" 709 | 710 | declare-option -hidden str _sokoban_level_28 " 711 | ##### 712 | ##### # 713 | ## o o #### 714 | ##### o o o ##.# 715 | # oo ##..# 716 | # ###### ###.. # 717 | ## # # #... # 718 | # o # #... # 719 | #@ #o ## ####...# 720 | #### o oo ##..# 721 | ## o o o...# 722 | # oo o # .# 723 | # o o #### 724 | ###### # 725 | #####" 726 | 727 | declare-option -hidden str _sokoban_level_29 " 728 | ##### 729 | # ## 730 | # o ######### 731 | ## # # ###### 732 | ## # o#o#@ # # 733 | # # o # o # 734 | # ### ######### ## 735 | # ## ..O..... # ## 736 | ## ## O.O..O.O # ## 737 | # o########## ##o # 738 | # o o o o # 739 | # # # # # # 740 | ###################" 741 | 742 | declare-option -hidden str _sokoban_level_30 " 743 | ########### 744 | # # # 745 | ##### # o o # 746 | # ##### o## # ## 747 | # o ## # ## o # 748 | # o @oo # ##ooo # 749 | ## ### # ## # 750 | ## # ### #####o# 751 | ## # o #....# 752 | # ### ## o #....## 753 | # o o # #..o. # 754 | # ## o # ##.... # 755 | ##### ######...## 756 | ##### #####" 757 | 758 | declare-option -hidden str _sokoban_level_31 " 759 | #### 760 | # ######### 761 | ## ## # # 762 | # o# o@o #### 763 | #o o # o o# ## 764 | ## o## #o o # 765 | # # # # ooo # 766 | # o o o## #### 767 | # o o #o# # # 768 | ## ### ###o # 769 | # #.... # 770 | ####......#### 771 | #....#### 772 | #...## 773 | #...# 774 | #####" 775 | 776 | declare-option -hidden str _sokoban_level_32 " 777 | #### 778 | ##### # 779 | ## o# 780 | ## o ## ### 781 | #@o o # o # 782 | #### ## o# 783 | #....#o o # 784 | #....# o# 785 | #.... oo ## 786 | #... # o # 787 | ######o o # 788 | # ### 789 | #o ### 790 | # # 791 | ####" 792 | 793 | declare-option -hidden str _sokoban_level_33 " 794 | ########### 795 | # ## # 796 | # o o # 797 | #### ## oo # 798 | # o # # 799 | # ooo # #### 800 | # # # o ## 801 | # # # o # 802 | # o# o# # 803 | # ..# #### 804 | ####.. o #@# 805 | #.....# o# # 806 | ##....# o # 807 | ##..## # 808 | ##########" 809 | 810 | declare-option -hidden str _sokoban_level_34 " 811 | ######### 812 | #.... ## 813 | #.#.# o ## 814 | ##....# # @## 815 | # ....# # ## 816 | # #o ##o # 817 | ## ### o # 818 | #o o o o# # 819 | # # o o ## # 820 | # ### ## # 821 | # ## ## ## 822 | # o # o # 823 | ###o o ### 824 | # ##### 825 | ####" 826 | 827 | declare-option -hidden str _sokoban_level_35 " 828 | ############ ###### 829 | # # # ###....# 830 | # oo# @ .....# 831 | # # ### # ....# 832 | ## ## ### # ....# 833 | # o o # # #### 834 | # o o## # # 835 | #### # #### # ## # 836 | # # #o ## # # 837 | # o o # ## # ## 838 | # # o o # # # 839 | # o ## ## # ##### 840 | # oo oo # 841 | ## ## ### o # 842 | # # # # 843 | ###### ######" 844 | 845 | declare-option -hidden str _sokoban_level_36 " 846 | ##### 847 | ##### ###### # 848 | # #### o o o # 849 | # o ## ## ## ## 850 | # o o o o # 851 | ### o ## ## ## 852 | # ##### #####oo # 853 | ##o##### @## # 854 | # o ###o### o ## 855 | # o # ### ### 856 | # oo o # oo # 857 | # # ## # 858 | #######.. .### 859 | #.........# 860 | #.........# 861 | ###########" 862 | 863 | declare-option -hidden str _sokoban_level_37 " 864 | ########### 865 | #...... ######### 866 | #...... # ## # 867 | #..### o o # 868 | #... o o # ## # 869 | #...#o##### # # 870 | ### # #o #o # 871 | # oo o o o## # 872 | # o #o#o ##o # 873 | ### ## # ## # 874 | # o o ## ###### 875 | # o o # 876 | ## # # # 877 | #####@##### 878 | ###" 879 | 880 | declare-option -hidden str _sokoban_level_38 " 881 | #### 882 | ####### @# 883 | # o # 884 | # o## o# 885 | ##o#...# # 886 | # o... # 887 | # #. .# ## 888 | # # #o # 889 | #o o # 890 | # ####### 891 | ####" 892 | 893 | declare-option -hidden str _sokoban_level_39 " 894 | ###### 895 | #############....# 896 | ## ## ##....# 897 | # oo## o @##....# 898 | # oo o# ....# 899 | # o ## oo # # ...# 900 | # o ## o # ....# 901 | ## ##### ### ##.### 902 | ## o o ## . # 903 | # o### # ##### ### 904 | # o # # 905 | # o #o o o### # 906 | # ooo# o # #### 907 | # # oo # 908 | ###### ### 909 | #####" 910 | 911 | declare-option -hidden str _sokoban_level_40 " 912 | ############ 913 | # ## 914 | # # #oo o # 915 | #o #o# ## @# 916 | ## ## # o # ## 917 | # o #o # # 918 | # # o # # 919 | ## o o ## # 920 | # # ## o # 921 | # ## oo# # 922 | ######oo # # 923 | #....# ######## 924 | #.#... ## 925 | #.... # 926 | #.... # 927 | #########" 928 | 929 | declare-option -hidden str _sokoban_level_41 " 930 | ##### 931 | ## ## 932 | ## # 933 | ## oo # 934 | ## oo o # 935 | # o o # 936 | #### # oo ##### 937 | # ######## ## # 938 | #. ooo@# 939 | #.# ####### ## ## 940 | #.# #######. #o o## 941 | #........... # # 942 | ############## o # 943 | ## ## 944 | ####" 945 | 946 | declare-option -hidden str _sokoban_level_42 " 947 | ######## 948 | #### ###### 949 | # ## o o @# 950 | # ## ##o#o o o## 951 | ### ......# oo ## 952 | # ......# # # 953 | # # ......#o o # 954 | # #o...... oo# o # 955 | # ### ###o o ## 956 | ### o o o o # 957 | # o o o o # 958 | ###### ###### 959 | #####" 960 | 961 | declare-option -hidden str _sokoban_level_43 " 962 | ####### 963 | ##### # #### 964 | # # o # 965 | #### #oo ## ## # 966 | ## # # ## ### 967 | # ### o#o o o # 968 | #... # ## # # 969 | #...# @ # ### ## 970 | #...# ### o o # 971 | ######## ## # # 972 | #########" 973 | 974 | declare-option -hidden str _sokoban_level_44 " 975 | ##### 976 | # # 977 | # # ####### 978 | # o@###### 979 | # o ##o ### # 980 | # #### o o # 981 | # ##### # #o #### 982 | ## #### ##o # 983 | # o# o # ## ## # 984 | # # #...# # 985 | ###### ### ... # 986 | #### # #...# # 987 | # ### # # 988 | # # 989 | #########" 990 | 991 | declare-option -hidden str _sokoban_level_45 " 992 | ##### #### 993 | #...# # #### 994 | #...### o # 995 | #....## o o### 996 | ##....## o # 997 | ###... ## o o # 998 | # ## # o # 999 | # ## # ### #### 1000 | # o # #o o # 1001 | # o @ o o # 1002 | # # o oo o ### 1003 | # ###### ### 1004 | # ## #### 1005 | ###" 1006 | 1007 | declare-option -hidden str _sokoban_level_46 " 1008 | ########## 1009 | # #### 1010 | # ###### # ## 1011 | # # o o o o # 1012 | # #o # 1013 | ###o oo# ### 1014 | # ## # o## 1015 | ##o# o @# 1016 | # o o ### 1017 | # # o # 1018 | # ## # # 1019 | ## ##### # 1020 | # # 1021 | #.......### 1022 | #.......# 1023 | #########" 1024 | 1025 | declare-option -hidden str _sokoban_level_47 " 1026 | #### 1027 | ######### ## 1028 | ## o o ##### 1029 | # ## ## ##...# 1030 | # #oo o oo#o##...# 1031 | # # @ # ...# 1032 | # o# ###oo ...# 1033 | # o oo o ##....# 1034 | ###o ####### 1035 | # ####### 1036 | ####" 1037 | 1038 | declare-option -hidden str _sokoban_level_48 " 1039 | ######### 1040 | #O.O#O.O# 1041 | #.O.O.O.# 1042 | #O.O.O.O# 1043 | #.O.O.O.# 1044 | #O.O.O.O# 1045 | ### ### 1046 | # # 1047 | ###### ###### 1048 | # # 1049 | # o o o o o # 1050 | ## o o o o ## 1051 | #o o o o o# 1052 | # o@o # 1053 | # ##### # 1054 | #### ####" 1055 | 1056 | declare-option -hidden str _sokoban_level_49 " 1057 | #### 1058 | # ## 1059 | # ## 1060 | # oo ## 1061 | ###o o ## 1062 | #### o # 1063 | ### # ##### # 1064 | # # #....o # 1065 | # # o ....# # 1066 | # o # #.O..# # 1067 | ### #### ### # 1068 | #### @o ##o## 1069 | ### o # 1070 | # ## # 1071 | #########" 1072 | 1073 | declare-option -hidden str _sokoban_level_50 " 1074 | ############ 1075 | ##.. # # 1076 | ##..O o o # 1077 | ##..O.# # # o## 1078 | #..O.# # # o # 1079 | ####...# # # # 1080 | # ## # # 1081 | # @o o ### # ## 1082 | # o o # # # 1083 | ###oo # # # # # 1084 | # o # # ##### 1085 | # o# ##### # 1086 | #o # # # # 1087 | # ### ## # 1088 | # # # ## 1089 | #### ######" 1090 | 1091 | declare-option -hidden str _sokoban_level_51 " 1092 | ######### 1093 | # # 1094 | # o oo o# 1095 | ### # o # 1096 | #.# oo ## 1097 | #.### o # 1098 | #.#. o ## #### 1099 | #... o## o # 1100 | #...o o # 1101 | #..###o### #@# 1102 | #..# # ### 1103 | #### #######" 1104 | 1105 | declare-option -hidden str _sokoban_level_52 " 1106 | ######## 1107 | #......# 1108 | #### #......# 1109 | # #########...# 1110 | # o o #...# 1111 | # # # # # # # 1112 | ##### # # #@# # # 1113 | # # ### ### ## ## 1114 | # o # o o o # # 1115 | # ooo o # # 1116 | # # ###o###o## # 1117 | ### # o # # 1118 | ## o # o o o ### 1119 | # # ### ### ## 1120 | # o # 1121 | # ########### 1122 | ####" 1123 | 1124 | declare-option -hidden str _sokoban_level_53 " 1125 | ################## 1126 | # ## 1127 | # o# o ## o # 1128 | # o### # oo # 1129 | #.### o o ## ## 1130 | #...# # # #o # 1131 | #..##oo#### o # # 1132 | #...# o ## ### 1133 | #...o ### # # # 1134 | ##.. o# ## ##@ # 1135 | ##.# # 1136 | ##################" 1137 | 1138 | declare-option -hidden str _sokoban_level_54 " 1139 | #################### 1140 | # # # # #@# 1141 | # o o o # # 1142 | ## ###..## ### # 1143 | # #....#o# o### # 1144 | # o #....# o o o # 1145 | # #....# # # o o # 1146 | # ##..## #o# # 1147 | ##o## ## # #o## 1148 | # o o # # # 1149 | # # # # # 1150 | ####################" 1151 | 1152 | declare-option -hidden str _sokoban_level_55 " 1153 | #################### 1154 | # @## # ## 1155 | # ## o o ## 1156 | # ###....# # # ### 1157 | # #....# # # o # 1158 | ### #...# # # 1159 | ## ##.# o o # 1160 | ## o o ### # # ### 1161 | ## o # # o # 1162 | #### o o# # # # o # 1163 | #### # # ## 1164 | ####################" 1165 | 1166 | declare-option -hidden str _sokoban_level_56 " 1167 | #################### 1168 | # # ## # @### 1169 | ## o # o### # 1170 | ##o# o ##o# o o # 1171 | # o# o ### 1172 | # ## o ### #....# 1173 | # # o# # # # #....## 1174 | # o o # #....### 1175 | ##o ### o #....#### 1176 | # # o ###### 1177 | # # # ###### 1178 | ####################" 1179 | 1180 | declare-option -hidden str _sokoban_level_57 " 1181 | #################### 1182 | #@ ### # # # 1183 | # # # # o o # 1184 | ##### # o o#o# # 1185 | #.#..# ##o o # 1186 | #..... o # ## 1187 | #..... ###o##o### 1188 | #.#..# o # # 1189 | ##### # #o o # 1190 | ##### # o o o # 1191 | ##### # # # # # 1192 | ####################" 1193 | 1194 | declare-option -hidden str _sokoban_level_58 " 1195 | #################### 1196 | ##... ## # # # 1197 | #.... o ## # 1198 | #....# # #o###o # 1199 | #...# # # # 1200 | ##.# #o # o## # 1201 | # # # o o ### o # 1202 | # o o # # ## # 1203 | ## # ## #oo# o# # # 1204 | # # o o # ## 1205 | # # # # @# 1206 | ####################" 1207 | 1208 | declare-option -hidden str _sokoban_level_59 " 1209 | #################### 1210 | # # #@# ## ##### 1211 | # # # o o ##### 1212 | # # ###### o ### 1213 | # # #....# oo # 1214 | ##o##o##....# # 1215 | # #....##o##o## 1216 | # oo #....# # 1217 | # o o # # ### # 1218 | ##### o o o # 1219 | ##### # # # ## 1220 | ####################" 1221 | 1222 | declare-option -hidden str _sokoban_level_60 " 1223 | #################### 1224 | # # # # 1225 | # o ## ### ## 1226 | ##### ## o o # 1227 | ##..## # # o # # # 1228 | #.... o ##o# ## 1229 | #.... o##### #o## 1230 | ##..# # # # o # 1231 | ###.# # o o # @# 1232 | ## o o # # #### 1233 | ## ########### 1234 | ####################" 1235 | 1236 | declare-option -hidden str _sokoban_level_61 " 1237 | #################### 1238 | # ###..### # 1239 | # oo ###..### o@ # 1240 | # # ##......# o # 1241 | # #......# o # 1242 | #### ###..######o # 1243 | # ooo #..# # # 1244 | # o# o o oo #o # 1245 | # # ## o ## # # 1246 | # o o ## o o # 1247 | # # ## ## # # 1248 | ####################" 1249 | 1250 | declare-option -hidden str _sokoban_level_62 " 1251 | #################### 1252 | # # # # # # # 1253 | # @# # ## o o ## 1254 | #### # # # o # 1255 | # # ## #o ## ## # 1256 | # o o o # 1257 | #..###oo## o##o ## # 1258 | #..#.# # o o # # 1259 | #....# oo ##o #### 1260 | #....# ##### # 1261 | #...### ## # 1262 | ####################" 1263 | 1264 | declare-option -hidden str _sokoban_level_63 " 1265 | #################### 1266 | #....# # # # 1267 | #....# # o o # 1268 | #.... ## o# # o#o # 1269 | #...# o o# o # 1270 | #..#### # o oo # 1271 | # #### #### ### 1272 | # # # # 1273 | # ## # o # o o # 1274 | # ## o ## o o # 1275 | # @# # # # 1276 | ####################" 1277 | 1278 | declare-option -hidden str _sokoban_level_64 " 1279 | #################### 1280 | #....### # 1281 | #....##### # #o# ## 1282 | #....### #o o # 1283 | #....### o #oo## 1284 | ## #### o# #o o # 1285 | ## #### o o # # 1286 | #@ ####o###o## o # 1287 | ## # # o # 1288 | ## ### # o #### 1289 | ######## # # # 1290 | ####################" 1291 | 1292 | declare-option -hidden str _sokoban_level_65 " 1293 | #################### 1294 | # # @#...### 1295 | # # ##...## 1296 | # # # ##o## ## ....# 1297 | # o # ooo ....# 1298 | ###o### oo ### ##.# 1299 | # o # # #### 1300 | # o # ### # # # 1301 | ## #o## o oo # 1302 | # o ## # # # # 1303 | # # # # # 1304 | ####################" 1305 | 1306 | declare-option -hidden str _sokoban_level_66 " 1307 | #################### 1308 | # # #...#@ # 1309 | # # ....# # 1310 | # o # #....# # 1311 | # ##o#### ##....# # 1312 | # o o # #...# # 1313 | # oo # # # oo # 1314 | ### ooo# oo o # 1315 | # o # # # o# # 1316 | # o# # o # 1317 | # # # # # # 1318 | ####################" 1319 | 1320 | declare-option -hidden str _sokoban_level_67 " 1321 | #################### 1322 | #####@###.##...## # 1323 | #####o ..#...# # 1324 | #### ......# o # 1325 | ### o #.....## # ## 1326 | ## oo# ##### o o # 1327 | ## o# o ## oo # 1328 | ## # # # o o # 1329 | ## oo ### #o## # 1330 | ## o# o o o ## 1331 | ### # # ### 1332 | ####################" 1333 | 1334 | declare-option -hidden str _sokoban_level_68 " 1335 | #################### 1336 | #@ # # # 1337 | ## ### ## #### # ## 1338 | # # # oo # 1339 | # # # # o # o ## ## 1340 | # o # #oo # # 1341 | # ### # ## ## 1342 | #..#.# o # o # # 1343 | #..#.# o # ## oo # 1344 | #....## oo o # # 1345 | #.....## # # 1346 | ####################" 1347 | 1348 | declare-option -hidden str _sokoban_level_69 " 1349 | #################### 1350 | # # # # ## 1351 | # o# o o ##...o o # 1352 | # o # ##....# o # 1353 | # ## o ##....# o # 1354 | # o #....## o # 1355 | # o## #...# # 1356 | # ooo##o## ### ## 1357 | # # # # # # # 1358 | # o # o ## # 1359 | # # #@ # 1360 | ####################" 1361 | 1362 | declare-option -hidden str _sokoban_level_70 " 1363 | #################### 1364 | # # # # # # # 1365 | # o o o # 1366 | ## # #o###o## ## # 1367 | # o o # o # 1368 | # ###o##o# # o # 1369 | # # o o ###### o# 1370 | # o oo o #@#.#...# 1371 | # # # # #.#...# 1372 | # ########## #.....# 1373 | # #.....# 1374 | ####################" 1375 | 1376 | declare-option -hidden str _sokoban_level_71 " 1377 | #################### 1378 | # # # ## ## 1379 | # o# o # ## # 1380 | # o o #..# o # 1381 | # o o #....# # ## 1382 | # o# #......### o # 1383 | # # #....# #o # 1384 | # o ####..# # # 1385 | ## o ## # # o o## 1386 | ### o o#@o o# # 1387 | #### # # # 1388 | ####################" 1389 | 1390 | declare-option -hidden str _sokoban_level_72 " 1391 | #################### 1392 | # ....# #### 1393 | # .... # 1394 | # # ########## # 1395 | # #o # ###..# 1396 | # o #oo### #..# 1397 | # o ### o o #..# 1398 | # o # o o # ##..# 1399 | # # oo # o ## ## 1400 | #@## o# o o ## 1401 | ## ## # ### 1402 | ####################" 1403 | 1404 | declare-option -hidden str _sokoban_level_73 " 1405 | #################### 1406 | # # #@ # # 1407 | # oo #oo# # # ## # 1408 | # # o o #oo # # 1409 | ## # # # # # # # 1410 | # ## # # 1411 | # # o # # # # 1412 | # o #o # # o #..# 1413 | ##o # #### #...# 1414 | # o #....# 1415 | # # # #.....# 1416 | ####################" 1417 | 1418 | declare-option -hidden str _sokoban_level_74 " 1419 | #################### 1420 | # # ##### # 1421 | ## o # #### o # 1422 | #### oo #..# # # 1423 | # o o ##..#### ## 1424 | # o ###.... oo # 1425 | # #o# ....# # o # 1426 | # # # o ..###o# # 1427 | # # o #..# ## # 1428 | # o# #### # o## 1429 | # # # @# ## 1430 | ####################" 1431 | 1432 | declare-option -hidden str _sokoban_level_75 " 1433 | #################### 1434 | # # # # #@# 1435 | # o o # o # # 1436 | ##o# o### # oo# # 1437 | # # #.### #o o # 1438 | # #o#....# # ### # 1439 | # o #.....## # # 1440 | ##o #.#....#oo o # 1441 | # ######..## # # # 1442 | # o o ### # 1443 | # # # # # 1444 | ####################" 1445 | 1446 | declare-option -hidden str _sokoban_level_76 " 1447 | #################### 1448 | # # # # #@## # # 1449 | # o # 1450 | # ##o# ##### o # ## 1451 | ## ##.....# # # 1452 | ##o##o#.....###o#o # 1453 | # # ##.....# # ## 1454 | # o ##..## # # 1455 | # o # o o ooo # 1456 | ## o o# # # o # 1457 | # ## # # # 1458 | ####################" 1459 | 1460 | declare-option -hidden str _sokoban_level_77 " 1461 | #################### 1462 | # ## # # # 1463 | # o o ## o # 1464 | ## ##### .###### ## 1465 | # ## ##....#### ## 1466 | ## ##o ###..## # 1467 | # #... .# o o # 1468 | # o ## ## . ### #### 1469 | # # o #.## # # 1470 | # o o # .#### ## 1471 | # # ## # ## # ## 1472 | ####### o##o o # 1473 | ## o #@# 1474 | # ## ###### 1475 | #######" 1476 | 1477 | declare-option -hidden str _sokoban_level_78 " 1478 | ########### 1479 | # # 1480 | # o o # 1481 | ###### # o ##### # 1482 | # ##### o ##o# 1483 | # o o # 1484 | # ## ## # 1485 | # ##@##### ## # 1486 | # #### # ## ## 1487 | #....# # o # 1488 | #....# # # 1489 | ###### #######" 1490 | 1491 | declare-option -hidden str _sokoban_level_79 " 1492 | ############# 1493 | # # 1494 | # ### oo # 1495 | # # o o # 1496 | # o####o###### 1497 | # o ## ##### 1498 | # oo o ...# 1499 | ### ## oo# ...# 1500 | # ## # ...# 1501 | # # ...# 1502 | ###@############# 1503 | ###" 1504 | 1505 | declare-option -hidden str _sokoban_level_80 " 1506 | ################# 1507 | ###@## ...# 1508 | # # ...# 1509 | # o # ...# 1510 | # oo # ...# 1511 | ## o ###o########## 1512 | # ### o # 1513 | ## o o # 1514 | # o # o # 1515 | # o # # 1516 | # o # # 1517 | # # # 1518 | ###########" 1519 | 1520 | declare-option -hidden str _sokoban_level_81 " 1521 | ##### 1522 | ########## # 1523 | # # # 1524 | # o o oo # 1525 | # ##### ## o # 1526 | #oo #o## o # 1527 | # ### # ##o # 1528 | ###### ### o o # 1529 | #.... ## # 1530 | #.... ###### 1531 | #.... # 1532 | ###########@## 1533 | ###" 1534 | 1535 | declare-option -hidden str _sokoban_level_82 " 1536 | ###### 1537 | #### # 1538 | # ## # 1539 | # o # 1540 | ### #### ######## 1541 | # o o ## ...# 1542 | # oo oo ...# 1543 | # o o## ...# 1544 | ##@## ## ## ...# 1545 | ### o ######## 1546 | # oo # 1547 | # # # 1548 | #########" 1549 | 1550 | declare-option -hidden str _sokoban_level_83 " 1551 | ####### ######### 1552 | # # # ## # 1553 | # ### # # o # 1554 | # # o ### o # 1555 | # oo ##o # 1556 | # #### ## # 1557 | #@############ ## 1558 | ###.. #####o # 1559 | #.. #### # 1560 | #.. oo # 1561 | #.. #### o # 1562 | #.. # # # 1563 | ######## #####" 1564 | 1565 | declare-option -hidden str _sokoban_level_84 " 1566 | ####### 1567 | # ########## 1568 | # # # ## 1569 | # o # o o # 1570 | # o # o ## # 1571 | # oo ##o o # 1572 | ## # ## ####### 1573 | ## # ## ...# 1574 | # #o ...# 1575 | # oo ...# 1576 | # ##@# ...# 1577 | ################" 1578 | 1579 | declare-option -hidden str _sokoban_level_85 " 1580 | ############ 1581 | # # ## 1582 | # o o # ###### 1583 | #### ##### # 1584 | #.. # #### # 1585 | #.#### #### # 1586 | #.... # o #### 1587 | # ...# # ooo# ## 1588 | ###.#### ## o@o # 1589 | # ##### o # # 1590 | # #.# o o###o # 1591 | # #.######## # o # 1592 | # #.. ## o # 1593 | # # ####### o # # # 1594 | # # # ## 1595 | ##### ##########" 1596 | 1597 | declare-option -hidden str _sokoban_level_86 " 1598 | ################ 1599 | # #@ # # 1600 | # # # # # o oo# 1601 | # #...# #ooo # 1602 | # ...# # o oo## 1603 | # ##.## # ## # 1604 | # #... o # 1605 | # ## ### ####### 1606 | # # #### 1607 | ######" 1608 | 1609 | declare-option -hidden str _sokoban_level_87 " 1610 | ##### 1611 | #### ## ##### 1612 | # o ### # 1613 | # o@o o o # 1614 | # #o######## ## 1615 | # # o # # 1616 | # # o o # # # 1617 | ## # o# # ##### 1618 | # ## # # 1619 | # o # ### # 1620 | ##### ## #....# 1621 | # o ....# 1622 | # #....# 1623 | ################" 1624 | 1625 | declare-option -hidden str _sokoban_level_88 " 1626 | ############# 1627 | #........#### 1628 | #...#### # ##### 1629 | #...# ### o # 1630 | #...oo o o # 1631 | # .# o o# o ## 1632 | #...# #o# o # 1633 | #.# # o o # 1634 | #. #o###o####o# 1635 | ## # o o # 1636 | # # o@o # # 1637 | # # #### o o# 1638 | # # ### # 1639 | # # oo # ##### 1640 | # # # 1641 | #########" 1642 | 1643 | declare-option -hidden str _sokoban_level_89 " 1644 | ################## 1645 | # o ...#.## 1646 | # ####..... # 1647 | # ####### #..... # 1648 | # # o o ##....## 1649 | # # o # # ###...# 1650 | # # o@o o ##### # 1651 | ## # o o oo o # 1652 | # #o# o# # o## # 1653 | # ## ## ## o # # 1654 | # # o# o o # # 1655 | # # ####### 1656 | # ########o## # 1657 | # # o # 1658 | ######## ##### 1659 | ### # 1660 | ####" 1661 | 1662 | declare-option -hidden str _sokoban_level_90 " 1663 | #################### 1664 | #..# # # 1665 | #.o o #oo o## o## 1666 | #.o# ### ## ## # 1667 | # # o # oo o # 1668 | # ### # # #o #### 1669 | # ## # o #@ # # 1670 | # o o ##.## o # 1671 | # # o# o# o ### 1672 | # # # # ### # 1673 | # ######## # # 1674 | # # #.#.# 1675 | ##o########o# ...# 1676 | # .O # ##.#.# 1677 | # .O...O o .....# 1678 | ####################" 1679 | -------------------------------------------------------------------------------- /grepmenu.asciidoc: -------------------------------------------------------------------------------- 1 | grepmenu.asciidoc 2 | ================= 3 | 4 | The builtin `grep` command allows searching for a pattern through given files 5 | and directories, but creates a buffer listing all the matched lines. Having 6 | a buffer created and stay in the buffers list after the results are not 7 | needed anymore is not always desirable, and interacting with a buffer to 8 | open another one feels wonky at times. 9 | 10 | This script provides with the same functionalities as the builtin `grep` 11 | command, except it displays matches in an interactive menu instead of a buffer. 12 | 13 | Commands 14 | -------- 15 | 16 | grepmenu 17 | ~~~~~~~~ 18 | 19 | The `grepmenu` command takes a pattern that will be searched for in the 20 | current working directory, and the resulting matches will be displayed in 21 | a menu. Selecting a candidate from that menu will open the buffer, and set 22 | the main selection's coordinates to that of the match automatically. 23 | 24 | Additional parameters are optional. 25 | 26 | All parameters are forwarded directly to the command stored in `grepmenucmd`. 27 | 28 | Variables 29 | --------- 30 | 31 | grepmenucmd 32 | ~~~~~~~~~~~ 33 | 34 | Default: `ag --all-text --vimgrep`. 35 | 36 | String holding the command to which the `grepmenu` command's parameters will 37 | be forwarded. The command should expect to receive a search pattern followed 38 | by optional arbitrary parameters as arguments. 39 | 40 | The output of the command should be in the following format: 41 | 42 | ``` 43 | ::: 44 | ``` 45 | -------------------------------------------------------------------------------- /grepmenu.kak: -------------------------------------------------------------------------------- 1 | ## 2 | ## grepmenu.kak for kakoune-extra 3 | ## by lenormf 4 | ## 5 | 6 | declare-option -docstring "shell command run to look for a pattern" str grepmenucmd "ag --all-text --vimgrep" 7 | 8 | define-command -params 1.. -file-completion \ 9 | -docstring %{grepmenu [targets]: search one or more targets for a given pattern} \ 10 | grepmenu %{ evaluate-commands %sh{ 11 | readonly PATTERN="$1" 12 | 13 | shift 14 | 15 | eval "${kak_opt_grepmenucmd}" "${PATTERN}" -- "$@" | awk " 16 | /^[^:]*:[0-9]*:[0-9]*:/ { 17 | # escape all simple quotes 18 | gsub(/'/, \"''\") 19 | # gather filename and coordinates into an array 20 | split(\$0, s, \":\") 21 | 22 | # remove the coordinates information from the matched line 23 | sub(\"^[^:]*:[0-9]*:[0-9]*:\", \"\") 24 | 25 | # strip the matched line 26 | sub(\"^[ \t]*|[ \t]*\$\", \"\") 27 | 28 | candidates = candidates \" \" \"'\" s[1] \":\" s[2] \":\" s[3] \" \" \$0 \"' ' edit! %{\" s[1] \"} \" s[2] \" \" s[3] \"'\" 29 | } 30 | 31 | END { 32 | if (length(candidates)) 33 | print \"menu\" candidates 34 | } 35 | " 36 | } } 37 | -------------------------------------------------------------------------------- /hatch_terminal.asciidoc: -------------------------------------------------------------------------------- 1 | hatch_terminal.kak 2 | ================== 3 | 4 | This script allows spawning a shell or an arbitrary command in a new window, exporting information about the current session in the environment. 5 | 6 | Commands 7 | -------- 8 | 9 | The following commands are specialized implementations that all follow the same prototype. They all take an optional argument, a shell command 10 | that will be run in the newly created window. If no command is passed, a shell is spawned. 11 | 12 | The environment of the newly created window will contain the following environment variables: 13 | 14 | * `KAK_SESSION`: name of the parent session that spawned the window 15 | * `KAK_CLIENT`: name of the parent client that spawned the window 16 | 17 | hatch-terminal-x11 18 | ~~~~~~~~~~~~~~~~~~ 19 | 20 | Implementation used when no multiplexer is detected and the `$DISPLAY` environment variable is not empty. A new terminal is spawned using the `termcmd` option. 21 | 22 | hatch-terminal-tmux 23 | ~~~~~~~~~~~~~~~~~~~ 24 | 25 | Implementation used when the `$TMUX` environment variable is not empty, creates an horizontal split by default. 26 | 27 | hatch-terminal-dvtm 28 | ~~~~~~~~~~~~~~~~~~~ 29 | 30 | Implementation used when the `$DVTM` environment variable is not empty. 31 | 32 | Aliases 33 | ------- 34 | 35 | hatch-terminal 36 | ~~~~~~~~~~~~~~ 37 | 38 | The `hatch-terminal` alias is automatically set to one of the commands defined by the script, according to the environment in which the session is set. 39 | -------------------------------------------------------------------------------- /hatch_terminal.kak: -------------------------------------------------------------------------------- 1 | ## 2 | ## hatch_terminal.kak by lenormf 3 | ## Spawn a new shell/command whose environment contains Kakoune metadata 4 | ## 5 | 6 | define-command hatch-terminal-x11 -params .. -docstring %{ 7 | hatch-terminal-x11 [command]: open a new X11 terminal 8 | If specified, the command will be ran in the newly created terminal, otherwise a shell is spawned 9 | The environment contains the `KAK_SESSION` variable set to the parent session's name 10 | } %{ evaluate-commands %sh{ 11 | setsid ${kak_opt_termcmd} "env TMPDIR='${TMPDIR}' \ 12 | KAK_SESSION='${kak_session}' \ 13 | KAK_CLIENT='${kak_client}' \ 14 | ${*:-${SHELL}}" /dev/null 2>&1 & 15 | } } 16 | 17 | define-command hatch-terminal-tmux -params .. -docstring %{ 18 | hatch-terminal-tmux [command]: open a new `tmux` horizontal pane 19 | If specified, the command will be ran in the newly created terminal, otherwise a shell is spawned 20 | The environment contains the `KAK_SESSION` variable set to the parent session's name 21 | } %{ evaluate-commands %sh{ 22 | env TMUX="${kak_client_env_TMUX:-${TMUX}}" tmux split-window -h \ 23 | "env TMPDIR='${TMPDIR}' \ 24 | KAK_SESSION='${kak_session}' \ 25 | KAK_CLIENT='${kak_client}' \ 26 | ${*:-${SHELL}}" /dev/null 2>&1 & 27 | } } 28 | 29 | define-command hatch-terminal-dvtm -params .. -docstring %{ 30 | hatch-terminal-dvtm [command]: open a new `dvtm` pane 31 | If specified, the command will be ran in the newly created terminal, otherwise a shell is spawned 32 | The environment contains the `KAK_SESSION` variable set to the parent session's name 33 | } %{ evaluate-commands %sh{ 34 | if [ -p "${DVTM_CMD_FIFO}" ]; then 35 | printf %s\\n "create \"env TMPDIR='${TMPDIR}' \ 36 | KAK_SESSION='${kak_session}' \ 37 | KAK_CLIENT='${kak_client}' \ 38 | ${*:-${SHELL}}\"" > "${DVTM_CMD_FIFO}" 39 | fi 40 | } } 41 | 42 | evaluate-commands %sh{ 43 | if [ -n "${TMUX}" ]; then 44 | echo "alias global hatch-terminal hatch-terminal-tmux" 45 | elif [ -n "${DVTM}" ]; then 46 | echo "alias global hatch-terminal hatch-terminal-dvtm" 47 | elif [ -n "${DISPLAY}" ]; then 48 | echo "alias global hatch-terminal hatch-terminal-x11" 49 | fi 50 | } 51 | -------------------------------------------------------------------------------- /idsession.asciidoc: -------------------------------------------------------------------------------- 1 | idsession.kak 2 | ============= 3 | 4 | The default name for a new session is the process ID of the server, 5 | which makes it difficult to differentiate one session from another. The 6 | `idsession` command fixes that by renaming the current session into a name 7 | that's human-readable (hyphen separated adjective/noun pair). 8 | 9 | Commands 10 | -------- 11 | 12 | idsession 13 | ~~~~~~~~~ 14 | 15 | Rename the current session. The current session name is expected to be a 16 | number to use as a seed, which is the case in a new session (the process 17 | ID of the server is the session name). If the session name is not a number, 18 | `0` will be used as a seed. 19 | 20 | The seed is subsequently used to pick an adjective and a noun that will 21 | make up the resulting session name. The selection is a simple modulo, 22 | which makes the outcome of this function deterministic for the same seed. 23 | 24 | To automatically rename new sessions, call this command from a hook: 25 | 26 | ``` 27 | hook global KakBegin .* idsession 28 | ``` 29 | 30 | Variables 31 | --------- 32 | 33 | idsession_adjectives 34 | ~~~~~~~~~~~~~~~~~~~~ 35 | 36 | List of adjectives that will make up the first part of the adjective/noun 37 | pair. 38 | 39 | The default list of adjectives contain words that start with the letter 40 | `k`, e.g. "katari". 41 | 42 | idsession_names 43 | ~~~~~~~~~~~~~~~ 44 | 45 | List of nouns that will make up the second part of the adjective/noun pair. 46 | 47 | The default list of nouns contain words that start with the letter `k`, 48 | e.g. "kettle". 49 | -------------------------------------------------------------------------------- /idsession.kak: -------------------------------------------------------------------------------- 1 | ## 2 | ## idsession.kak by lenormf 3 | ## Rename newly created sessions to human readable names 4 | ## 5 | 6 | declare-option -docstring "list of adjectives used to make up a session name" str-list idsession_adjectives \ 7 | "kantian" "kaput" "kashmiri" "katabolic" "katari" "kayoed" "kadenced" "kaesarian" "kaffeinic" "kalcific" "kalorific" "kancelled" "kanicular" "kanine" "kanonized" "kapable" "kapillary" "karamel" "kareful" "kasual" 8 | declare-option -docstring "list of adjectives used to make up a session name" str-list idsession_nouns \ 9 | "keeper" "keg" "kernel" "kerosene" "ketchup" "kettle" "key" "keyboard" "keyhole" "keynote" "kick" "kickoff" "kid" "kilometer" "kimono" "kingdom" "kiosk" "kit" "kitchen" "kite" "kitten" "klaxon" "knife" "knight" "knockdown" "knot" "konga" "kinesis" "kicker" "koala" "kangaroo" "kraken" 10 | 11 | define-command -docstring %{Set the session name to a human-readable composed word 12 | 13 | The current session name will be used as a seed, and is expected to be a number (default)} \ 14 | idsession %{ evaluate-commands %sh{ 15 | seed="${kak_session}" 16 | 17 | eval set -- "${kak_opt_idsession_adjectives}" 18 | 19 | if [ $# -lt 1 ]; then 20 | exit 1 21 | fi 22 | 23 | n=$((seed % $# + 1)) 24 | name_session=$(eval "printf %s \${${n}}") 25 | 26 | eval set -- "${kak_opt_idsession_nouns}" 27 | 28 | if [ $# -lt 1 ]; then 29 | exit 1 30 | fi 31 | 32 | n=$((seed % $# + 1)) 33 | name_session="${name_session}-"$(eval "printf %s \${${n}}") 34 | 35 | printf 'rename-session "%s"' $(printf %s "${name_session}" | sed 's/"/""/g') 36 | } } 37 | -------------------------------------------------------------------------------- /lineindent.asciidoc: -------------------------------------------------------------------------------- 1 | lineindent.kak 2 | ============== 3 | 4 | This script provides a way to indent a selection in relation with a 5 | remote line, be it using a relative index or an absolute line number. 6 | 7 | Commands 8 | -------- 9 | 10 | lineindent 11 | ~~~~~~~~~~ 12 | 13 | A single argument is expected by the `lineindent` function, which can 14 | take one of the following forms: 15 | 16 | - an integer, which indicates the number of the reference line, e.g. `3` 17 | - a plus sign `+` followed by an integer, which points to a specific 18 | line beneath the current selection, e.g. `+2` 19 | - a negative integer, which points to a specific line above the current 20 | selection, e.g. `-2` 21 | 22 | Once the modifier has been passed, it will be used to pinpoint the 23 | reference line, and all the lines within the current selection will be 24 | aligned with it. 25 | 26 | Example: indenting lines in a list (the last two lines are selected) 27 | 28 | ----------------------------------------------------------------------- 29 | - this is the first item of a list 30 | this line was manually indented to match the first item's indentation 31 | this line was typed after that and is part of the current selection 32 | and so is this one 33 | 34 | :lineindent -1 35 | 36 | - this is the first item of a list 37 | this line was manually indented to match the first item's indentation 38 | this line was typed after that and is part of the current selection 39 | and so is this one 40 | ----------------------------------------------------------------------- 41 | -------------------------------------------------------------------------------- /lineindent.kak: -------------------------------------------------------------------------------- 1 | ## 2 | ## lineindent.kak by lenormf 3 | ## Align a line with the previous/next, across empty ones 4 | ## 5 | 6 | define-command -params 1 \ 7 | -docstring %{lineindent : indent the current selection using a remote line as reference 8 | The offset argument is an integer that indicates the number of the reference line, but can be prefixed with the following: 9 | - '-': indent with the previous non empty line, e.g. -2 for second line above the current selection 10 | - '+': indent with the next non empty line, e.g. +3 for the third line beneath the current selection} \ 11 | lineindent %{ evaluate-commands %sh{ 12 | pattern_align='' 13 | n=$(expr "$1" : '[+-]*\([0-9]*\)') 14 | case "$1" in 15 | -[0-9]*) pattern_align="${n}^\\h*[^\\h\\n]+";; 16 | +[0-9]*) pattern_align="gl ${n}/^\\h*[^\\h\\n]+";; 17 | [0-9]*) pattern_align="${n}g";; 18 | *) exit;; 19 | esac 20 | 21 | printf %s\\n "eval -draft %{ 22 | try %{ exec \"^$giZ)${pattern_align}gia\" } 23 | }" 24 | } } 25 | -------------------------------------------------------------------------------- /overstrike.asciidoc: -------------------------------------------------------------------------------- 1 | overstrike.kak 2 | ============== 3 | 4 | This module allows overstrike formatted contents to be rendered by Kakoune in a buffer. 5 | 6 | The following environment variables will be parsed and translated into faces at parsing time: 7 | 8 | * `LESS_TERMCAP_md`: capacity used by the `less` pager to render bold text 9 | * `LESS_TERMCAP_us`: capacity used by the `less` pager to render underlined text 10 | 11 | If those variables are not exported in the environment, regular bold and underline effects will be used instead. 12 | 13 | Accentuated characters using an overstrike sequence are not supported. 14 | 15 | Commands 16 | -------- 17 | 18 | overstrike-parse 19 | ~~~~~~~~~~~~~~~~ 20 | 21 | Parse the current buffer and apply a highlighter to the current window that applies the `OverstrikeBold` and 22 | `OverstrikeUnderline` faces to the overstriken text. 23 | 24 | Note that this function isn't suited to convert big documents (> 1000 lines) at the time of writing. For reference, 25 | it takes a solid minute to render `bash`'s manpage, and around 5 minutes to render `gcc`'s. 26 | -------------------------------------------------------------------------------- /overstrike.kak: -------------------------------------------------------------------------------- 1 | ## 2 | ## overstrike.kak by lenormf 3 | ## Overstrike markup parser 4 | ## 5 | 6 | declare-option -hidden range-specs overstrike_ranges 7 | 8 | set-face global OverstrikeBold default+b 9 | set-face global OverstrikeUnderline default+u 10 | 11 | evaluate-commands %sh{ 12 | # https://en.wikipedia.org/wiki/ANSI_escape_code#Colors 13 | ansi_index_to_color() { 14 | case "${1}" in 15 | 0) echo "black";; 16 | 1) echo "red";; 17 | 2) echo "green";; 18 | 3) echo "yellow";; 19 | 4) echo "blue";; 20 | 5) echo "magenta";; 21 | 6) echo "cyan";; 22 | 7) echo "white";; 23 | *) echo "default";; 24 | esac 25 | } 26 | 27 | ansi_to_face() { 28 | capacity="$1" 29 | color_fg='default' 30 | color_bg='default' 31 | attributes='e' 32 | 33 | descriptors=$(expr "${capacity}" : '^.\[\([0-9]*\(;[0-9]*\)*\)m$') 34 | if [ $? -eq 0 ]; then 35 | # TODO: support bright colors, whenever kakoune supports them as well 36 | for code in $(printf %s "${descriptors}" | tr ';' '\n' | sed 's/ +//g'); do 37 | code=$((code)) 38 | 39 | case "${code}" in 40 | 1) attributes="${attributes}b";; 41 | 3) attributes="${attributes}i";; 42 | 4) attributes="${attributes}u";; 43 | 5) attributes="${attributes}B";; 44 | 7) attributes="${attributes}r";; 45 | 30|31|32|33|34|35|36|37) color_fg=$(ansi_index_to_color $((code - 30)));; 46 | 40|41|42|43|44|45|46|47) color_bg=$(ansi_index_to_color $((code - 40)));; 47 | *) printf 'Unsupported code: %s\n' "${code}" >&2;; 48 | esac 49 | done 50 | else 51 | printf 'Unsupported capacity format: %s\n' "${capacity}" >&2 52 | exit 1 53 | fi 54 | 55 | printf %s\\n "${color_fg},${color_bg}+${attributes}" 56 | } 57 | 58 | if [ -n "${LESS_TERMCAP_md}" ] && [ -n "${LESS_TERMCAP_us}" ]; then 59 | face_bold=$(ansi_to_face "${LESS_TERMCAP_md}") 60 | face_underline=$(ansi_to_face "${LESS_TERMCAP_us}") 61 | 62 | if [ -n "${face_bold}" ]; then 63 | printf 'set-face global OverstrikeBold "%s"\n' "${face_bold}" 64 | fi 65 | if [ -n "${face_underline}" ]; then 66 | printf 'set-face global OverstrikeUnderline "%s"\n' "${face_underline}" 67 | fi 68 | fi 69 | } 70 | 71 | define-command -hidden overstrike-parse-bold %{ 72 | eval -draft %{ 73 | try %{ 74 | exec '%1s(.\x08).d' 75 | update-option window overstrike_ranges 76 | 77 | eval -itersel %{ 78 | set -add window overstrike_ranges "%val{selection_desc}|OverstrikeBold" 79 | } 80 | } 81 | } 82 | } 83 | 84 | define-command overstrike-parse -docstring "Parse the contents of the current buffer and convert the overstrike escapes to ranges" %{ 85 | set window overstrike_ranges "%val{timestamp}" 86 | 87 | eval -draft %{ 88 | try %{ 89 | exec '%1s(_\x08).d' 90 | update-option window overstrike_ranges 91 | 92 | overstrike-parse-bold 93 | 94 | eval -itersel %{ 95 | set -add window overstrike_ranges "%val{selection_desc}|OverstrikeUnderline" 96 | } 97 | } catch %{ 98 | overstrike-parse-bold 99 | } 100 | } 101 | 102 | addhl ranges overstrike_ranges 103 | } 104 | -------------------------------------------------------------------------------- /readline.kak: -------------------------------------------------------------------------------- 1 | ## 2 | ## readline.kak by lenormf 3 | ## Readline shortcuts implemented in insert mode 4 | ## 5 | 6 | map -docstring "move the cursor one character to the left" global insert hi 7 | map -docstring "move the cursor one character to the right" global insert li 8 | map -docstring "move the cursor one word to the left" global insert b\;i 9 | map -docstring "move the cursor one word to the right" global insert e\;i 10 | map -docstring "move the cursor to the start of the line" global insert I 11 | map -docstring "move the cursor to the end of the line" global insert gli 12 | 13 | map -docstring "delete the character under the anchor" global insert c 14 | map -docstring "delete from the anchor to the start of the line" global insert Ghc 15 | map -docstring "delete from the anchor to the end of the line" global insert Glc 16 | map -docstring "delete until the next word boundary" global insert ec 17 | map -docstring "delete until the previous word boundary" global insert bc 18 | 19 | map -docstring "exchange the char before cursor with the character at cursor" global insert %{:try 'exec Ha-k>[^\n][^\n]ret>\;dp'i} 20 | map -docstring "exchange the word before cursor with the word at cursor" global insert %{:try 'exec a-k>\sret>e' catch 'exec a-i>w'BS\s+\;i} 21 | map -docstring "uppercase the current or following word" global insert ew~\;i 22 | map -docstring "lowercase the current or following word" global insert ew`\;i 23 | map -docstring "capitalize the current or following word" global insert ew\;~i 24 | 25 | map -docstring "paste after the anchor" global insert pi 26 | -------------------------------------------------------------------------------- /searchmarks.asciidoc: -------------------------------------------------------------------------------- 1 | searchmarks.kak 2 | =============== 3 | 4 | The `search-marks` command allows showing how many matches each line holds, 5 | after a search was performed. 6 | 7 | Commands 8 | -------- 9 | 10 | search-marks 11 | ~~~~~~~~~~~~ 12 | 13 | Interfacing command that takes a search primitive as first argument, which 14 | can be any of the builtin primitives (`/`, `` etc), or a custom mapping 15 | declared by the user. 16 | 17 | The command prompts the user for a pattern, which will be passed to 18 | the search primitive upon validation of the prompt, and a `flag-lines` 19 | highlighter added to the current window. 20 | 21 | If no matches result from the search, the highlighter is removed from 22 | the window. 23 | 24 | Faces 25 | ----- 26 | 27 | SearchMark 28 | ~~~~~~~~~~ 29 | 30 | Face applied to the line flags that indicate the amount of matches on the line. 31 | 32 | Example 33 | ------- 34 | 35 | The following mappings override the builtin search primitives to use the 36 | markers command interface: 37 | 38 | 39 | ``` 40 | map -docstring 'search with markers' global normal '/' %{: search-marks /} 41 | map -docstring 'backward search with markers' global normal '' %{: search-marks a-/>} 42 | map -docstring 'extend search with markers' global normal '?' %{: search-marks ?} 43 | map -docstring 'backward extend search with markers' global normal '' %{: search-marks a-?>} 44 | ``` 45 | -------------------------------------------------------------------------------- /searchmarks.kak: -------------------------------------------------------------------------------- 1 | ## 2 | ## searchmarks.kak for kakoune-extra 3 | ## by lenormf 4 | ## 5 | 6 | declare-option -hidden line-specs searchmarks_flags 7 | 8 | set-face global SearchMark LineNumbers 9 | 10 | define-command -hidden -params 2 searchmarks-impl %{ 11 | try %{ 12 | execute-keys -save-regs '' %arg{1} %arg{2} 13 | 14 | evaluate-commands -draft %{ 15 | execute-keys \%s 16 | 17 | evaluate-commands %sh{ 18 | printf %s "${kak_selections_desc}" | awk -v timestamp="${kak_timestamp}" ' 19 | { 20 | for (i = 1; i <= NF; i++) { 21 | split($i, n, /,|\./) 22 | line_begin = n[1] 23 | line_end = n[3] 24 | 25 | for (j = line_begin; j <= line_end; j++) 26 | lines[j]++ 27 | } 28 | } 29 | END{ 30 | specs = "" 31 | for (i in lines) 32 | specs = specs " " i "|{SearchMark}" lines[i] 33 | 34 | if (length(specs)) 35 | printf "set-option window searchmarks_flags %d%s", timestamp, specs 36 | } 37 | ' 38 | } 39 | } 40 | 41 | try %{ add-highlighter window/searchmarks flag-lines Default searchmarks_flags } 42 | } catch %{ 43 | remove-highlighter window/searchmarks 44 | } 45 | } 46 | 47 | define-command -params 1 -docstring %{ 48 | search-marks : Hint at search matches with markers and match counts 49 | 50 | The primitive argument is whatever key spawns a prompt, and search for a given pattern (e.g. `/`) 51 | } search-marks %{ 52 | prompt -init %reg{/} "search (%arg{1}):" "searchmarks-impl %arg{1} %%val{text}" 53 | } 54 | -------------------------------------------------------------------------------- /syntastic.asciidoc: -------------------------------------------------------------------------------- 1 | syntastic.kak 2 | ============= 3 | 4 | :syntastic-website: https://github.com/scrooloose/syntastic 5 | 6 | This script leverages the builtin `format.kak` and `lint.kak` scripts to 7 | provide automatic linting of the source code. Similarly to `vim`'s 8 | {syntastic-website}[Syntastic], the contents of a 9 | buffer will be passed to an external tool when it is saved to disk, and 10 | diagnostics will be printed on screen automatically. 11 | 12 | For a list of all the languages supported and tools used for each of 13 | them, refer to the `Languages and dependencies` section of this document. 14 | 15 | When loaded,the script will declare hooks that: 16 | 17 | - set the `formatcmd` and `lintcmd` options to default values unless 18 | they were already defined 19 | - call the `format` and `lint` functions respectively before and after 20 | the buffer has been saved 21 | 22 | Optionally, this script can also automatically format the code before 23 | writting it to the filesystem, and the commands used to either lint of 24 | format the code be customized, by setting the `syntastic_autoformat` 25 | option to `true`. 26 | 27 | Languages and dependencies 28 | -------------------------- 29 | 30 | The following languages are currently supported, and formatted/linted by 31 | the according tools: 32 | 33 | - C 34 | * format: `clang-format` 35 | * lint: `cppcheck` 36 | - C++ 37 | * format: `clang-format` 38 | * lint: `cppcheck` 39 | - D 40 | * format: `dfmt` 41 | * lint: `dscanner` 42 | - Go 43 | * format: `gofmt` 44 | * lint: `gometalinter` 45 | - Python 46 | * format: `autopep8` 47 | * lint: `pyflakes` 48 | - Shell 49 | * format: 50 | * lint: `shellcheck` 51 | 52 | Variables 53 | --------- 54 | 55 | syntastic_autoformat 56 | ~~~~~~~~~~~~~~~~~~~~ 57 | 58 | Boolean that enables auto-formatting of a buffer's contents when set to 59 | `true`. Formatting is done before the buffer is actually saved to the 60 | disk. 61 | 62 | Functions 63 | --------- 64 | 65 | syntastic-declare-filetype 66 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 67 | 68 | The `syntastic-declare-filetype` function allows buffers with a 69 | specific `filetype` to be automatically linted, and formatted if the 70 | according option allows it. 71 | 72 | The arguments passed to the function are, respectively: 73 | 74 | - the Kakoune `filetype` of the buffers that need to be parsed on write 75 | - the command to execute to lint the buffer (c.f. the `lintcmd` option) 76 | - the command to execute to format the buffer (c.f. the `formatcmd` 77 | option) 78 | 79 | As formatting buffers automatically can be disabled, the third argument 80 | is optional and can be ignored when using this function. However, if an 81 | empty string is passed as formatting command and auto formatting is 82 | enabled, then the default `formatcmd` will be used. 83 | 84 | Examples 85 | -------- 86 | 87 | Seamless use with the default settings 88 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 89 | 90 | Once the script has been loaded, the buffer will automatically be 91 | checked when it's saved with the `write` command, granted that the 92 | current `filetype` is one of the languages supported and that the 93 | default format or lint utility is installed. 94 | 95 | If for some reason you do not want the current buffer to be parsed, you 96 | can disable hooks temporarily with the following command: 97 | 98 | -------------------- 99 | eval -no-hooks write 100 | -------------------- 101 | 102 | Overriding a default command 103 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 104 | 105 | Every time the buffer is saved, a hook set by this script at load time 106 | will activate and verify that the `formatcmd` and `lintcmd` options have 107 | a variable assigned. If not (e.g. they are empty), then the default 108 | command defined internally will be assigned to the option, and executed. 109 | 110 | To override a default command permanently, define the corresponding option 111 | mentioned previously in your configuration file (`~/.config/kak/kakrc` 112 | by default). 113 | 114 | To override a default comment temporarily, set the corresponding option 115 | mentioned previously manually, write the buffer and set empty out the 116 | same variable to let the script fill it again with a default on the next 117 | save. 118 | 119 | Example: 120 | 121 | ----------------------------------- 122 | set window lintcmd "linter command" 123 | write 124 | set window lintcmd "" 125 | ----------------------------------- 126 | 127 | Declaring a filetype 128 | ~~~~~~~~~~~~~~~~~~~~ 129 | 130 | It's possible to benefit from the same features provided to buffers 131 | whose `filetype` is officially supported with custom filetypes, by 132 | simply calling the `syntastic-declare-filetype` function in the main 133 | configuration file (`~/.config/kak/kakrc`). 134 | 135 | Example: support for automatic linting of `puppet` buffers, no 136 | formatting 137 | 138 | ---------------------------------------------------------------------------------------------- 139 | syntastic-declare-filetype "puppet" \ 140 | 'puppet-lint --log-format "%{filename}:%{line}:%{column}: %{kind}: %{message} [%{check}]"' 141 | ---------------------------------------------------------------------------------------------- 142 | -------------------------------------------------------------------------------- /syntastic.kak: -------------------------------------------------------------------------------- 1 | ## 2 | ## syntastic.kak by lenormf 3 | ## Auto lint (and optionally format) your code on write 4 | ## 5 | 6 | declare-option -docstring "format the buffer on save" \ 7 | bool syntastic_autoformat no 8 | 9 | define-command -params 2..3 \ 10 | -docstring %{syntastic-declare-filetype : automatically lint and/or format buffers on write} \ 11 | syntastic-declare-filetype %{ evaluate-commands %sh{ 12 | readonly filetype="$1" 13 | 14 | printf 'hook global WinSetOption filetype=%s %%{\n' "${filetype}" 15 | 16 | if [ $# -gt 2 ] && [ -n "$3" ]; then 17 | printf 'hook buffer BufWritePre "\Q%%val{buffile}" %%{ eval %%sh{ 18 | if [ "${kak_opt_syntastic_autoformat}" = true ]; then 19 | if [ -z "${kak_opt_formatcmd}" ]; then 20 | printf "set buffer formatcmd \\"%%s\\"\\\\n" "%s" 21 | fi 22 | echo format 23 | fi 24 | } }\n' "$(printf %s "$3" | sed -e 's/\([%"]\)/\1\1/g' -e 's/"/\\"/g')" 25 | fi 26 | 27 | ## FIXME: try isn't the good solution, this has to be executed only once 28 | echo ' 29 | try %{ lint-enable } 30 | hook buffer BufWritePost "\Q%val{buffile}" %{ 31 | ' 32 | 33 | if [ -n "$2" ]; then 34 | printf 'eval %%sh{ 35 | if [ -z "${kak_opt_lintcmd}" ]; then 36 | printf "set window lintcmd \\"%%s\\"\\\\n" "%s" 37 | fi 38 | }\n' "$(printf %s "$2" | sed -e 's/\([%"]\)/\1\1/g' -e 's/"/\\"/g')" 39 | fi 40 | 41 | echo 'lint } }' 42 | } } 43 | 44 | syntastic-declare-filetype "c" \ 45 | 'cppcheck --language=c --enable=all --template="{file}:{line}:1: {severity}: {message}" 2>&1' \ 46 | 'clang-format' 47 | 48 | syntastic-declare-filetype "cpp" \ 49 | 'cppcheck --language=c++ --enable=all --template="{file}:{line}:1: {severity}: {message}" 2>&1' \ 50 | 'clang-format' 51 | 52 | ## FIXME: `dscanner` doesn't allow formatting the output yet 53 | syntastic-declare-filetype "d" \ 54 | 'dscanner -S' \ 55 | 'dfmt' 56 | 57 | ## FIXME: `gometalinter` only takes directories as argument, create a wrapper 58 | syntastic-declare-filetype "go" \ 59 | 'gometalinter' \ 60 | 'gofmt -e -s' 61 | 62 | ## NOTE: ignore all default errors/warnings documented in the man page, plus lines too long (E501) 63 | syntastic-declare-filetype "python" \ 64 | 'flake8 --filename=* --format="%(path)s:%(row)d:%(col)d: error: %(text)s" --ignore=E121,E123,E126,E226,E24,E704,W503,W504,E501' \ 65 | 'autopep8 -' 66 | 67 | syntastic-declare-filetype "sh" \ 68 | 'shellcheck -fgcc -Cnever' 69 | -------------------------------------------------------------------------------- /tldr.asciidoc: -------------------------------------------------------------------------------- 1 | tldr.kak 2 | ======== 3 | 4 | Utility that fetches pages from the [tldr](https://github.com/tldr-pages/tldr) documentation. 5 | 6 | Pages are not cached, they are fetched every time the `tldr` command is executed. 7 | 8 | Commands 9 | -------- 10 | 11 | tldr 12 | ~~~~ 13 | 14 | Open a new scratch buffer containing a TL;DR page in markdown format. The 15 | first argument is the name of the command whose documentation page is to 16 | be downloaded. The second argument is optional and automatically detected 17 | if omitted, but can otherwise be one of the following: 18 | 19 | * osx 20 | * linux 21 | * sunos 22 | * common 23 | -------------------------------------------------------------------------------- /tldr.kak: -------------------------------------------------------------------------------- 1 | declare-option -hidden str tldr_index_url "http://tldr.sh/assets/index.json" 2 | declare-option -hidden str tldr_page_url "https://raw.githubusercontent.com/tldr-pages/tldr/master/pages" 3 | 4 | define-command -hidden -params 2 tldr-open %{ 5 | edit! -scratch "*tldr:%arg{1}*" 6 | set-option buffer filetype markdown 7 | execute-keys \%d "!curl -sL '%opt{tldr_page_url}/%arg{2}/%arg{1}.md'" 8 | } 9 | 10 | define-command -params 1..2 -shell-script-candidates %{ 11 | curl -sL "${kak_opt_tldr_index_url}" | jq -r '.commands[] | .name' 12 | } -docstring %{ 13 | tldr [platform]: open a new buffer with a TL;DR for the given command 14 | 15 | The optional platform argument can be one of the following: 16 | - osx 17 | - linux 18 | - sunos 19 | - common 20 | } tldr %{ evaluate-commands %sh{ 21 | command="$1" 22 | 23 | if [ $# -lt 2 ]; then 24 | case $(uname -s) in 25 | Darwin) platform="osx";; 26 | Linux) platform="linux";; 27 | SunOS) platform="sunos";; 28 | *) platform="common";; 29 | esac 30 | 31 | curl -sL "${kak_opt_tldr_index_url}" \ 32 | | jq -r --arg command "${command}" '.commands[] | select(.name==$command) | .platform[]' \ 33 | | while read -r p; do 34 | printf 'tldr-open "%s" "%s"\n' "${command}" "${p}" 35 | done 36 | else 37 | platform="$2" 38 | if ! expr "${platform}" : '\(osx\|linux\|sunos\|common\)$' >/dev/null; then 39 | echo 'echo -markup {Error}Unsupported platform' 40 | exit 1 41 | else 42 | printf 'tldr-open "%s" "%s"\n' "${command}" "${platform}" 43 | fi 44 | fi 45 | } } 46 | -------------------------------------------------------------------------------- /utils.kak: -------------------------------------------------------------------------------- 1 | ## 2 | ## utils.kak by lenormf 3 | ## 4 | 5 | define-command -params 4.. -file-completion \ 6 | -docstring %{find-parent-file : assign to a given variable the full path of a file, looked for upwards from a given path 7 | The dirs parameter is a list of one or more directories which the function will traverse in order} \ 8 | find-parent-file %{ evaluate-commands %sh{ 9 | filename="$1" 10 | variable="${2#*:}" 11 | variable_scope="${2%%:*}" 12 | maxdepth="$3" 13 | 14 | shift 3 15 | 16 | function fatal { 17 | printf %s\\n "echo -color Error %{$@}" 18 | exit 1 19 | } 20 | 21 | ## FIXME: backup the old value in the variable, and restore it after looking up the file 22 | printf %s\\n "set '${variable_scope}' '${variable}' ''" 23 | if [ -z "${filename}" ]; then 24 | fatal "first argument: filename needed" 25 | elif [ -z "${variable}" ] || ! echo "window buffer global current" | grep -qiw "${variable_scope}"; then 26 | fatal "second argument: syntax expected: \"scope:name\"" 27 | elif ! [[ $maxdepth =~ [0-9]+ ]]; then 28 | fatal "third argument: maximum depth of recursion needed" 29 | fi 30 | 31 | for basedir in "$@"; do 32 | if [ ! -d "${basedir}" ]; then 33 | fatal "no such directory: \"${basedir}\"" 34 | fi 35 | 36 | n_depth=0 37 | while true; do 38 | n_depth=$((n_depth + 1)) 39 | current_path=$(readlink -e "${basedir}/${filename}") 40 | 41 | if [ -f "${basedir}/${filename}" ]; then 42 | printf %s\\n "set '${variable_scope}' '${variable}' '${current_path}'" 43 | exit 44 | elif [ "${basedir}" = / ]; then 45 | break 46 | elif [ "${n_depth}" -ge "${maxdepth}" ] && [ "${maxdepth}" -gt 0 ]; then 47 | break 48 | fi 49 | 50 | basedir="${basedir}/.." 51 | done 52 | done 53 | } } 54 | -------------------------------------------------------------------------------- /vcs.asciidoc: -------------------------------------------------------------------------------- 1 | vcs.kak 2 | ======= 3 | 4 | Auto-detect and store the path to the root of the current repository, if any. 5 | 6 | When a new buffer is created/opened, the script will try to use the following 7 | Version Control Systems, on after the other: 8 | 9 | * `git` 10 | * `svn` 11 | * `hg` 12 | * `bzr` 13 | 14 | As soon as a VCS returns a path, indicating that the current buffer was 15 | created within a repository, the variable below is set. 16 | 17 | Variables 18 | --------- 19 | 20 | vcs_name 21 | ~~~~~~~~ 22 | 23 | String holding the name of the VCS detected. Can be one of: 24 | 25 | * `git` 26 | * `svn` 27 | * `mercurial` 28 | * `bazaar` 29 | 30 | vcs_root_path 31 | ~~~~~~~~~~~~~ 32 | 33 | String containing the path to the repository in which the current buffer 34 | was created. This variable only has a value set in the `buffer` scope. 35 | 36 | After the script has been loaded, one could use it in subsequent hooks to 37 | apply project-wide settings (c.f. example below). 38 | 39 | Examples 40 | -------- 41 | 42 | Auto-detecting root `tags` files 43 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 44 | 45 | Adding a `tags` file (for use with the builtin `ctags` support script) 46 | to the `ctagsfiles` option, on buffer creation: 47 | 48 | ```sh 49 | hook global BufCreate .* %{ 50 | %sh{ 51 | if [ -e "${kak_opt_vcs_root_path}/tags" ]; then 52 | printf 'set-option -add buffer ctagsfiles %%{%s}\n' "${kak_opt_vcs_root_path}/tags" 53 | fi 54 | } 55 | } 56 | ``` 57 | 58 | Highlighting `git` changes 59 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 60 | 61 | Highlighting with a flag the lines that were changed, in a buffer, since 62 | the last `git` commit: 63 | 64 | ```sh 65 | hook global WinCreate .* %{ evaluate-commands %sh{ 66 | if [ -n "${kak_opt_vcs_root_path}" ]; then 67 | case "${kak_opt_vcs_name}" in 68 | git) 69 | echo " 70 | git show-diff 71 | hook global BufWritePost %val{buffile} %{git update-diff} 72 | hook global BufReload %val{buffile} %{git update-diff} 73 | hook global WinDisplay %val{buffile} %{git update-diff} 74 | ";; 75 | esac 76 | fi 77 | } } 78 | ``` 79 | -------------------------------------------------------------------------------- /vcs.kak: -------------------------------------------------------------------------------- 1 | ## 2 | ## vcs.kak by lenormf 3 | ## Auto-detect the path to the root of the current repository 4 | ## 5 | 6 | declare-option -docstring "name of the VCS detected" str vcs_name 7 | declare-option -docstring "path to the root of the current versioned project" str vcs_root_path 8 | 9 | hook global BufCreate .* %{ evaluate-commands %sh{ 10 | for cmd in "git:git rev-parse --show-toplevel" \ 11 | "svn:svn info | awk '/Working Copy Root Path:/ { print substr($0, 25); }'" \ 12 | "mercurial:hg root" \ 13 | "bazaar:bzr root" 14 | do 15 | cd "${kak_buffile%/*}" 2>/dev/null || continue 16 | 17 | name="${cmd%%:*}" 18 | cmd="${cmd#*:}" 19 | path=$(eval "${cmd}" 2>/dev/null) 20 | if [ -n "${path}" ]; then 21 | printf ' 22 | set-option buffer vcs_name %%{%s} 23 | set-option buffer vcs_root_path %%{%s} 24 | ' "${name}" "${path}" 25 | break 26 | fi 27 | done 28 | } } 29 | -------------------------------------------------------------------------------- /versioncheck.asciidoc: -------------------------------------------------------------------------------- 1 | versioncheck.kak 2 | ================ 3 | 4 | When the editor starts, a hook fetches the version number of the latest 5 | stable release on Github, and compares it with the local version of the 6 | running instance. 7 | 8 | The state of the comparison is printed on the debug buffer, along with 9 | context information: whether the local instance is up to date, its version, 10 | the upstream stable version etc. 11 | 12 | A development version is always considered up-to-date with its associated 13 | stable, e.g. `v2018.09.04-65-gdbfed130` is considered aligned with 14 | `v2018.09.04`. 15 | 16 | Example output: 17 | 18 | ``` 19 | Local version: v2018.09.04-65-gdbfed130 20 | Upstream version: v2018.09.04 21 | Up to date 22 | ``` 23 | -------------------------------------------------------------------------------- /versioncheck.kak: -------------------------------------------------------------------------------- 1 | ## 2 | ## versioncheck.kak for kakoune-extra 3 | ## by lenormf 4 | ## 5 | 6 | hook global KakBegin .* %{ evaluate-commands %sh{ 7 | upstream_version=$(curl -si 'https://github.com/mawww/kakoune/releases/latest' \ 8 | | awk -F/ '/^Location:/{ print $NF; }' \ 9 | | sed 's/.$//') 10 | version="${kak_version}" 11 | 12 | printf ' 13 | echo -debug Local version: %s 14 | echo -debug Upstream version: %s 15 | ' "${version}" "${upstream_version}" 16 | 17 | if [ ${#version} -gt ${#upstream_version} ]; then 18 | version="${version%%-*}" 19 | fi 20 | 21 | version=$(printf %s "${version}" | sed 's/^v\|\.//g') 22 | upstream_version=$(printf %s "${upstream_version}" | sed 's/^v\|\.//g') 23 | 24 | if [ "${upstream_version}" -gt "${version}" ]; then 25 | echo 'echo -debug A new version is available' 26 | else 27 | echo 'echo -debug Up to date' 28 | fi 29 | } } 30 | -------------------------------------------------------------------------------- /widgets/git-branch.kak: -------------------------------------------------------------------------------- 1 | ## 2 | ## git-branch.kak by lenormf 3 | ## Store the current git branch that contains the buffer 4 | ## 5 | 6 | declare-option -docstring "name of the git branch holding the current buffer" \ 7 | str modeline_git_branch 8 | 9 | hook global WinCreate .* %{ 10 | hook window NormalIdle .* %{ evaluate-commands %sh{ 11 | branch=$(cd "$(dirname "${kak_buffile}")" && git rev-parse --abbrev-ref HEAD 2>/dev/null) 12 | if [ -n "${branch}" ]; then 13 | printf 'set window modeline_git_branch %%{%s}' "${branch}" 14 | fi 15 | } } 16 | } 17 | -------------------------------------------------------------------------------- /widgets/percent.kak: -------------------------------------------------------------------------------- 1 | ## 2 | ## percent.kak by lenormf 3 | ## Compute and store the relative position of the cursor in percent 4 | ## 5 | 6 | ## position of the cursor in the buffer, in percent 7 | declare-option str modeline_pos_percent 8 | 9 | hook global WinCreate .* %{ 10 | hook window NormalIdle .* %{ evaluate-commands %sh{ 11 | echo "set window modeline_pos_percent '$(($kak_cursor_line * 100 / $kak_buf_line_count))'" 12 | } } 13 | } 14 | --------------------------------------------------------------------------------