pax_global_header00006660000000000000000000000064135063736010014516gustar00rootroot0000000000000052 comment=2ff9fd8d9262e9fd1361dd2c0e873277aabad663 kakoune-2019.07.01/000077500000000000000000000000001350637360100135545ustar00rootroot00000000000000kakoune-2019.07.01/.github/000077500000000000000000000000001350637360100151145ustar00rootroot00000000000000kakoune-2019.07.01/.github/issue_template.md000066400000000000000000000006151350637360100204630ustar00rootroot00000000000000 ### Steps ### Outcome ### Expected kakoune-2019.07.01/.gitignore000066400000000000000000000002051350637360100155410ustar00rootroot00000000000000*.o .*.d *.pyc *.1-r .*.kak.* src/kak src/kak.debug src/kak.opt src/.version* doc/kak.1.gz doc/manpages/*.gz tags GPATH GRTAGS GTAGS kakoune-2019.07.01/.travis.yml000066400000000000000000000015341350637360100156700ustar00rootroot00000000000000language: cpp sudo: false os: - linux - osx osx_image: xcode10.1 compiler: - clang - gcc env: global: - secure: "R+NxqtytOslIcQ/eCbLoZhImsgYdJnljfjANdieFQGune9ACPPQL0YanXkF49c9SWGBSxrAcute0egQzv2CU2+ivSQIX/xnMebKHiOmSPYBoxX+VgxLT3U1itUYlpYwixo9rF8UnGdlgXid6oENSiCvfWtNKoM2qOL0Ttw31J9E=" before_install: if [ "$CXX" = "g++" ]; then export CXX=g++-7; fi addons: apt: sources: - ubuntu-toolchain-r-test packages: - libstdc++-7-dev - g++-7 - libncursesw5-dev homebrew: update: true packages: gcc@7 coverity_scan: project: name: "mawww/kakoune" description: "Build submitted via Travis CI" notification_email: frrrwww@gmail.com build_command_prepend: "cd src && make clean" build_command: "make -j4" branch_pattern: coverity-scan script: cd src && make && make test kakoune-2019.07.01/CHANGELOG000077700000000000000000000000001350637360100222542doc/pages/changelog.asciidocustar00rootroot00000000000000kakoune-2019.07.01/CONTRIBUTING000066400000000000000000000012531350637360100154070ustar00rootroot00000000000000The preferred way to contribute would be through GitHub pull requests, as an alternative patches can be discussed on the IRC channel. When contributing your first changes, please include an empty commit for copyright waiver using the following message (replace 'John Doe' with your name or nickname): John Doe Copyright Waiver I dedicate any and all copyright interest in this software to the public domain. I make this dedication for the benefit of the public at large and to the detriment of my heirs and successors. I intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. kakoune-2019.07.01/README.asciidoc000066400000000000000000000651641350637360100162250ustar00rootroot00000000000000= image:{logo}[K,30,30,link="{website}",title="Kakoune logo by p0nce"] Kakoune image:{travis-img}[link="{travis-url}"] image:{irc-img}[link="{irc-url}"] ifdef::env-github,env-browser[:outfilesuffix: .asciidoc] :logo: https://rawgit.com/mawww/kakoune/master/doc/kakoune_logo.svg :website: http://kakoune.org :travis-img: https://travis-ci.org/mawww/kakoune.svg?branch=master :travis-url: https://travis-ci.org/mawww/kakoune :irc-img: https://img.shields.io/badge/IRC-%23kakoune-blue.svg :irc-url: https://webchat.freenode.net/?channels=kakoune :icons: font :toc: right :pp: ++ TL;DR ----- {website} *Modal editor* -- *Faster as in fewer keystrokes* -- *Multiple selections* -- *Orthogonal design* --------------------------------------------- git clone http://github.com/mawww/kakoune.git cd kakoune/src make ./kak --------------------------------------------- See http://github.com/mawww/golf for kakoune solutions to vimgolf challenges, regularly beating the best Vim solution. See the link:doc/design.asciidoc[design document] for more information on Kakoune philosophy and design. :numbered: Introduction ------------ Kakoune is a code editor that implements Vi's "keystrokes as a text editing language" model. As it's also a modal editor, it is somewhat similar to the Vim editor (after which Kakoune was originally inspired). Kakoune can operate in two modes, normal and insertion. In insertion mode, keys are directly inserted into the current buffer. In normal mode, keys are used to manipulate the current selection and to enter insertion mode. Kakoune has a strong focus on interactivity, most commands provide immediate and incremental results, while still being competitive (as in keystroke count) with Vim. Kakoune works on selections, which are oriented, inclusive range of characters, selections have an anchor and a cursor character. Most commands move both of them, except when extending selection where the anchor character stays fixed and the cursor one moves around. See http://vimeo.com/82711574 Join us on freenode IRC `#Kakoune` Features ~~~~~~~~ * Multiple selections as a central way of interacting * Powerful selection manipulation primitives - Select all regex matches in current selections - Keep selections containing/not containing a match for a given regex - Split current selections with a regex - Text objects (paragraph, sentence, nestable blocks) * Powerful text manipulation primitives - Align selections - Rotate selection contents - Case manipulation - Indentation - Piping each selection to external filter * Client-Server architecture - Multiple clients on the same editing session - Use tmux or your X11 window manager to manage windows * Simple interaction with external programs * Automatic contextual help * Automatic as you type completion * Macros * Hooks * Syntax Highlighting - Supports multiple languages in the same buffer - Highlight a buffer differently in different windows Screenshots ~~~~~~~~~~~ [[screenshot-i3]] .Kakoune in i3 image::doc/screenshot-i3.gif[Kakoune in i3] [[screenshot-tmux]] .Kakoune in tmux image::doc/screenshot-tmux.gif[Kakoune in tmux] Getting started --------------- Building ~~~~~~~~ Kakoune dependencies are: * A {cpp}17 compliant compiler (GCC >= 7 or clang >= 5) along with its associated {cpp} standard library (libstdc{pp} or libc{pp}) * ncurses with wide-characters support (>= 5.3, generally referred to as libncursesw) To build, just type *make* in the src directory. To generate man pages, type *make man* in the src directory. Kakoune can be built on Linux, MacOS, and Cygwin. Due to Kakoune relying heavily on being in a Unix-like environment, no native Windows version is planned. Installing ~~~~~~~~~~ In order to install kak on your system, rather than running it directly from its source directory, type *make install*, you can specify the `PREFIX` and `DESTDIR` if needed. [TIP] .Homebrew (macOS) or Linuxbrew ==== --------------------------------- brew install kakoune --------------------------------- ==== [TIP] .Fedora supported versions and Rawhide ==== Use the https://copr.fedoraproject.org/coprs/jkonecny/kakoune/[copr] repository. --------------------------------- dnf copr enable jkonecny/kakoune dnf install kakoune --------------------------------- ==== [TIP] .Arch Linux ==== Kakoune is found in the https://www.archlinux.org/packages/community/x86_64/kakoune/[repositories]. -------------------------------------------------- pacman -S kakoune -------------------------------------------------- ==== [TIP] .Gentoo ==== Kakoune is found in portage as https://packages.gentoo.org/packages/app-editors/kakoune[app-editors/kakoune] ==== [TIP] .Exherbo ==== -------------------------------- cave resolve -x repository/mawww cave resolve -x kakoune -------------------------------- ==== [TIP] .openSUSE ==== kakoune can be found in the https://build.opensuse.org/package/show/editors/kakoune[editors] devel project. Make sure to adjust the link below to point to the repository of your openSUSE version. --------------------------------------------------------------------------------------------------- #Example for Tumbleweed: sudo zypper addrepo http://download.opensuse.org/repositories/editors/openSUSE_Factory/editors.repo sudo zypper refresh sudo zypper install kakoune --------------------------------------------------------------------------------------------------- ==== [TIP] .Ubuntu ==== Building on Ubuntu 16.04. Make sure you have .local/bin in your path to make the kak binary available from your shell. ---------------------------------------------------------------- sudo apt install libncursesw5-dev pkg-config git clone https://github.com/mawww/kakoune.git && cd kakoune/src make PREFIX=$HOME/.local make install ---------------------------------------------------------------- ==== [TIP] .FreeBSD ==== Kakoune is available in the official ports tree as https://www.freshports.org/editors/kakoune[editors/kakoune]. A binary package is also available and can be installed with -------------------------------------------------- pkg install kakoune -------------------------------------------------- ==== [TIP] .Solus ==== Kakoune is available in the Solus stable repository. It can be installed with --------------------- eopkg install kakoune --------------------- ==== [TIP] .Void ==== Kakoune is available in the repositories. It can be installed with ----------------------- xbps-install -S kakoune ----------------------- ==== [TIP] .Termux ==== Kakoune is available in the repositories. It can be installed with ------------------- pkg install kakoune ------------------- ==== Running ~~~~~~~ Just running *kak* launches a new kak session with a client on local terminal. Run *kak -help* to discover the valid command line flags. Configuration ^^^^^^^^^^^^^ There are two directories containing Kakoune's scripts: * `runtime`: located in `../share/kak/` relative to the `kak` binary contains the system scripts, installed with Kakoune. * `userconf`: located in `$XDG_CONFIG_HOME/kak/`, which will fallback to `$HOME/.config/kak/` if `$XDG_CONFIG_HOME` is not set, containing the user configuration. Unless `-n` is specified, Kakoune will load its startup script located at `${runtime}/kakrc` relative to the `kak` binary. This startup script is responsible for loading the user configuration. First, Kakoune will search recursively for `.kak` files in the `autoload` directory. It will first look for an `autoload` directory at `${userconf}/autoload` and will fallback to `${runtime}/autoload` if it does not exist. Once all those files are loaded, Kakoune will try to source `${runtime}/kakrc.local` which is expected to contain distribution provided configuration. And finally, the user configuration will be loaded from `${userconf}/kakrc`. NOTE: If you create a user `autoload` directory in `${userconf}/autoload`, the system one at `${runtime}/autoload` will not be loaded anymore. You can add a symbolic link to it (or to individual scripts) inside `${userconf}/autoload` to keep loading system scripts. Basic Interaction ----------------- Selections ~~~~~~~~~~ The main concept in Kakoune is the selection. A selection is an inclusive, directed range of character. A selection has two ends, the anchor and the cursor. There is always at least one selection, and a selection is always at least one character (in which case the anchor and cursor of the selections are on the same character). Normal Mode ~~~~~~~~~~~ In normal mode, keys are not inserted directly inside the buffer, but are editing commands. These commands provide ways to manipulate either the selections themselves, or the selected text. Insert Mode ~~~~~~~~~~~ When entering insert mode, keys are now directly inserted before each selection's cursor. Some additional keys are recognised in insert mode: * ``: leave insert mode * ``: delete characters before cursors * ``: delete characters under cursors * `, , , `: move the cursors in given direction * ``: move cursors to line begin * ``: move cursors to end of line * ``: select next completion candidate * ``: select previous completion candidate * ``: explicit insert completion query, followed by: - `f`: explicit file completion - `w`: explicit word completion - `l`: explicit line completion * ``: disable automatic completion for this insert session * ``: insert contents of the register given by next key * ``: insert next keystroke directly into the buffer, without interpreting it. * ``: commit changes up to now as a single undo group. * ``: escape to normal mode for a single command Movement ~~~~~~~~ See <> below for instructions on extending (appending to) the current selection, in order to select more text in multiple steps. * `h`: select the character on the left of selection end * `j`: select the character below the selection end * `k`: select the character above the selection end * `l`: select the character on the right of selection end * `w`: select the word and following whitespaces on the right of selection end * `b`: select preceding whitespaces and the word on the left of selection end * `e`: select preceding whitespaces and the word on the right of selection end * ``: same as [wbe] but select WORD instead of word * `f`: select to (including) the next occurrence of the given character * `t`: select until (excluding) the next occurrence of the given character * ``: same as [ft] but in the other direction * `m`: select to matching character * `M`: extend selection to matching character * `x`: select line on which selection end lies (or next line when end lies on an end-of-line) * `X`: similar to `x`, except the current selection is extended * ``: expand selections to contain full lines (including end-of-lines) * ``: trim selections to only contain full lines (not including last end-of-line) * `%`: select whole buffer * ``: select to line begin * ``: select to line end * `/`: search (select next match) * ``: search (select previous match) * `?`: search (extend to next match) * ``: search (extend to previous match) * `n`: select next match * `N`: add a new selection with next match * ``: select previous match * ``: add a new selection with previous match * `pageup, `: scroll one page up * `pagedown, `: scroll one page down * ``: scroll half a page up * ``: scroll half a page down * `)`: rotate selections (the main selection becomes the next one) * `(`: rotate selections backwards * `;`: reduce selections to their cursor * ``: flip the selections' direction * ``: ensure selections are in forward direction (cursor after anchor) * ``: repeat last object or `f`/`t` selection command. * `_`: trim selections A word is a sequence of alphanumeric characters or underscore, a WORD is a sequence of non whitespace characters. Appending ~~~~~~~~~ For most <> commands, using `Shift` extends the current selection instead of replacing it. Examples: * `wWW` selects 3 consecutive words: first `w` selects a word, then `WW` extends the selection two words further. * `f/F/` selects up to and including the second `/` character forward. Using Counts ~~~~~~~~~~~~ Most selection commands also support counts, which are entered before the command itself. For example, `3W` selects 3 consecutive words and `3w` select the third word on the right of selection end. Disabling Hooks ~~~~~~~~~~~~~~~ Any normal mode command can be prefixed with `\` which will disable hook execution for the duration for the command (including the duration of modes the command could move to, so `\i` will disable hooks for the whole insert session). As autoindentation is implemented in terms of hooks, this can be used to disable it when pasting text. Changes ~~~~~~~ * `i`: enter insert mode before current selection * `a`: enter insert mode after current selection * `d`: yank and delete current selection * `c`: yank and delete current selection and enter insert mode * `.`: repeat last insert mode change (`i`, `a`, or `c`, including the inserted text) * ``: delete current selection * ``: delete current selection and enter insert mode * `I`: enter insert mode at current selection begin line start * `A`: enter insert mode at current selection end line end * `o`: enter insert mode in one (or given count) new lines below current selection end * `O`: enter insert mode in one (or given count) new lines above current selection begin * ``: add an empty line below cursor * ``: add an empty line above cursor * `y`: yank selections * `p`: paste after current selection end * `P`: paste before current selection begin * ``: paste all after current selection end, and select each pasted string. * ``: paste all before current selection begin, and select each pasted string. * `R`: replace current selection with yanked text * ``: replace current selection with every yanked text * `r`: replace each character with the next entered one * ``: join selected lines * ``: join selected lines and select spaces inserted in place of line breaks * ``: merge contiguous selections together (works across lines as well) * ` (>)`: indent selected lines * ``: indent selected lines, including empty lines * ` (<)`: deindent selected lines * ``: deindent selected lines, do not remove incomplete indent (3 leading spaces when indent is 4) * `|`: pipe each selection through the given external filter program and replace the selection with it's output. * ``: pipe each selection through the given external filter program and ignore its output * `!`: insert command output before selection * ``: append command output after selection * `u`: undo last change * ``: move backward in history * `U`: redo last change * ``: move forward in history * `&`: align selection, align the cursor of selections by inserting spaces before the first character of the selection * ``: copy indent, copy the indentation of the main selection (or the count one if a count is given) to all other ones * ```: to lower case * `~`: to upper case * ````: swap case * `@`: convert tabs to spaces in current selections, uses the buffer tabstop option or the count parameter for tabstop. * ``: convert spaces to tabs in current selections, uses the buffer tabstop option or the count parameter for tabstop. * ``: rotate selections content, if specified, the count groups selections, so `3` rotate (1, 2, 3) and (3, 4, 6) independently. * ``: rotate selections content backwards Goto Commands ~~~~~~~~~~~~~ Commands beginning with `g` are used to goto certain position and or buffer. If a count is given prior to hitting `g`, `g` will jump to the given line. Using `G` will extend the selection rather than jump. See <>. View commands ~~~~~~~~~~~~~ Commands beginning with `v` permit to center or scroll the current view. Using `V` will lock view mode until `` is hit See <>. Marks ~~~~~ Current selections position can be saved in a register and restored later on. See <>. Jump list ~~~~~~~~~ Some commands, like the goto commands, buffer switch or search commands, push the previous selections to the client's jump list. See <>. Multi Selection ~~~~~~~~~~~~~~~ Kak was designed from the start to handle multiple selections. One way to get a multiselection is via the `s` key. For example, to change all occurrences of word 'roger' to word 'marcel' in a paragraph, here is what can be done: * select the paragraph with enough `x` * press `s` and enter roger, then enter * now paragraph selection was replaced with multiselection of each roger in the paragraph * press `c` and marcel to replace rogers with marcels A multiselection can also be obtained with `S`, which splits the current selection according to the regex entered. To split a comma separated list, use `S` then ', *' The regex syntax supported by Kakoune is the based on the ECMAScript script syntax and is described at <>. `s` and `S` share the search pattern with `/`, and hence entering an empty pattern uses the last one. As a convenience, `` allows you to split the current selections on line boundaries. To clear multiple selections, use `space`. To keep only the nth selection use `n` followed by `space`, in order to remove a selection, use ``. `` allows you to enter a regex and keep only the selections that contains a match for this regex. Using `` you can keep the selections not containing a match. `C` copies the current selection to the next line (or lines if a count is given) `` does the same to previous lines. `$` allows you to enter a shell command and pipe each selection to it. Selections whose shell command returns 0 will be kept, other will be dropped. Object Selection ~~~~~~~~~~~~~~~~ Objects are specific portions of text, like sentences, paragraphs, numbers… Kakoune offers many keys allowing you to select various text objects. See <>. Commands -------- When pressing `:` in normal mode, Kakoune will open a prompt to enter a command. Commands are used for non editing tasks, such as opening a buffer, writing the current one, quitting, etc. See <>. Basic Commands ~~~~~~~~~~~~~~ Some commands take an exclamation mark (`!`), which can be used to force the execution of the command (i.e. to quit a modified buffer, the command `q!` has to be used). Commands starting with horizontal whitespace (e.g. a space) will not be saved in the command history. * `cd []`: change the current directory to ``, or the home directory if unspecified * `doc `: display documentation about a topic. The completion list displays the available topics. * `e[dit][!] [ []]`: open buffer on file, go to given line and column. If file is already opened, just switch to this file. Use edit! to force reloading. * `w[rite][!] []`: write buffer to or use its name if filename is not given. If the file is write-protected, its permissions are temporarily changed to allow saving the buffer and restored afterwards when the write! command is used. * `w[rite]a[ll]`: write all buffers that are associated to a file. * `q[uit][!] []`: exit Kakoune, use quit! to force quitting even if there is some unsaved buffers remaining. If specified, the client exit status will be set to . * `w[a]q[!] []`: write the current buffer (or all buffers when `waq` is used) and quit. If specified, the client exit status will be set to . * `kill[!]`: terminate the current session, all the clients as well as the server, use kill! to ignore unsaved buffers * `b[uffer] `: switch to buffer * `b[uffer]n[ext]`: switch to the next buffer * `b[uffer]p[rev]`: switch to the previous buffer * `d[el]b[uf][!] []`: delete the buffer * `source `: execute commands in * `colorscheme `: load named colorscheme. * `rename-client `: set current client name * `rename-buffer `: set current buffer name * `rename-session `: set current session name * `echo [options] `: show in status line, with the following options: ** `-markup`: expand the markup strings in ** `-debug`: print the given text to the `\*debug*` buffer * `nop`: does nothing, but as with every other commands, arguments may be evaluated. So nop can be used for example to execute a shell command while being sure that it's output will not be interpreted by kak. `:%sh{ echo echo tchou }` will echo tchou in Kakoune, whereas `:nop %sh{ echo echo tchou }` will not, but both will execute the shell command. * `fail `: raise an error, uses as its description Multiple commands ~~~~~~~~~~~~~~~~~ Multiple commands can be separated either by new lines or by semicolons, as such a semicolon must be escaped with `\;` to be considered as a literal semicolon argument. String syntax and expansions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Values, options and shell context can be interpolated in strings. See <>. Configuration & Autoloading --------------------------- Kakrc ~~~~~ If not launched with the `-n` switch, Kakoune will source the `../share/kak/kakrc` file relative to the `kak` binary, which will source additional files: If the `$XDG_CONFIG_HOME/kak/autoload` directory exists, load every `*.kak` files in it, and load recursively any subdirectory. If it does not exist, falls back to the site wide autoload directory in `../share/kak/autoload/`. After that, if it exists, source the `$XDG_CONFIG_HOME/kak/kakrc` file which should be used for user configuration. In order to continue autoloading site-wide files with a local autoload directory, just add a symbolic link to `../share/kak/autoload/` into your local autoload directory. Color Schemes ~~~~~~~~~~~~~ Kakoune ships with some color schemes that are installed to `../share/kak/colors/`. If `$XDG_CONFIG_HOME/kak/colors/` is present the builtin command `colorscheme` will offer completion for those color schemes. If a scheme is duplicated in userspace, it will take precedence. Options ------- Kakoune can store named and typed values that can be used both to customize the core editor behaviour, and to keep data used by extension scripts. See <>. Advanced topics --------------- Faces ~~~~~ Faces describe how characters are displayed on the screen: color, bold, italic... See <>. Registers ~~~~~~~~~ Registers are named lists of text. They are used for various purposes, like storing the last yanked text, or the captured groups associated with the selections. See <>. Macros ~~~~~~ Kakoune can record and replay a sequence of key presses. See <>. Search selection ~~~~~~~~~~~~~~~~ Using the `*` key, you can set the search pattern to the current selection. See <>. Regex syntax ~~~~~~~~~~~~ Kakoune regex syntax is based on the ECMAScript syntax (ECMA-262 standard). It always run on Unicode codepoint sequences, not on bytes. See <>. Exec and Eval ~~~~~~~~~~~~~ The `execute-keys` and `evaluate-commands` are useful for scripting in non interactive contexts. See <>. Insert mode completion ~~~~~~~~~~~~~~~~~~~~~~ Kakoune can propose completions while inserting text: filenames, words, lines… See <>. Escape to normal mode ~~~~~~~~~~~~~~~~~~~~~ From insert mode, pressing `` allows you to execute a single normal mode command. This provides a few advantages: * The selections are not modified: when leaving insert mode using `` the selections can change, for example when insert mode was entered with `a` the cursor will go back one char. Or if on an end of line the cursor will go back left (if possible). * The modes are nested: that means the normal mode can enter prompt (with `:`), or any other modes (using `:on-key` or `:menu` for example), and these modes will get back to the insert mode afterwards. This feature is tailored for scripting/macros, as it provides a more predictable behaviour than leaving insert mode with ``, executing normal mode command and entering back insert mode (with which binding ?) See <>. Highlighters ~~~~~~~~~~~~ Manipulation of the displayed text, such as syntax coloration and wrapping is done through highlighters. See <>. Hooks ~~~~~ Commands can be registered to be executed when certain events arise with hooks. See <>. Key Mapping ~~~~~~~~~~~ Custom key shortcuts can be registered through mappings. See <>. Defining Commands and Aliases ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ New commands can be created using `:define-command`. See <>. They can be given additional short names depending of the scope with `:alias`. See <>. Some helper commands are available to define composite commands. See <>. FIFO Buffers ~~~~~~~~~~~ FIFO buffers are very useful for running some commands asynchronously while progressively displaying their result in Kakoune. See <>. Menus ~~~~~ When a menu is displayed, you can use `j`, `` or `` to select the next entry, and `k`, `` or `` to select the previous one. Using the `/` key, you can enter some regex in order to restrict available choices to the matching ones. Credits ------- Thanks to https://github.com/p0nce[p0nce] for designing the https://github.com/mawww/kakoune/blob/master/doc/kakoune_logo.svg[Kakoune logo]. And thanks to all the https://github.com/mawww/kakoune/graphs/contributors[contributors] who help move the project forward! kakoune-2019.07.01/UNLICENSE000066400000000000000000000022731350637360100150300ustar00rootroot00000000000000This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to kakoune-2019.07.01/VIMTOKAK000066400000000000000000000043401350637360100147250ustar00rootroot00000000000000Vi(m) to Kakoune: ================= Kakoune is inspired heavily by Vim, it strives to be as efficient as Vim, more consistent and simpler. A big difference is that a lot of special features in Vim just become regular interactions of basic features in Kakoune. Operations and moves are reversed in Kakoune. First select whatever text you want to operate on, and then use an modifying operation. That makes things more consistent (Vim needs a separate x and d operation because of the operator -> move order, Kakoune only needs the d operation). That also allows more complex selections. delete a word: * vim: dw * kak: wd delete a character: * vim: x * kak: d or ;d (; reduces the selection to a single char) copy a line: * vim: yy * kak: xy global replace: * vim: :%s/word/replacement * kak: %swordcreplacement Explanation: '%' selects the entire buffer, 's' opens a prompt for a regex, validates the regex and replace the selection with one per matches (hence, all occurences of word are selected). 'c' deletes the selection contents and enter insert mode, replacement is typed and goes back to normal mode. Note that the Kakoune version is one key less, and is not a special feature per se, but just a nice way Kakoune features work together. replace in current curly braces block: * vim: viB:s/word/replacement * kak: Bswordcreplacement Here again, we need to rely on another Vim special feature, visual mode. join line with next: * vim: J * kak: alt-J delete to line end: * vim: d$ * kak: alt-ld or Gld some classic vim moves are not bound to the same key, this is due to Kakoune using shifted moves to append to selection, so moves that were bound to non alphabetic chars had to change. * % become m (for matching), however m will replace selection with the next block, if you want to get a selection from current point to next block end, you should use M ( clears the selection to one character) * 0 and $ became alt-h and alt-l. Another binding is gh and gl. :[gv]/re/cmd to emulate :g or :v, use % to select the whole buffer, alt-s to get one selection by line, and then alt-k or alt-K in order to keep only the selections matching (or not matching) the entered regex. kakoune-2019.07.01/colors/000077500000000000000000000000001350637360100150555ustar00rootroot00000000000000kakoune-2019.07.01/colors/base16.kak000066400000000000000000000051351350637360100166320ustar00rootroot00000000000000## ## base16.kak by lenormf ## evaluate-commands %sh{ black_lighterer='rgb:383838' black_lighter='rgb:2D2D2D' black_light='rgb:1C1C1C' cyan_light='rgb:7CB0FF' green_dark='rgb:A1B56C' grey_dark='rgb:585858' grey_light='rgb:D8D8D8' magenta_dark='rgb:AB4642' magenta_light='rgb:AB4434' orange_dark='rgb:DC9656' orange_light='rgb:F7CA88' purple_dark='rgb:BA8BAF' ## code echo " face global value ${orange_dark}+b face global type ${orange_light} face global variable ${magenta_dark} face global module ${green_dark} face global function ${cyan_light} face global string ${green_dark} face global keyword ${purple_dark}+b face global operator ${cyan_light} face global attribute ${orange_dark} face global comment ${grey_dark} face global meta ${orange_light} face global builtin default+b " ## markup echo " face global title blue face global header ${cyan_light} face global bold ${orange_light} face global italic ${orange_dark} face global mono ${green_dark} face global block ${orange_dark} face global link blue face global bullet ${magenta_light} face global list ${magenta_dark} " ## builtin echo " face global Default ${grey_light},${black_lighter} face global PrimarySelection white,blue+fg face global SecondarySelection black,blue+fg face global PrimaryCursor black,white+fg face global SecondaryCursor black,white+fg face global PrimaryCursorEol black,${cyan_light}+fg face global SecondaryCursorEol black,${cyan_light}+fg face global LineNumbers ${grey_light},${black_lighter} face global LineNumberCursor ${grey_light},rgb:282828+b face global MenuForeground ${grey_light},blue face global MenuBackground blue,${grey_light} face global MenuInfo ${cyan_light} face global Information ${black_light},${cyan_light} face global Error ${grey_light},${magenta_light} face global StatusLine ${grey_light},${black_lighterer} face global StatusLineMode ${orange_dark} face global StatusLineInfo ${cyan_light} face global StatusLineValue ${green_dark} face global StatusCursor ${black_lighterer},${cyan_light} face global Prompt ${black_light},${cyan_light} face global MatchingChar ${cyan_light},${black_light}+b face global BufferPadding ${cyan_light},${black_lighter} face global Whitespace ${grey_dark}+f " } kakoune-2019.07.01/colors/default.kak000066400000000000000000000027361350637360100172010ustar00rootroot00000000000000# Kakoune default color scheme # For Code face global value red face global type yellow face global variable green face global module green face global function cyan face global string magenta face global keyword blue face global operator yellow face global attribute green face global comment cyan face global meta magenta face global builtin default+b # For markup face global title blue face global header cyan face global bold red face global italic yellow face global mono green face global block magenta face global link cyan face global bullet cyan face global list yellow # builtin faces face global Default default,default face global PrimarySelection white,blue+fg face global SecondarySelection black,blue+fg face global PrimaryCursor black,white+fg face global SecondaryCursor black,white+fg face global PrimaryCursorEol black,cyan+fg face global SecondaryCursorEol black,cyan+fg face global LineNumbers default,default face global LineNumberCursor default,default+r face global MenuForeground white,blue face global MenuBackground blue,white face global MenuInfo cyan face global Information black,yellow face global Error black,red face global StatusLine cyan,default face global StatusLineMode yellow,default face global StatusLineInfo blue,default face global StatusLineValue green,default face global StatusCursor black,cyan face global Prompt yellow,default face global MatchingChar default,default+b face global Whitespace default,default+f face global BufferPadding blue,default kakoune-2019.07.01/colors/desertex.kak000066400000000000000000000036731350637360100174010ustar00rootroot00000000000000# desertex theme # Code face global value rgb:fa8072 face global type rgb:dfdfbf face global identifier rgb:87ceeb face global string rgb:fa8072 face global error rgb:c3bf9f+b face global keyword rgb:eedc82 face global operator rgb:87ceeb face global attribute rgb:eedc82 face global comment rgb:7ccd7c+i # #include <...> face global meta rgb:ee799f # Markup face global title blue face global header cyan face global bold red face global italic yellow face global mono green face global block magenta face global link cyan face global bullet cyan face global list yellow # Builtin # fg,bg+attributes # face global Default default,rgb:262626 <- change the terminal bg color instead face global Default default,default face global PrimarySelection white,blue+fg face global SecondarySelection black,blue+fg face global PrimaryCursor black,white+fg face global SecondaryCursor black,white+fg face global PrimaryCursorEol black,rgb:7ccd7c+fg face global SecondaryCursorEol black,rgb:7ccd7c+fg face global LineNumbers rgb:605958 face global LineNumberCursor yellow,default+b # Bottom menu: # text + background face global MenuBackground black,rgb:c2bfa5+b # selected entry in the menu (use 302028 when true color support is fixed) face global MenuForeground rgb:f0a0c0,magenta # completion menu info face global MenuInfo white,rgb:445599 # assistant, [+] face global Information black,yellow face global Error white,red face global StatusLine cyan,default # Status line modes and prompts: # insert, prompt, enter key... face global StatusLineMode rgb:ffd75f,default # 1 sel face global StatusLineInfo blue,default # param=value, reg=value. ex: "ey face global StatusLineValue green,default face global StatusCursor black,cyan # : face global Prompt blue # (), {} face global MatchingChar cyan+b # EOF tildas (~) face global BufferPadding blue,default # Whitespace characters face global Whitespace default+f kakoune-2019.07.01/colors/github.kak000066400000000000000000000030461350637360100170320ustar00rootroot00000000000000## ## github.kak by lenormf ## v1.0 ## ## code face global value rgb:0086B3+b face global type rgb:795DA3 face global variable rgb:0086B3 face global module rgb:0086B3 face global function rgb:A71D5D face global string rgb:183691 face global keyword rgb:A71D5D+b face global operator yellow face global attribute rgb:A71D5D face global comment rgb:AAAAAA face global meta rgb:183691 face global builtin default+b ## markup face global title blue face global header cyan face global bold red face global italic yellow face global mono green face global block magenta face global link cyan face global bullet cyan face global list yellow ## builtin face global Default rgb:121213,rgb:F8F8FF face global PrimarySelection default,rgb:A6F3A6+fg face global SecondarySelection default,rgb:DBFFDB+fg face global PrimaryCursor black,rgb:888888+fg face global SecondaryCursor black,rgb:888888+fg face global PrimaryCursorEol black,rgb:A71D5D+fg face global SecondaryCursorEol black,rgb:A71D5D+fg face global LineNumbers rgb:A0A0A0,rgb:ECECEC face global LineNumberCursor rgb:434343,rgb:DDDDDD face global MenuForeground rgb:434343,rgb:CDCDFD face global MenuBackground rgb:F8F8FF,rgb:808080 face global Information rgb:F8F8FF,rgb:4078C0 face global Error rgb:F8F8FF,rgb:BD2C00 face global StatusLine rgb:434343,rgb:DDDDDD face global StatusCursor rgb:434343,rgb:CDCDFD face global Prompt rgb:F8F8FF,rgb:4078C0 face global MatchingChar rgb:F8F8FF,rgb:4078C0+b face global Search default,default+u face global BufferPadding rgb:A0A0A0,rgb:F8F8FF face global Whitespace rgb:A0A0A0+f kakoune-2019.07.01/colors/gruvbox.kak000066400000000000000000000047761350637360100172570ustar00rootroot00000000000000# gruvbox theme evaluate-commands %sh{ gray="rgb:928374" red="rgb:fb4934" green="rgb:b8bb26" yellow="rgb:fabd2f" blue="rgb:83a598" purple="rgb:d3869b" aqua="rgb:8ec07c" orange="rgb:fe8019" bg="rgb:282828" bg1="rgb:3c3836" bg2="rgb:504945" bg3="rgb:665c54" bg4="rgb:7c6f64" fg0="rgb:fbf1c7" fg="rgb:ebdbb2" fg2="rgb:d5c4a1" fg3="rgb:bdae93" fg4="rgb:a89984" echo " # Code highlighting face global value ${purple} face global type ${yellow} face global variable ${blue} face global module ${green} face global function ${fg} face global string ${green} face global keyword ${red} face global operator ${fg} face global attribute ${orange} face global comment ${gray}+i face global meta ${aqua} face global builtin ${fg}+b # Markdown highlighting face global title ${green}+b face global header ${orange} face global bold ${fg}+b face global italic ${fg}+i face global mono ${fg4} face global block ${aqua} face global link ${blue}+u face global bullet ${yellow} face global list ${fg} face global Default ${fg},${bg} face global PrimarySelection ${fg},${blue}+fg face global SecondarySelection ${bg},${blue}+fg face global PrimaryCursor ${bg},${fg}+fg face global SecondaryCursor ${bg},${bg4}+fg face global PrimaryCursorEol ${bg},${fg4}+fg face global SecondaryCursorEol ${bg},${bg2}+fg face global LineNumbers ${bg4} face global LineNumberCursor ${yellow},${bg1} face global LineNumbersWrapped ${bg1} face global MenuForeground ${bg2},${blue} face global MenuBackground ${fg},${bg2} face global MenuInfo ${bg} face global Information ${bg},${fg} face global Error ${bg},${red} face global StatusLine ${fg},${bg} face global StatusLineMode ${yellow}+b face global StatusLineInfo ${purple} face global StatusLineValue ${red} face global StatusCursor ${bg},${fg} face global Prompt ${yellow} face global MatchingChar ${fg},${bg3}+b face global BufferPadding ${bg2},${bg} face global Whitespace ${bg2}+f " } kakoune-2019.07.01/colors/lucius.kak000066400000000000000000000064021350637360100170530ustar00rootroot00000000000000# lucius theme evaluate-commands %sh{ # first we define the lucius colors as named colors lucius_darker_grey="rgb:303030" lucius_dark_grey="rgb:444444" lucius_grey="rgb:808080" lucius_light_grey="rgb:b2b2b2" lucius_lighter_grey="rgb:d7d7d7" lucius_dark_red="rgb:870000" lucius_light_red="rgb:ff8787" lucius_orange="rgb:d78700" lucius_purple="rgb:d7afd7" lucius_dark_green="rgb:5f875f" lucius_bright_green="rgb:87af00" lucius_green="rgb:afd787" lucius_light_green="rgb:d7d7af" lucius_dark_blue="rgb:005f87" lucius_blue="rgb:87afd7" lucius_light_blue="rgb:87d7ff" echo " # then we map them to code face global value ${lucius_light_green} face global type ${lucius_blue} face global variable ${lucius_green} face global module ${lucius_green} face global function ${lucius_light_blue} face global string ${lucius_light_green} face global keyword ${lucius_light_blue} face global operator ${lucius_green} face global attribute ${lucius_light_blue} face global comment ${lucius_grey} face global meta ${lucius_purple} face global builtin default+b # and markup face global title ${lucius_light_blue} face global header ${lucius_light_green} face global bold ${lucius_blue} face global italic ${lucius_green} face global mono ${lucius_light_green} face global block ${lucius_light_blue} face global link ${lucius_light_green} face global bullet ${lucius_green} face global list ${lucius_blue} # and built in faces face global Default ${lucius_lighter_grey},${lucius_darker_grey} face global PrimarySelection ${lucius_darker_grey},${lucius_orange}+fg face global SecondarySelection ${lucius_lighter_grey},${lucius_dark_blue}+fg face global PrimaryCursor ${lucius_darker_grey},${lucius_lighter_grey}+fg face global SecondaryCursor ${lucius_darker_grey},${lucius_lighter_grey}+fg face global PrimaryCursorEol ${lucius_darker_grey},${lucius_dark_green}+fg face global SecondaryCursorEol ${lucius_darker_grey},${lucius_dark_green}+fg face global LineNumbers ${lucius_grey},${lucius_dark_grey} face global LineNumberCursor ${lucius_grey},${lucius_dark_grey}+b face global MenuForeground ${lucius_blue},${lucius_dark_blue} face global MenuBackground ${lucius_darker_grey},${lucius_light_grey} face global MenuInfo ${lucius_grey} face global Information ${lucius_lighter_grey},${lucius_dark_green} face global Error ${lucius_light_red},${lucius_dark_red} face global StatusLine ${lucius_lighter_grey},${lucius_dark_grey} face global StatusLineMode ${lucius_lighter_grey},${lucius_dark_green}+b face global StatusLineInfo ${lucius_dark_grey},${lucius_lighter_grey} face global StatusLineValue ${lucius_lighter_grey} face global StatusCursor default,${lucius_blue} face global Prompt ${lucius_lighter_grey} face global MatchingChar ${lucius_lighter_grey},${lucius_bright_green} face global BufferPadding ${lucius_green},${lucius_darker_grey} face global Whitespace ${lucius_grey}+f " } kakoune-2019.07.01/colors/palenight.kak000066400000000000000000000054061350637360100175250ustar00rootroot00000000000000# palenight theme # This was ported from https://github.com/drewtempelmeyer/palenight.vim evaluate-commands %sh{ red=rgb:ff5370 light_red=rgb:ff869a dark_red=rgb:be5046 green=rgb:c3e88d yellow=rgb:ffcb6b dark_yellow=rgb:f78c6c blue=rgb:82b1ff purple=rgb:c792ea cyan=rgb:89ddff white=rgb:bfc7d5 black=rgb:292d3e comment_grey=rgb:697098 gutter_fg_grey=rgb:4b5263 cursor_grey=rgb:2c323c visual_grey=rgb:3e4452 menu_grey=rgb:3e4452 special_grey=rgb:3b4048 vertsplit=rgb:181a1f visual_black=default printf "%s\n" " # Code face global value $dark_yellow face global type $yellow face global function $blue face global variable $blue face global identifier $blue face global string $green face global error rgb:c3bf9f+b face global keyword $purple face global operator $cyan face global attribute rgb:eedc82 face global comment $comment_grey+i # #include <...> face global meta $yellow # Markup face global title $blue face global header $cyan face global bold $red face global italic $yellow face global mono $green face global block $purple face global link $cyan face global bullet $cyan face global list $yellow # Builtin face global Default $white,$black face global PrimarySelection $black,$white+bfg face global SecondarySelection $black,$white+fg face global PrimaryCursor white,$purple+bfg face global SecondaryCursor $black,$purple+fg face global PrimaryCursorEol $black,$green+fg face global SecondaryCursorEol $black,$green+fg face global LineNumbers $gutter_fg_grey face global LineNumberCursor $yellow,default+b # Bottom menu: # text + background face global MenuBackground $black,$white face global MenuForeground $black,$purple # completion menu info face global MenuInfo $black,$white+i # assistant, [+] face global Information $white,$visual_grey face global Error $white,$red face global StatusLine $white,$black # Status line face global StatusLineMode $black,$purple # insert, prompt, enter key ... face global StatusLineInfo $white,$visual_grey # 1 sel face global StatusLineValue $visual_grey,$green # param=value, reg=value. ex: \"ey face global StatusCursor white,$purple+bg face global Prompt $purple,$black # : face global MatchingChar $red+b # (), {} face global BufferPadding $gutter_fg_grey,$black # EOF tildas (~) # Whitespace characters face global Whitespace $gutter_fg_grey,$black+fg " } kakoune-2019.07.01/colors/red-phoenix.kak000066400000000000000000000052371350637360100177760ustar00rootroot00000000000000## ## Red Phoenix (dkeg) - adapted by boj ## evaluate-commands %sh{ black="rgb:000000" blue="rgb:81a2be" orange1="rgb:F2361E" orange2="rgb:ED4B19" orange3="rgb:FA390F" light_orange1="rgb:DF9767" white1="rgb:EDEDED" white2="rgb:E1E1E1" gray1="rgb:6F6F6F" gray2="rgb:D1D1D1" gray3="rgb:2D2D2D" gray4="rgb:909090" tan1="rgb:D2C3AD" tan2="rgb:AAA998" tan3="rgb:DF9767" yellow1="rgb:AAA998" purple1="rgb:4C3A3D" foreground=${white1} background=${black} selection=${purple1} window=${gray3} text=${white2} text_light=${white1} line=${tan1} comment=${gray1} ## code echo " face global value ${orange2} face global type ${gray2} face global variable ${orange1} face global module ${gray2} face global function ${yellow1} face global string ${tan2} face global keyword ${light_orange1} face global operator ${yellow1} face global attribute ${tan1} face global comment ${gray1} face global meta ${gray2} face global builtin ${tan1} " ## markup echo " face global title blue face global header ${orange1} face global bold ${orange2} face global italic ${orange3} face global mono ${yellow1} face global block ${tan1} face global link blue face global bullet ${gray1} face global list ${gray1} " ## builtin echo " face global Default ${text},${background} face global PrimarySelection default,${selection}+fg face global SecondarySelection default,${selection}+fg face global PrimaryCursor black,${tan1}+fg face global SecondaryCursor black,${tan2}+fg face global PrimaryCursorEol black,${orange1}+fg face global SecondaryCursorEol black,${orange2}+fg face global LineNumbers ${text_light},${background} face global LineNumberCursor ${text},${gray1}+b face global MenuForeground ${text_light},blue face global MenuBackground ${orange1},${window} face global MenuInfo ${gray1} face global Information white,${window} face global Error white,${gray1} face global StatusLine ${text},${window} face global StatusLineMode ${yellow1}+b face global StatusLineInfo ${orange2} face global StatusLineValue ${orange2} face global StatusCursor ${window},${orange2} face global Prompt ${background},${orange2} face global MatchingChar ${orange3},${background}+b face global BufferPadding ${orange2},${background} face global Whitespace default+f " } kakoune-2019.07.01/colors/reeder.kak000066400000000000000000000055501350637360100170200ustar00rootroot00000000000000## ## reeder theme ## a light theme inspired after https://github.com/hyspace/st2-reeder-theme ## evaluate-commands %sh{ white="rgb:f9f8f6" white_light="rgb:f6f5f0" black="rgb:383838" black_light="rgb:635240" grey_dark="rgb:c6b0a4" grey_light="rgb:e8e8e8" brown_dark="rgb:af4609" brown_light="rgb:baa188" brown_lighter="rgb:f0e7df" orange="rgb:fc7302" orange_light="rgb:f88e3b" green="rgb:438047" green_light="rgb:7ba84d" red="rgb:f03c3c" # Base color definitions echo " # then we map them to code face global value ${orange_light}+b face global type ${orange} face global variable default face global module ${green} face global function default face global string ${green} face global keyword ${brown_dark} face global operator default face global attribute ${green} face global comment ${brown_light} face global meta ${brown_dark} face global builtin default+b # and markup face global title ${orange}+b face global header ${orange}+b face global bold default+b face global italic default+i face global mono ${green_light} face global block ${green} face global link ${orange} face global bullet ${brown_dark} face global list ${black} # and built in faces face global Default ${black_light},${white} face global PrimarySelection ${black},${brown_lighter}+fg face global SecondarySelection ${black_light},${grey_light}+fg face global PrimaryCursor ${black},${grey_dark}+fg face global SecondaryCursor ${black},${grey_dark}+fg face global PrimaryCursorEol ${black},${brown_dark}+fg face global SecondaryCursorEol ${black},${brown_dark}+fg face global LineNumbers ${grey_dark},${white} face global LineNumberCursor ${grey_dark},${brown_lighter} face global MenuForeground ${orange},${brown_lighter} face global MenuBackground ${black_light},${brown_lighter} face global MenuInfo default,${black} face global Information ${black_light},${brown_lighter} face global Error default,${red} face global StatusLine ${black},${grey_light} face global StatusLineMode ${orange} face global StatusLineInfo ${black}+b face global StatusLineValue ${green_light} face global StatusCursor ${orange},${white_light} face global Prompt ${black_light} face global MatchingChar default+b face global BufferPadding ${grey_dark},${white} face global Whitespace ${grey_dark}+f " } kakoune-2019.07.01/colors/solarized-dark-termcolors.kak000066400000000000000000000041461350637360100226540ustar00rootroot00000000000000# Solarized Dark (with termcolors) # Useful if you've set up your terminal with the exact Solarized colors # code face global value cyan face global type yellow face global variable blue face global module cyan face global function blue face global string cyan face global keyword green face global operator green face global attribute bright-magenta face global comment bright-green face global meta bright-red face global builtin default+b # markup face global title blue+b face global header blue face global bold bright-blue+b face global italic bright-blue+i face global mono bright-cyan face global block cyan face global link bright-cyan face global bullet yellow face global list green # builtin face global Default bright-blue,bright-black face global PrimarySelection bright-black,blue+fg face global SecondarySelection bright-green,bright-cyan+fg face global PrimaryCursor bright-black,bright-blue+fg face global SecondaryCursor bright-black,bright-green+fg face global PrimaryCursorEol bright-black,white+fg face global SecondaryCursorEol bright-black,bright-white+fg face global LineNumbers bright-green,black face global LineNumberCursor bright-cyan,black face global LineNumbersWrapped black,black face global MenuForeground bright-black,yellow face global MenuBackground bright-cyan,black face global MenuInfo bright-green face global Information black,bright-cyan face global Error red,default+b face global StatusLine bright-cyan,black+b face global StatusLineMode bright-red face global StatusLineInfo cyan face global StatusLineValue green face global StatusCursor bright-yellow,bright-white face global Prompt yellow+b face global MatchingChar red,bright-green+b face global BufferPadding bright-green,bright-black face global Whitespace blue+f kakoune-2019.07.01/colors/solarized-dark.kak000066400000000000000000000053701350637360100204650ustar00rootroot00000000000000# Solarized Dark evaluate-commands %sh{ base03='rgb:002b36' base02='rgb:073642' base01='rgb:586e75' base00='rgb:657b83' base0='rgb:839496' base1='rgb:93a1a1' base2='rgb:eee8d5' base3='rgb:fdf6e3' yellow='rgb:b58900' orange='rgb:cb4b16' red='rgb:dc322f' magenta='rgb:d33682' violet='rgb:6c71c4' blue='rgb:268bd2' cyan='rgb:2aa198' green='rgb:859900' echo " # code face global value ${cyan} face global type ${red} face global variable ${blue} face global module ${cyan} face global function ${blue} face global string ${cyan} face global keyword ${green} face global operator ${yellow} face global attribute ${violet} face global comment ${base01} face global meta ${orange} face global builtin default+b # markup face global title ${blue}+b face global header ${blue} face global bold ${base0}+b face global italic ${base0}+i face global mono ${base1} face global block ${cyan} face global link ${base1} face global bullet ${yellow} face global list ${green} # builtin face global Default ${base0},${base03} face global PrimarySelection ${base03},${blue}+fg face global SecondarySelection ${base01},${base1}+fg face global PrimaryCursor ${base03},${base0}+fg face global SecondaryCursor ${base03},${base01}+fg face global PrimaryCursorEol ${base03},${base2}+fg face global SecondaryCursorEol ${base03},${base3}+fg face global LineNumbers ${base01},${base02} face global LineNumberCursor ${base1},${base02} face global LineNumbersWrapped ${base02},${base02} face global MenuForeground ${base03},${yellow} face global MenuBackground ${base1},${base02} face global MenuInfo ${base01} face global Information ${base02},${base1} face global Error ${red},default+b face global StatusLine ${base1},${base02}+b face global StatusLineMode ${orange} face global StatusLineInfo ${cyan} face global StatusLineValue ${green} face global StatusCursor ${base00},${base3} face global Prompt ${yellow}+b face global MatchingChar ${red},${base01}+b face global BufferPadding ${base01},${base03} face global Whitespace ${base01}+f " } kakoune-2019.07.01/colors/solarized-light-termcolors.kak000066400000000000000000000041421350637360100230360ustar00rootroot00000000000000# Solarized Light (with termcolors) # Useful if you've set up your terminal with the exact Solarized colors # code face global value cyan face global type red face global variable blue face global module cyan face global function blue face global string cyan face global keyword green face global operator yellow face global attribute bright-magenta face global comment bright-cyan face global meta bright-red face global builtin default+b # markup face global title blue+b face global header blue face global bold bright-green+b face global italic bright-green+i face global mono bright-cyan face global block cyan face global link bright-green face global bullet yellow face global list green # builtin face global Default bright-yellow,bright-white face global PrimarySelection bright-white,blue+fg face global SecondarySelection bright-cyan,bright-green+fg face global PrimaryCursor bright-white,bright-yellow+fg face global SecondaryCursor bright-white,bright-cyan+fg face global PrimaryCursorEol bright-white,yellow+fg face global SecondaryCursorEol bright-white,bright-red+fg face global LineNumbers bright-cyan,white face global LineNumberCursor bright-green,white face global LineNumbersWrapped white,white face global MenuForeground bright-white,yellow face global MenuBackground bright-green,white face global MenuInfo bright-cyan face global Information white,bright-cyan face global Error red,default+b face global StatusLine bright-green,white+b face global StatusLineMode bright-red face global StatusLineInfo cyan face global StatusLineValue green face global StatusCursor bright-blue,bright-black face global Prompt yellow+b face global MatchingChar red,white+b face global BufferPadding bright-cyan,bright-white face global Whitespace yellow+f kakoune-2019.07.01/colors/solarized-light.kak000066400000000000000000000053561350637360100206570ustar00rootroot00000000000000# Solarized Light evaluate-commands %sh{ base03='rgb:002b36' base02='rgb:073642' base01='rgb:586e75' base00='rgb:657b83' base0='rgb:839496' base1='rgb:93a1a1' base2='rgb:eee8d5' base3='rgb:fdf6e3' yellow='rgb:b58900' orange='rgb:cb4b16' red='rgb:dc322f' magenta='rgb:d33682' violet='rgb:6c71c4' blue='rgb:268bd2' cyan='rgb:2aa198' green='rgb:859900' echo " # code face global value ${cyan} face global type ${red} face global variable ${blue} face global module ${cyan} face global function ${blue} face global string ${cyan} face global keyword ${green} face global operator ${yellow} face global attribute ${violet} face global comment ${base1} face global meta ${orange} face global builtin default+b # markup face global title ${blue}+b face global header ${blue} face global bold ${base01}+b face global italic ${base01}+i face global mono ${base1} face global block ${cyan} face global link ${base01} face global bullet ${yellow} face global list ${green} # builtin face global Default ${base00},${base3} face global PrimarySelection ${base3},${blue}+fg face global SecondarySelection ${base1},${base01}+fg face global PrimaryCursor ${base3},${base00}+fg face global SecondaryCursor ${base3},${base1}+fg face global PrimaryCursorEol ${base3},${yellow}+fg face global SecondaryCursorEol ${base3},${orange}+fg face global LineNumbers ${base1},${base2} face global LineNumberCursor ${base01},${base2} face global LineNumbersWrapped ${base2},${base2} face global MenuForeground ${base3},${yellow} face global MenuBackground ${base01},${base2} face global MenuInfo ${base1} face global Information ${base2},${base1} face global Error ${red},default+b face global StatusLine ${base01},${base2}+b face global StatusLineMode ${orange} face global StatusLineInfo ${cyan} face global StatusLineValue ${green} face global StatusCursor ${base0},${base03} face global Prompt ${yellow}+b face global MatchingChar ${red},${base2}+b face global BufferPadding ${base1},${base3} face global Whitespace ${base1}+f " } kakoune-2019.07.01/colors/tomorrow-night.kak000066400000000000000000000047711350637360100205550ustar00rootroot00000000000000## ## Tomorrow-night, adapted by nicholastmosher ## evaluate-commands %sh{ foreground="rgb:c5c8c6" background="rgb:272727" selection="rgb:373b41" window="rgb:383838" text="rgb:D8D8D8" text_light="rgb:4E4E4E" line="rgb:282a2e" comment="rgb:969896" red="rgb:cc6666" orange="rgb:d88860" yellow="rgb:f0c674" green="rgb:b5bd68" green_dark="rgb:a1b56c" blue="rgb:81a2be" aqua="rgb:87afaf" magenta="rgb:ab4642" purple="rgb:b294bb" ## code echo " face global value ${orange} face global type ${yellow} face global variable ${magenta} face global module ${green} face global function ${aqua} face global string ${green_dark} face global keyword ${purple} face global operator ${aqua} face global attribute ${purple} face global comment ${comment} face global meta ${purple} face global builtin ${orange} " ## markup echo " face global title blue face global header ${aqua} face global bold ${yellow} face global italic ${orange} face global mono ${green_dark} face global block ${orange} face global link blue face global bullet ${red} face global list ${red} " ## builtin echo " face global Default ${text},${background} face global PrimarySelection default,${selection}+fg face global SecondarySelection default,${selection}+fg face global PrimaryCursor black,${aqua}+fg face global SecondaryCursor black,${aqua}+fg face global PrimaryCursorEol black,${green_dark}+fg face global SecondaryCursorEol black,${green_dark}+fg face global LineNumbers ${text_light},${background} face global LineNumberCursor ${yellow},rgb:282828+b face global MenuForeground ${text_light},blue face global MenuBackground ${aqua},${window} face global MenuInfo ${aqua} face global Information white,${window} face global Error white,${red} face global StatusLine ${text},${window} face global StatusLineMode ${yellow}+b face global StatusLineInfo ${aqua} face global StatusLineValue ${green_dark} face global StatusCursor ${window},${aqua} face global Prompt ${background},${aqua} face global MatchingChar ${yellow},${background}+b face global BufferPadding ${aqua},${background} face global Whitespace ${text_light}+f " } kakoune-2019.07.01/colors/zenburn.kak000066400000000000000000000057451350637360100172430ustar00rootroot00000000000000# zenburn theme evaluate-commands %sh{ # define some named colors zentext="rgb:cfcfcf" zenselectionbg="rgb:3f7fcc" zencursor="rgb:2a2a2a,rgb:dfdfbf" zencursoreol="rgb:2a2a2a,rgb:cc9393" zensecondaryfg="rgb:2a2a2a" zendefault="${zentext},rgb:3f3f3f" zenstatus="rgb:efdcbc,rgb:2a2a2a" zenstatuscursor="${zentext},rgb:7f9f7f" zeninfo="rgb:cc9393,rgb:2a2a2a" zenmenubg="rgb:7f9f7f,rgb:4a4a4a" zenmenufg="rgb:8cd0d3,rgb:5b5b5b" zenkeyword="rgb:f0dfaf+b" zenstorageClass="rgb:c3bf9f+b" zennumber="rgb:8cd0d3" zencomment="rgb:7f9f7f" zenconstant="rgb:dca3a3+b" zenspecial="rgb:cfbfaf" zenfunction="rgb:efef8f" zenstatement="rgb:e3ceab" zenvariable="rgb:efdcbc" zentype="rgb:dfdfbf" zenstring="rgb:cc9393" zenmodule="${zenstring}" zenexception="rgb:c3bf9f+b" zenmatching="rgb:3f3f3f,rgb:8cd0d3" zenpadding="rgb:f0dfaf,rgb:343434+b" echo " # then we map them to code face global value ${zenconstant} face global type ${zentype} face global variable ${zenvariable} face global module ${zenstring} face global function ${zenfunction} face global string ${zenstring} face global keyword ${zenkeyword} face global operator ${zenfunction} face global attribute ${zenstatement} face global comment ${zencomment} face global meta ${zenspecial} face global builtin default+b # and markup face global title ${zenkeyword} face global header ${zenconstant} face global bold ${zenstorageClass} face global italic ${zenfunction} face global mono ${zennumber} face global block ${zenstatement} face global link ${zenstring} face global bullet ${zenvariable} face global list ${zentype} # and built in faces face global Default ${zendefault} face global PrimarySelection ${zentext},${zenselectionbg}+fg face global SecondarySelection ${zensecondaryfg},${zenselectionbg}+fg face global PrimaryCursor ${zencursor}+fg face global SecondaryCursor ${zencursor}+fg face global PrimaryCursorEol ${zencursoreol}+fg face global SecondaryCursorEol ${zencursoreol}+fg face global LineNumbers ${zendefault} face global LineNumberCursor ${zenstatus} face global MenuForeground ${zenmenufg} face global MenuBackground ${zenmenubg} face global MenuInfo rgb:cc9393 face global Information ${zeninfo} face global Error default,red face global StatusLine ${zenstatus} face global StatusLineMode ${zencomment} face global StatusLineInfo ${zenspecial} face global StatusLineValue ${zennumber} face global StatusCursor ${zenstatuscursor} face global Prompt ${zenconstant} face global MatchingChar default+b face global BufferPadding ${zenpadding} face global Whitespace ${zensecondaryfg}+f " } kakoune-2019.07.01/contrib/000077500000000000000000000000001350637360100152145ustar00rootroot00000000000000kakoune-2019.07.01/contrib/TRAMPOLINE000066400000000000000000000630341350637360100166170ustar00rootroot00000000000000+=----------------------------------------------------------------------------=+ _ _ | | | | | | __ __ _ | | __ ___ _ _ _ __ ___ | |/ / / _` | | |/ / / _ \ | | | | | '_ \ / _ \ | < | (_| | | < | (_) | | |_| | | | | | | __/ |_|\_\ \__,_| |_|\_\ \___/ \__,_| |_| |_| \___| Mawww's experiment for a better code editor +=----------------------------------------------------------------------------=+ This walk-through is an introduction to Kakoune's basic editing capabilities to help new users transition over easily from another editor, or simply learn how to write and edit documents with style. During the learning period it is useful to activate an automatically displayed contextual help for commands in normal mode: `:set -add global autoinfo normal` In the first section, you will learn about the primitives of the editing language to be able to get to a level of knowledge of the editor that guarantees that you can work with it efficiently. In the second section, for users who've gone through the basics and want to move on to more advanced functionalities, we explain other primitives whose role has a less dominant place in an everyday editing session, but still prove themselves powerful when used on the right occasion. Finally, as this document is in no way an exhaustive list of features, don't hesitate to check out the official documentation to compliment your tool-set, ask questions to more seasoned users on IRC, and check the documentation using the built-in `:doc` command. +=--------------------------------=+ BASICS +=--------------------------------=+ =[ MODES Kakoune uses a paradigm called "modal editing" to allow .---, users to either have every single key they type inserted | i | into the file being edited (called "insert mode"), `---' or execute commands that are triggered by the keys hit (the "normal mode"). Aside from arrow keys, most keys .---, described in this document are "editing primitives" that |esc| have to be hit in normal mode, which is the default mode `---' when you start the editor. To enter insert mode, hit the `i` key, and to leave it and return to normal mode, hit the escape key. =[ MOVEMENT .---, | ↑ | Movement in a buffer (the representation of the contents .---'---'---, of a file opened by Kakoune) can be achieved using the arrow | ← | ↓ | → | keys, which will move the cursor up one column/row into `---'---'---` a given direction. However, furthering the tradition of mode-based editors, .---,---,---,---, the `h`, `j`, `k` and `l` keys can be used for the same | h | j | k | l | purpose, and will respectively move the cursor to the `---'---'---'---` left, down, up, right by one, when hit. Using those keys | | | | is the recommended way of moving around in a buffer. .---,---,---,---, If you're not familiar with this concept, the proximity | ← | ↓ | ↑ | → | of those four keys with the rest of the lettered keys `---'---'---'---` on a `qwerty` layout allows faster interaction with the primitives than if the user had to moves their hand to .---, reach the arrow keys. | g |_. `---' |`.---, Another way of moving the cursor is the "goto" utility, | | g | invoked by hitting the `g` key. A menu will pop up with a | `---' summary of all the possible keys that can be hit, along with `.---, the location where they will move the cursor to, but the | e | most used ones that we are interested in, for now, are `g` `---' and `e`. The first one will jump to the beginning of the buffer, and the second one to its end. =[ VIEW .---, Displacing the cursor can sometimes move the view into an | v |_. inconvenient configuration, leaving some necessary context `---' |`.---, off screen, or simply feel uncomfortable to type into. | | t | Kakoune provides a menu (similar to the `goto` menu | `---' mentioned in the previous section) that allows users to |`.---, move the current view in relation with the position of the | | b | cursor. Upon hitting the `v` key, a short menu appears | `---' which allows us to hit a second key according to how the `.---, view should be centered vertically: to leave the cursor | v | respectively on top, at the bottom or in the middle of the `---' current view, hit the `t`, `b` or `v` keys. =[ SEARCH In order to move the cursor to a specific word, the search command is the way to go. This functionality allows .---, the user to jump to the next occurrence of a piece of text. | / | Upon hitting the `/` key, a prompt reading "search" `---' will pop up in the status bar in which you can type your text and validate using the `` (return) key. .---, .---, You'll notice that as you type, the cursor changes location |alt|+| / | to automatically give you a preview of where the cursor `---' `---' would be displaced to if you validated the search. However, this behavior is only a preview, exiting prompt mode with the `` (escape) key will leave the current position .---, of the cursor unchanged. Note that you can also use a | n | regular expression as input. By default the search `---' function will look for results forward, starting from the current location of the cursor, but you can search .---, .---, backwards using `` (alt + `/`). |alt|+| n | `---' `---' Jumping from one match to the other forward can be achieved using the `n` key, and backwards using the `` (alt + `n`) key combination. =[ SELECTIONS You have certainly noticed that when searching for .---, text, the cursor extends to highlight the entire match. | ; | In fact, what we know in other editors as a "cursor" is `---' actually a single character wide selection in Kakoune, and can be expanded using primitives. When "expanded", .---, .---, the selection is an area whose beginning is the "anchor" |alt|+| ; | and the end the "secondary cursor". To switch anchor and `---' `---' cursor, use ``, and to collapse the selection onto its anchor, use `;`. Moreover, not only Kakoune expands the principle of "cursor" by introducing selections, but it also allows .---, multiple selections within the same buffer. This makes | % | it very convenient to modify text in multiple locations `---' at once, as editing primitives apply to all the currently selected text. .---, | s | Example: to remove all occurrences of the word "foo", one `---' would select the entire buffer (`%`), select occurrences of the word (`s`, "\bfoo\b", ``), then remove it (`d`). ==[ SELECTING OBJECTS In addition to allowing text selection using regular .---, .---, expressions, certain objects are defined by default to |alt|+| i | allow easy selection of text. Objects are bits of text `---' `---' in the buffer that are identified according to their structure, rather than their contents, e.g. a paragraph, .---, .---, a sentence, or a word. When the cursor is located within |alt|+| a | the boundaries of an object you want to interact with, `---' `---' several options are available: selecting the contents of an object without its boundaries (``), a part of it (from .---, the anchor to its end or to its beginning, respectively `]` | ] | and `[`), or the entire object (``). Those "selection `---' ranges" are the first part of a two stages shortcut, as once you've used the key that dictates what part of .---, the object is to be selected, a menu with a description | [ | of all the object types select-able will be displayed, `---' giving a summary of all the keys you can hit to complete the selection procedure. Example: to select the paragraph in which the anchor lies, invoke the "inner object selection" shortcut (``), locate "paragraph" in the information box that pops up and .---, hit the according key (`p`). The entire two steps sequence | [ |_. is thus: ` p`. `---' |`.---, | | ( | Example: to select everything between the anchor and the | `---' beginning of the current parenthesis pair, use the selection `.---, sequence is: `[ (`. Note that common objects that use | r | pairs of opening/closing punctuation signs (brackets, `---' braces, quotes etc) have an alternative second key that is displayed in the information menu that you can use to minimize finger gymnastics. The previous shortcut could thus also be written: `[ r`. ==[ MOVEMENT SELECTIONS If objects are an easy way to select content-agnostic .---, data in a buffer, they can also be seen as a way to move | [ |_. about the buffer. As selecting objects will displace the `---' `.---, anchor into a given direction, you can wrap or move around | p | particular chunks of text without using the conventional `---' means (e.g. arrow keys or jumps), turning them partially into movement primitives. .---, | ] |_. Example: one of the most used object selection combination `---' `.---, is the "object end/begin paragraph" one: using `[` or | p | `]` will displace the anchor into a given direction, and `---' applying that to the paragraph object allows "jumping" from one newline separated block of text to another. The resulting shortcut is thus: `] p` to move forward, or `[ p` to move backward. =[ FILTERING A SELECTION Selecting an entire buffer (`%`) or parts of it (`s`) is a natural and basic operation in a typical editing session, .---, .---, however there are some cases where we need to be able to |alt|+| k | drop some selections arbitrarily, as opposed to trying `---' `---' to select the ones we need directly. This concept becomes very useful when coming up with a regular expression for .---, .---, the basic selection primitive (`s`) is too tedious (if |alt|+| K | even possible), that's why the editor provides us with a `---' `---' "keep matching" and a "keep not matching" operations, in order to respectively keep exclusively the selections who match or do not match a given regular expression. Example: when parsing a log file whose lines follow the usual log pattern (e.g. "[1484383442] ERROR: some data"), we want to be able to select all the lines individually .---, .---, (`%`, `` to split all the lines), keep those that |alt|+| s | start with a bracketed time-stamp (`^\[`), but `---' `---' exclude the debug messages (`DEBUG`). Of course, it's possible to come up with a regular expression to match those simple requirements, but it would take more work to write it than to organically apply filters on a general selection, individually. =[ SELECTION DUPLICATION .---, Duplicating content can be achieved using a widely | y | implemented concept: yanking and pasting. Yanking the `---' current selection (`y`) into the copy register allows the .---, user to subsequently insert the copied text in the buffer | p | (`p`). `---' .---, Note that the default "paste" primitive will insert the | P | contents of the copy register after the current selection, `---' if you want copied test to be inserted before the current selection then you can use the `P` key. =[ REPLACING SELECTIONS Text replacement is a two step process in Kakoune, which involves selecting text to be replaced, and then erasing it .---, to insert the replacement text. After selections have been | c | made, you can simply hit the deletion primitive (`d`), then `---' either enter insert mode to write down the replacement text (`i`), or stay in command mode to paste the replacement text stored in the copy register. As deleting and entering .---, insert mode can be redundant, a primitive that implements | R | deletion followed by insert mode entrance was implemented: `---' `c`. You can also directly replace the current selection with the content of the copy register using a primitive also implemented for that purpose: `R`. +=-------------------------------=+ ADVANCED +=-------------------------------=+ =[ SPLITTING The selection primitive (`s`) is a powerful tool to select chunks of data, but sometimes the format of said data isn't .---, uniform enough to allow creating clear cut selections. In | S | order to avoid having to write overly complicated regular `---' expressions that select precisely the wanted text, the splitting primitive (`S`) allows applying a delimiter to the current selection, splitting it into separate chunks. Example: selecting the items in a CSV-style list (e.g. "1,2,3,4") is as simple as selecting the line, then splitting it using the comma separator (`S,`). Note that more advanced splitting is possible, since the delimiter passed to this primitive is a regular expression. =[ ROTATING Often used in conjunction with the splitting primitive (`S`), the rotation primitive (``) shifts all the selections clock-wise. Note that a count (described after) allows the rotation to take place in sub-groups whose size .---, .---, is given by the count parameter. |alt|+| ) | `---' `---' Example: in a numbered list where all the numbers are selected (e.g. `1 2 3 4 5 6 7 8 9 0`), a rotation using this primitive will shift all the numbers by one selection forward, while leaving the original multiple selection untouched (e.g. `0 1 2 3 4 5 6 7 8 9`). =[ COUNTS .---, In order to pass a count to a primitive, simply type the |0-9|_. number out before hitting the primitive key/combination. `---' |`.---, Counts allow primitives to specialize or extend their | | g | original functionality by using it as a parameter, | `---' acting on their side effect. |`.---, | | G | Example: in order to respectively jump or select up to a | `---' particular line, pass the line number to the `g` or `G` |`.---, primitives (e.g. `42g` or `7G`). | | o | | `---' Example: creating an arbitrary amount of new lines `.---, above or below the current line and spawning a new selection | O | for each of them is achieved by passing the amount of lines `---' as a count respectively to the `o` and `O` primitives. =[ REGISTERS Similarly to counts, registers influence the behavior of .---, certain primitives. They are storage structures identified | " |_. by a single character, and are populated by primitives as a `---' `.---, result of a side effect. Although primitives populate a |a-z| specific register by default, it's possible to modify which `---' is going to be populated upon execution using the double quote (`"`) primitive, and subsequently hitting a key that .---, will serve as identifier. | * | `---' Example: the smart search primitive (`*`) uses the current selection as a search pattern, which will be saved to the .---, `/` register. In order to use this primitive to execute a | " |_. .---, temporary search, one could make this primitive save the `---' `| _ | pattern to a different register, to preserve the default one `---' e.g. `"m*` to save the pattern to the `m` register, or even `"_*` to save the pattern to a "null" register, which not store anything written to it. ==[ CAPTURE GROUPS Although registers can pass as mere buffer metadata, .---, .---, they are an integral part of an editing session. The |ctl|+| r | `` key combination allows to insert into the buffer `---' `---' the value of a register, whose identifier is typed right after the combination. .---, .---, Example: inserting the name of the current buffer in insert |ctl|+| r |_. mode can be achieved using the `%` register, which holds `---' `---' `.---, this information: `%`. | % | `---' Another kind of registers that is set automatically are the numbered registers, which hold the values of the groups matched in the last search or select operation (`/` and .---, .---, `s` primitives). |ctl|+| r |_. `---' `---' `.---, Example: when using the search primitive (`/`) with a |0-9| regular expression containing groups to match a list of `---' first and last names (e.g. `(\w+) (\w+)` on `John Doe`), issuing `1` would insert the first name (`John`), and `2` the last name (`Doe`). =[ CUSTOM SELECTIONS Despite the ability to select bits of data using regular expressions, there are times when using them isn't enough, and additional manual editing of the selections is .---, needed. In order to loop through all the selections and | ) | remove the current one, two primitives are available: `---' respectively the parenthesis (`)`), and the alt/space key combination (``). .---, .---, |alt|+|spc| Example: given a list of three numbers all selected `---' `---' individually, (e.g. `1 2 3`), deselecting the second selection would be done by hitting the parenthesis primitive (`)`) until the according selection is the current one, then hitting `` to end up with only the first and third number selected. However, being able to trim out some selections out .---, of a bigger set isn't always convenient, as it doesn't | ^ | allow more advanced constructs such as combining sets of `---' multiple-selections that result from different regular .---, expressions. To allow that, the save mark (`Z`) and append | Z | mark (``) come in handy, as they respectively save `---' the current selection to the mark register (`^`), and show a menu that allows appending the current selection .---, .---, to the mark register upon hitting the `a` key. That way, |alt|+| z |_. it becomes possible to chain and save (append) several `---' `---' `.---, selections made using completely different methods | a | (select, split etc) without being forced to preserve `---' them at all times. .---, | z | Restoring a mark saved to the mark register using those `---' primitives can be achieved by using the restore mark primitive (`z`). =[ LEVERAGING SHELL COMMANDS UNIX systems provide with some tools whose purpose is to interact with raw data, and being a UNIX compliant .---, aspiring tool itself, Kakoune allows leveraging those | | | tools to modify a buffer's contents. Upon invoking the pipe `---' primitive (`|`), an input field pops up which prompts for a shell command, to which the selections will individually be sent through the command's standard input. Example: wrapping a selection can be achieved by invoking the `fold` utility, e.g. `|fold -w80`. You could also want to see a patch of all the modifications made to the buffer since it was last saved: `%|diff -u % -`. Note that the `%` has to be typed interactively, as it will insert the name name of the buffer into the command. Another equally useful primitive that doesn't depend on .---, the contents of the current selections is the exclamation | ! | mark primitive (`!`), which simply insert the output of `---' the given shell command before each selection. Example: in order to insert the date of the day at the beginning of the current buffer, one could use `gg` followed with `!date`. But not all shell-related primitives insert data into the current buffer, the `$` key is in fact a way to .---, apply a predicate to all selections, in order to filter | $ | them out. The command passed to this primitive will be `---' executed in a new shell using each individual selection for context, which will either be kept if the command returned a successful exit code (zero) or dropped otherwise (any non-zero value). Example: after selecting all the lines in a buffer and splitting them individually (`%`, ``), keeping every odd numbered line can be achieved with the following sequence: `$` `[ $((kak_reg_hash)) -ne 0 ]`. =[ REPEATING ACTIONS ==[ PUNCTUAL INTERACTIONS In order to modify text efficiently or insert redundant bits of data, two primitives are available. The dot `.` .---, primitive repeats the last change that was made in insert | . | mode (e.g. writing down text after hitting the insert `---' primitive `i`). Similarly, repeating the last selection (make with e.g. the find primitive `f`) can be achieved using the `` primitive. Example: to select a paragraph to append a newline .---, .---, character to it and cycle through the following paragraphs |alt|+| . | to repeat the same insertion an arbitrary amount of times, `---' `---' one would first select the paragraph with `]p`, append a newline to it `a`, then repeat both operations as needed with `` and `.` respectively. ==[ COMPLEX CHANGES Transforming successive chunks of formatted data can .---, be cumbersome when done manually, and lack hindsight | q | when writing a script for that particular purpose `---' non-interactively. The middle ground between the two .---, solutions is to record the modifications made to one | Q | chunk interactively, and replay the sequence of keys `---' at will. The sequence in question is a macro: the `q` primitive will create a new one (i.e. record all the keys .---, .---, hit henceforth until the escape key `` is hit), and |ctl|+| r |_. the `Q` primitive will replay the keys saved in the macro. `---' `---' `.---, | @ | Notes: macros can easily be translated into a proper `---' script, as they are saved in the `@` register, which you can insert into a buffer using `@`. kakoune-2019.07.01/contrib/Tupfile000066400000000000000000000025731350637360100165560ustar00rootroot00000000000000## ## Tupfile for kakoune ## by lenormf ## ## How to use: ## Initialize a tup database in the main directory with `tup init` ## Create a symlink from `contrib/Tupfile` to `src/Tupfile` ## Start the build with the `tup` command ## .gitignore debug = yes static = no suffix = .opt CXX = g++ CXXFLAGS = -pedantic -std=gnu++14 -Wall -Wno-unused-parameter -Wno-reorder -Wno-sign-compare -Wno-address -Wno-noexcept-type -Wno-unknown-attributes -Wno-unknown-warning-option CPPFLAGS = LDFLAGS = LIBS = ifeq ($(debug),yes) CXXFLAGS += -g CPPFLAGS += -DKAK_DEBUG suffix = .debug else CXXFLAGS += -O3 endif ifeq ($(static),yes) LIBS += -ltinfo -lgpm LDFLAGS += -static -pthread endif ifeq (@(TUP_PLATFORM),macosx) LIBS += -lncurses CPPFLAGS += -I/usr/local/opt/ncurses/include LDFLAGS += -L/usr/local/opt/ncurses/lib else ifeq (@(TUP_PLATFORM),win32) LIBS += -lncursesw -ldbghelp CPPFLAGS += -D_XOPEN_SOURCE=700 else LIBS += `pkg-config --libs ncursesw` CPPFLAGS += `pkg-config --cflags ncursesw` ifeq ($(CXX),g++) LDFLAGS += -rdynamic endif endif endif ifeq ($(CXX),clang++) CXXFLAGS += -Wno-unknown-attributes endif !cxx = |> $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c %f -o %o |> !ld = |> $(CXX) $(LDFLAGS) $(LIBS) %f -o %o |> !ln = |> ln -sf %f %o |> :foreach *.cc |> !cxx |> .%B$(suffix).o {objects} :{objects} |> !ld |> kak$(suffix) :kak$(suffix) |> !ln |> kak kakoune-2019.07.01/contrib/describe_sessions.sh000077500000000000000000000045251350637360100212670ustar00rootroot00000000000000#!/bin/sh ## ## describe_sessions.sh for kakoune ## by lenormf ## readonly KAK_SCRIPT=' { echo printf "Session: %s\n" "${kak_session}" printf "Current working directory: %s\n" "${PWD}" eval set -- "${kak_buflist}" printf "Buffers (%d):\n" $# for bufname in "$@"; do printf "\t%s\n" "${bufname}" done eval set -- "${kak_client_list}" printf "Clients (%d):\n" $# for clientname in "$@"; do printf "\t%s\n" "${clientname}" done } >>{{outfile}} rm -rf {{sentinel}} ' main() { outfile=$(mktemp "${TMPDIR:-/tmp}"/kak-describe_sessions.XXXXXXXX) nb_sessions=0 nb_dead_sessions=0 nb_suspended_sessions=0 if ! command -v socat >/dev/null 2>&1; then echo "Unmet dependency: socat" >&2 exit 1 fi script=$(printf 'nop %%sh{ %s }' "${KAK_SCRIPT}" | sed "s,{{outfile}},\"${outfile}\",g") for session in "${TMPDIR:-/tmp}/kakoune/${USER}"/*; do name_session="${session##*/}" if printf '' | socat - UNIX-CONNECT:"${session}",connect-timeout=1 2>/dev/null; then sentinel=$(mktemp -d "${TMPDIR:-/tmp}"/kak-sentinel.XXXXXXXX) script_session=$(printf %s "${script}" | sed "s,{{sentinel}},\"${sentinel}\",g") if ! printf %s "${script_session}" | kak -p "${name_session}"; then printf '\nSession "%s" dead\n' "${name_session}" >> "${outfile}" nb_dead_sessions=$((nb_dead_sessions + 1)) continue fi wait_limit=2 while ! mkdir "${sentinel}" 2>/dev/null && [ "${wait_limit}" -gt 0 ]; do wait_limit=$((wait_limit - 1)) sleep 1 done rm -rf "${sentinel}" if [ "${wait_limit}" -gt 0 ]; then nb_sessions=$((nb_sessions + 1)) else printf '\nSession "%s" suspended\n' "${name_session}" >> "${outfile}" nb_suspended_sessions=$((nb_suspended_sessions + 1)) fi else nb_dead_sessions=$((nb_dead_sessions + 1)) fi done printf 'Running sessions: %d\nSuspended sessions: %d\nDead sessions: %d\n' \ "${nb_sessions}" "${nb_suspended_sessions}" "${nb_dead_sessions}" cat "${outfile}" rm -f "${outfile}" } main "$@" kakoune-2019.07.01/contrib/kakmap.rb000077500000000000000000000034551350637360100170170ustar00rootroot00000000000000#!/usr/bin/env ruby # Generate a reference sheet for Kakoune's normal mode # Use: ./kakmap.rb ../src/normal.cc require 'markaby' # Relies on the keymap HashMap assignment ending with }; raw = ARGF.read.split( /const\s+HashMap\s+keymap\s*{/ ).last.split( /^};$/ ).first commands = {} raw.split( /\n+/ ).each{ |line| # skip empty or comment line line = line.strip if line.empty? or /^\/\// =~ line next end # match key mapping line /^\{\s*\{(?[^}]+)\}\s*,\s*\{\s*"(?[^"]+)"/.match(line) do |m| modAndKey = m['mdky'] des = m['dsc'] modAndKey.gsub!(/\s*\/\*[^*]+\*\/\s*/, '') # remove comment in key definition # match key and modifier /Key::(?\w+)|(?alt|ctrl)\('\\?(?.+?)'\)|'\\?(?.+?)'$/.match(modAndKey) do |sm| key = sm['key'] mod = (sm['mod'] || 'none').to_sym key = 'Space' if key == ' ' commands[key] ||= {} commands[key][mod] = des end end } # sort, showing single characters first, symbols next and spelled out keys last commands = commands.sort_by{ |key, _| case key when /^\w$/ key.upcase + key.swapcase when /^\W$/ '_' + key else '~~' + key end } puts Markaby::Builder.new { html do head do title "Kakoune default keymap" end body do table :style => "border-collapse: collapse" do thead do tr do th "Key" th "Description" th "ALT + key" th "CTRL + key" end end tbody do for key, binding in commands tr :style => "border-bottom: 1px solid #fbfbfb" do th key td binding[:none] td binding[:alt] td binding[:ctrl] end end end end end end } kakoune-2019.07.01/contrib/kakoune.spec000066400000000000000000000031571350637360100175330ustar00rootroot00000000000000Name: kakoune Version: 2019.01.20 Release: 1%{?dist} Summary: Vim inspired editor License: Unlicense URL: http://kakoune.org/ Source0: %{name}-%{version}.tar.bz2 BuildRequires: ncurses-devel >= 5.3 BuildRequires: asciidoc BuildRequires: gcc-c++ BuildRequires: glibc-langpack-en Requires: ncurses-libs >= 5.3 %description Kakoune is a code editor heavily inspired by Vim %prep %setup -qn %{name}-%{version} %build cd src make %{?_smp_mflags} %check cd src LANG=en_US.utf8 make test %install cd src %make_install PREFIX=/usr %files %doc %{_bindir}/* %{_mandir}/man1/kak* %{_datadir}/doc/kak/* %{_datadir}/kak/* %changelog * Wed Apr 24 2019 Jiri Konecny - v2019.01.20-1 - Add a new build dependency (glibc-langpack-en) required for Fedora 30 and later - Update version * Fri Oct 12 2018 Jiri Konecny - v2018.09.04-1 - Update spec file to a new release * Sat May 5 2018 Łukasz Jendrysik - v2018.04.13 - Use tagged release * Wed May 11 2016 jkonecny - 0-208.20160511git84f62e6f - Add LANG=en_US.UTF-8 to fix tests - Update to git: 84f62e6f * Thu Feb 11 2016 jkonecny - 0-158.20160210git050484eb - Add new build requires asciidoc - Use new man pages * Sat Mar 28 2015 jkonecny - 0-5.20150328gitd1b81c8f - Automated git update by dgroc script new hash: d1b81c8f * Tue Mar 24 2015 Jiri Konecny 0-1.7eaa697git - Add tests * Tue Mar 17 2015 Jiri Konecny 0-1.12a732dgit - Create first rpm for kakoune kakoune-2019.07.01/contrib/tmux-256color.terminfo000066400000000000000000000053151350637360100213330ustar00rootroot00000000000000tmux-256color|tmux with 256 color and palette setting, am, hs, km, mir, msgr, xenl, colors#256, cols#80, it#8, lines#24, pairs#32767, acsc=++\,\,--..00``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~, bel=^G, blink=\E[5m, bold=\E[1m, cbt=\E[Z, ccc, civis=\E[?25l, clear=\E[H\E[J, cnorm=\E[34h\E[?25h, cr=^M, csr=\E[%i%p1%d;%p2%dr, cub=\E[%p1%dD, cub1=^H, cud=\E[%p1%dB, cud1=^J, cuf=\E[%p1%dC, cuf1=\E[C, cup=\E[%i%p1%d;%p2%dH, cuu=\E[%p1%dA, cuu1=\EM, cvvis=\E[34l, dch=\E[%p1%dP, dch1=\E[P, dim=\E[2m, dl=\E[%p1%dM, dl1=\E[M, dsl=\E]0;\007, ed=\E[J, el=\E[K, el1=\E[1K, enacs=\E(B\E)0, flash=\Eg, fsl=^G, home=\E[H, hpa=\E[%i%p1%dG, ht=^I, hts=\EH, ich=\E[%p1%d@, il=\E[%p1%dL, il1=\E[L, ind=\n, indn=\E[%p1%dS, initc=\E]4;%p1%d;rgb\:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E\\, invis=\E[8m, is2=\E)0, kDC=\E[3;2~, kEND=\E[1;2F, kHOM=\E[1;2H, kIC=\E[2;2~, kLFT=\E[1;2D, kNXT=\E[6;2~, kPRV=\E[5;2~, kRIT=\E[1;2C, kbs=^H, kcbt=\E[Z, kcub1=\EOD, kcud1=\EOB, kcuf1=\EOC, kcuu1=\EOA, kdch1=\E[3~, kend=\E[4~, kf1=\EOP, kf10=\E[21~, kf11=\E[23~, kf12=\E[24~, kf13=\E[1;2P, kf14=\E[1;2Q, kf15=\E[1;2R, kf16=\E[1;2S, kf17=\E[15;2~, kf18=\E[17;2~, kf19=\E[18;2~, kf2=\EOQ, kf20=\E[19;2~, kf21=\E[20;2~, kf22=\E[21;2~, kf23=\E[23;2~, kf24=\E[24;2~, kf25=\E[1;5P, kf26=\E[1;5Q, kf27=\E[1;5R, kf28=\E[1;5S, kf29=\E[15;5~, kf3=\EOR, kf30=\E[17;5~, kf31=\E[18;5~, kf32=\E[19;5~, kf33=\E[20;5~, kf34=\E[21;5~, kf35=\E[23;5~, kf36=\E[24;5~, kf37=\E[1;6P, kf38=\E[1;6Q, kf39=\E[1;6R, kf4=\EOS, kf40=\E[1;6S, kf41=\E[15;6~, kf42=\E[17;6~, kf43=\E[18;6~, kf44=\E[19;6~, kf45=\E[20;6~, kf46=\E[21;6~, kf47=\E[23;6~, kf48=\E[24;6~, kf49=\E[1;3P, kf5=\E[15~, kf50=\E[1;3Q, kf51=\E[1;3R, kf52=\E[1;3S, kf53=\E[15;3~, kf54=\E[17;3~, kf55=\E[18;3~, kf56=\E[19;3~, kf57=\E[20;3~, kf58=\E[21;3~, kf59=\E[23;3~, kf6=\E[17~, kf60=\E[24;3~, kf61=\E[1;4P, kf62=\E[1;4Q, kf63=\E[1;4R, kf7=\E[18~, kf8=\E[19~, kf9=\E[20~, khome=\E[1~, kich1=\E[2~, kind=\E[1;2B, kmous=\E[M, knp=\E[6~, kpp=\E[5~, kri=\E[1;2A, nel=\EE, op=\E[39;49m, rc=\E8, rev=\E[7m, ri=\EM, ritm=\E[23m, rmacs=^O, rmcup=\E[?1049l, rmir=\E[4l, rmkx=\E[?1l\E>, rmso=\E[27m, rmul=\E[24m, rs2=\Ec\E[?1000l\E[?25h, sc=\E7, setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m, setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m, sgr=\E[0%?%p6%t;1%;%?%p1%t;7%;%?%p2%t;4%;%?%p3%t;7%;%?%p4%t; 5%;%?%p5%t;2%;m%?%p9%t\016%e\017%;, sgr0=\E[m\017, sitm=\E[3m, smacs=^N, smcup=\E[?1049h, smir=\E[4h, smkx=\E[?1h\E=, smso=\E[7m, smul=\E[4m, tbc=\E[3g, tsl=\E]0;, vpa=\E[%i%p1%dd, kakoune-2019.07.01/doc/000077500000000000000000000000001350637360100143215ustar00rootroot00000000000000kakoune-2019.07.01/doc/autoedit.asciidoc000066400000000000000000000074421350637360100176460ustar00rootroot00000000000000Edition auto insertion in Kakoune ================================= It is a quite common feature for code editor to help the programmer by automatically inserting some text in certain contexts. This document goal is to explain how this is done in Kakoune. There is no special support in Kakoune for this problem, hooks are expected to be used in order to manage that, and the normal kakoune editing command are expected to be expressive enough so that relatively complex indentation can be written concisely. The main hook is *InsertChar*, which gets called immediately _after_ a character has been inserted in insertion mode due to the user pressing the corresponding key. Previous line indentation ------------------------- Let's see a simple indent hook: preserving the previous line indentation. Here is the Kakoune normal mode key list in order to do that: ---------------------------------------------------------------- k # 1. go to previous line and select it s^\h+y # 2. select the leading spaces and copy them jP # 3. go back to next line start and paste the spaces ---------------------------------------------------------------- note that if nothing gets selected on phase *2.*, an error will be raised. We want to do that each time the user jumps a line, just after the new line is inserted. So the hook would be: -------------------------------------------------------- :hook InsertChar \n %{ exec k s^\h+y jP } -------------------------------------------------------- (exec concatenates the keys for all argument, so the spaces will be ignored, allowing for clearer separation. either use or quote the argument to use a space key) That works, however if the phase *2.* raises an error, the +:exec+ will stop and the user will get its selections on the previous line. The solution is to use a *draft* context, instead of the one the user is interacting with. --------------------------------------------------------------- :hook InsertChar \n %{ exec -draft k s^\h+y jP } --------------------------------------------------------------- That way, exec is executed in a *copy* of the user's context, which means it manipulates a *copy* of the user's selections. Increasing indentation ---------------------- A little bit more complicated is to increase indentation whenever we insert a new line after a +{+ or a +(+. The complexity arises from the presence of a condition. We want to increase the indentation *only* if the previous line ends with +{+ or +(+. Fortunately, Kakoune provides us with a command for that: the ++ command, which keeps selections where a certain regex can be found. Here is how we can do that: ------------------------------------------------------------------------------- k # 1. select the previous line [{(]\h*$ # 2. keep selections that end with { or ( followed by blanks j # 3. go back to next line and indent it even if it is empty ------------------------------------------------------------------------------- Note that if no previous lines end with a +{+ or +(+, the ++ command will raise an error, and stop the execution. This is what we want: it is similar to what would happen if we would continue with no selections; the following commands would have no effects. However, the error would end up being caught by the hook execution code, and it will write informations about it in the debug buffer, which we do not want, as this is actually expected. In order to prevent that, the exec should be wrapped in a try command. So we would have: ------------------------------------------------------------------------------- :hook InsertChar \n %[ try %[ exec -draft k [{(]\h*$ j ] ] ------------------------------------------------------------------------------- kakoune-2019.07.01/doc/coding-style.asciidoc000066400000000000000000000021151350637360100204210ustar00rootroot00000000000000C++ Coding Style ================ Kakoune is written in C++14, here are the main coding style points: * Avoid external dependencies besides posix/stdc++/ncurses * 4 spaces for indentation, no tabs * public interface before private methods/data when defining a class * use +override+ keyword for overridden virtual methods * opening brackets on their own lines by default, except when declaring an object where the opening bracket follows the equal sign. * use alternative logical operator names (and, or, not instead of &&, ||, !) ----- int func() { if (condition) { ... } else statement; } int array[] = { ... }; ----- * End lines with an operator when continuing on the next line ---- if (condition1 or condition2) ---- * Try to keep under 80 columns, even though this is not a strict limit. * CamelCase for types, snake_case for variables/function names * prefix fields with m_, static ones with ms_ except for dumb structs (struct with every field public) where these prefixes can be dropped. * use const and constexpr liberally kakoune-2019.07.01/doc/design.asciidoc000066400000000000000000000142511350637360100172750ustar00rootroot00000000000000Kakoune design ============== This document describes the design goals for Kakoune, including rationales. Interactivity ------------- Unlike Vim, Kakoune does not have an underlying line-oriented editor, and is always expected to be used in an interactive (i.e. with the edited text being displayed in real time) fashion. That should not prevent Kakoune from being used non interactively (executing macro for example), but priority should be given to ease of interactive use. Limited scope ------------- Kakoune is a code editor. It is not an IDE, not a file browser, not a word processor and not a window manager. It should be very efficient at editing code, and should, as a side effect, be very efficient at editing text in general. Composability ------------- Being limited in scope to code edition should not isolate Kakoune from its environment. On the contrary, Kakoune is expected to run on a Unix-like system, along with a lot of text-based tools, and should make it easy to interact with these tools. For example, sorting lines should be done using the Unix sort command, not with an internal implementation. Kakoune should make it easy to do that, hence the +|+ command for piping selected text through a filter. The modern Unix environment is not limited to text filters, most people use a graphical interface nowadays, and Kakoune should be able to take advantage of that, without hindering text mode support. For example Kakoune supports multiple clients on the same editing session, so that multiple windows can be used, letting the system window manager handle its responsibilities such as tiling or tabbing. Orthogonality ------------- Kakoune features should be as orthogonal as possible, for example, in Vim, there are multiple ways for modifying the buffer: Through normal/insert mode, command mode, and Vim scripts. In Kakoune, modifying the buffer is the normal/insert mode job. That means there should be clear separation of concerns between modes: * normal mode is for manipulating the selection and the selection contents. * insert mode is for interactive insertion into the buffer. * command mode is for non-editing features (opening a file, setting options...). Orthogonality is an ideal, and should not prevent common sense pragmatism, the +gf+ and +ga+ commands are not strictly selection manipulation ones, but fit nicely with other +goto+ commands, and hence are acceptable in normal mode even though they could arguably be moved to command mode. Modes should be orthogonal, and commands in modes should be as well. For example, Vim uses +d+ and +x+ for very similar things: deleting text. In Kakoune only +d+ exists, and the design ensures that +x+ is not needed. Speed ----- Kakoune should be fast, fast to use, as in a lot of editing in a few keystrokes, and fast to execute. * Vim is the benchmark here, most editing tasks should be doable in less or the same number of keys. * Kakoune be designed with asynchronicity in mind, launching a background process and using its result when available should not block the editor. * Kakoune should be implemented with speed in mind, a slow editor is a useless one. Simplicity ---------- Simplicity is nice, simplicity correlates with orthogonality and speed, and makes things easier to understand, bugs easier to fix, and code easier to change. * *No threading*: multithreading is a hard problem, and is not well suited to a text editor: - Either we want a direct result, and we need to be synchronous with the user, so getting a 4x speed up is meaningless, we need to have an algorithm which appears instantaneous the user. - Or we want an asynchronous result, and then the processing is best left to a helper command which can be reused with other Unix tools. * *No binary plugins*: shared object by themselves add a lot of complexity. Plugins add another interface to Kakoune, and goes against orthogonality. The +%sh{ ... }+ and socket interface should be made good enough for most plugin use cases. - It is better to write Kakoune-independent helper tools (intelligent code completer, source code navigation programs) that can interact with Kakoune through the shell than write them in a plugin. * *No integrated scripting language*: for the same reason as binary plugins. * *Limited smartness*: Kakoune should not try to be too smart, being smart is often unpredictable for the user, and makes things context dependent. When Kakoune tries to be smart, it should provide the alternative, 'non smart' version (+\*+ tries to detect word boundaries on the selection, but +alt-*+ permits to avoid this behavior). Unified interactive use and scripting ------------------------------------- As both an effect of Orthogonality and Simplicity, normal mode is *not* a layer on top of a text editing language layer (normal mode keys are *not* bound to text editing commands), normal mode *is* the text editing language. That means there is no +delete-selected-text+ command that +d+ is bound to, +d+ *is* the +delete selected text+ command. This permits to have scripting use case and interactive use cases share the same text editing language. Both use normal mode to express complex edition. Besides promoting simplicity by avoiding the introduction of another layer, this helps ensure the interactive editing language is as expressive as possible as we need to make it able to handle complex use cases, such as indentation hooks. Language agnostic ----------------- Kakoune should not be tailored for writing in a specific programming language. Support for different languages should be provided by a kak script file, built-in language support should be avoided. Self documenting ---------------- Kakoune should be able to document its features, live documentation along with an extensive suggestion/completion system provides the discoverability which is often lacking in non GUI tools. Documentation should as much as possible be integrated with the code so that it stays up to date. Vim compatibility ----------------- Kakoune is inspired by Vim, and should try to keep its commands close to Vim's if there are no compelling reasons to change. However self-consistency is more important than Vim compatibility. kakoune-2019.07.01/doc/interfacing.asciidoc000066400000000000000000000116021350637360100203120ustar00rootroot00000000000000Interfacing Kakoune with external programs ========================================== In order to interact with the external world, Kakoune uses the shell, mainly through the +%sh{ ... }+ string type, and its control socket. Basic interaction ----------------- For synchronous operations, +%sh{ ... }+ blocks are easy to use, they behave similarly to +$( ... )+ shell construct. For example, one can echo the current time in Kakoune's status line using: [source,bash] ---- :echo %sh{ date } ---- For asynchronous operations, the Kakoune Unix stream socket can be used. This is the same socket that Kakoune clients connect to. It is available through the +kak_session+ environment variable: the socket is +/tmp/kakoune/${username}/${kak_session}+ For example, we can echo a message in Kakoune in 10 seconds with: [source,bash] ---- :nop %sh{ { sleep 10 echo "eval -client '$kak_client' 'echo sleep ended'" | kak -p ${kak_session} } > /dev/null 2>&1 < /dev/null & } ---- * The +nop+ command is used so that any eventual output from the +%sh{ ... }+ is not interpreted by Kakoune * When writing to the socket, Kakoune has no way to guess in which client's context the command should be evaluated. A temporary context is used, which does not have any user interface, so if we want to interact with the user, we need to use the +eval+ command, with its +-client+ option to send commands to a specific client. * For the command to run asynchronously, we wrap it in a sub shell with braces, redirect its +std{in,err,out}+ to +/dev/null+, and run it in background with +&+. Using this pattern, the shell does not wait for this sub shell to finish before quitting. Interactive output ------------------ It is a frequent interaction mode to run a program and display its output in a Kakoune buffer. The common pattern to do that is to use a fifo buffer: [source,bash] ----- evaluate-commands %sh{ # Create a temporary fifo for communication output=$(mktemp -d -t kak-temp-XXXXXXXX)/fifo mkfifo ${output} # run command detached from the shell { run command here > ${output} } > /dev/null 2>&1 < /dev/null & # Open the file in Kakoune and add a hook to remove the fifo echo "edit! -fifo ${output} *buffer-name* hook buffer BufClose .* %{ nop %sh{ rm -r $(dirname ${output})} }" } ----- This is a very simple example, most of the time, the echo command will as well contain ----- set buffer filetype <...> ----- and some hooks for this filetype will have been written Completion candidates --------------------- Filetype specific completion should be provided by external programs. External completions are provided using an option to store completion, which have the following format. ---- line.column[+len]@timestamp candidate1|select1|menu1 candidate2|select2|menu2 ... ---- the first element of this string list specify where and when this completion applies, the others are a triplet `||` candidates, except for the first element which follows the `.[+]@` format to define where the completion apply in the buffer. Select commands are arbitrary kakoune commands that will be executed each time the element is selected in the menu. The common use case is to display element specific documentation. Markup can be used in the menu text. (see <>) `set -add` adds a new completion to the list *enum(value1|value2|...)*:: an enum, taking one of the given values Cannot be used with `declare-option` *flags(value1|value2|...)*:: a set of flags, taking a combination of the given values joined by a '|' character. `set -add` adds the new flag to the combination Cannot be used with `declare-option` *-to--map*:: a list of `key=value` pairs. `set -add` adds the new pair to the hashmap or replace an already existing key. Only `str-to-str-map` options can be created with `declare-option`. == Builtin options *tabstop* `int`:: _default_ 8 + width of a tab character *indentwidth* `int`:: _default_ 4 + width (in spaces) used for indentation, 0 means a tab character *scrolloff* `coord`:: _default_ 0,0 + number of lines, columns to keep visible around the cursor when scrolling *eolformat* `enum(lf|crlf)`:: _default_ lf + the format of end of lines when writing a buffer, this is autodetected on load; values of this option assigned to the `window` scope are ignored *BOM* `enum(none|utf8)`:: _default_ none + define if the file should be written with a unicode byte order mark; values of this option assigned to the `window` scope are ignored *readonly* `bool`:: _default_ false + prevent modifications from being saved to disk, all buffers if set to `true` in the `global` scope, or current buffer if set in the `buffer` scope; values of this option assigned to the `window` scope are ignored *incsearch* `bool`:: _default_ true + execute search as it is typed *aligntab* `bool`:: _default_ false + use tabs for alignment command *autoinfo* `flags(command|onkey|normal)`:: _default_ command|onkey + display automatic information box in the enabled contexts *autocomplete* `flags(insert|prompt)`:: _default_ insert|prompt + automatically display possible completions in the enabled modes. *ignored_files* `regex`:: filenames matching this regex won't be considered as candidates on filename completion (except if the text being completed already matches it) *disabled_hooks* `regex`:: hooks whose group matches this regex won't be executed. For example indentation hooks can be disabled with `.*-indent`. (See <>) *filetype* `str`:: arbitrary string defining the type of the file. Filetype dependent actions should hook on this option changing for activation/deactivation *path* `str-list`:: _default_ ./ %/ /usr/include + directories to search for *gf* command and filenames completion `%/` represents the current buffer directory *completers* `completer-list`:: _default_ filename word=all + completion engines to use for insert mode completion (they are tried in order until one generates candidates). Existing completers are: *word=all*, *word=buffer*::: which complete using words in all buffers (*word=all*) or only the current one (*word=buffer*) *filename*::: which tries to detect when a filename is being entered and provides completion based on local filesystem *line*::: which complete using lines in current buffer *option=*::: where *opt-name* is an option of type 'completions' whose contents will be used *static_words* `str-list`:: list of words that are always added to completion candidates when completing words in insert mode *extra_word_chars* `codepoint-list`:: a list of all additional codepoints that should be considered as word character. *matching_pairs* `codepoint-list`:: _default_ ( ) { } [ ] < > + a list of codepoints that are to be treated as matching pairs for the *m* command. *autoreload* `enum(yes|no|ask)`:: _default_ ask + auto reload the buffers when an external modification is detected *writemethod* `enum(overwrite|replace)`:: _default_ overwrite + method used to write buffers to file, `overwrite` will open the existing file and write on top of the previous data, `replace` will open a temporary file next to the target file, write it and then rename it to the target file. *debug* `flags(hooks|shell|profile|keys|commands)`:: dump various debug information in the '\*debug*' buffer *idle_timeout* `int`:: _default_ 50 + timeout, in milliseconds, with no user input that will trigger the *PromptIdle*, *InsertIdle* and *NormalIdle* hooks, and autocompletion. *fs_checkout_timeout* `int`:: _default_ 500 + timeout, in milliseconds, between checks in normal mode of modifications of the file associated with the current buffer on the filesystem. *modelinefmt* `string`:: A format string used to generate the mode line, that string is first expanded as a command line would be (expanding '%...{...}' strings), then markup tags are applied (see <>) Two special atoms are available as markup: *`{{mode_info}}`*::: Information about the current mode, such as `insert 3 sel` or `prompt`. The faces used are StatusLineMode, StatusLineInfo, and StatusLineValue. *`{{context_info}}`*::: Information such as `[+][recording (@)][no-hooks][new file][fifo]`, in face Information. The default value is '%val{bufname} %val{cursor_line}:%val{cursor_char_column} {{context_info}} {{mode_info}} - %val{client}@[%val{session}]' *ui_options* `str-to-str-map`:: a list of `key=value` pairs that are forwarded to the user interface implementation. The NCurses UI support the following options: *ncurses_set_title*::: if *yes* or *true*, the terminal emulator title will be changed *ncurses_status_on_top*::: if *yes*, or *true* the status line will be placed at the top of the terminal rather than at the bottom *ncurses_assistant*::: specify the nice assistant displayed in info boxes, can be *clippy* (the default), *cat*, *dilbert* or *none* *ncurses_enable_mouse*::: boolean option that enables mouse support *ncurses_change_colors*::: boolean option that can disable color palette changing if the terminfo enables it but the terminal does not support it. *ncurses_wheel_down_button*, *ncurses_wheel_up_button*::: specify which button send for wheel down/up events *ncurses_shift_function_key*::: Function key from which shifted function key start, if the terminal sends F13 for , this should be set to 12. *ncurses_builtin_key_parser*::: Bypass ncurses key parser and use an internal one. [[startup-info]] *startup_info_version* `int`:: _default_ 0 + Controls which messages will be displayed in the startup info box, only messages relating to a Kakoune version greater than this value will be displayed. Versions are written as a single number: Like `20180413` for version `2018.04.13` == Current values The current value for an option can be viewed using <>. For example, the current value of the `BOM` option can be displayed in the status line using the `echo` command: -------------- echo %opt{BOM} -------------- The current values for all options can be dumped to the *\*debug*\* buffer using the following command: ------------- debug options ------------- kakoune-2019.07.01/doc/pages/regex.asciidoc000066400000000000000000000161351350637360100202400ustar00rootroot00000000000000= Regex == Regex Syntax Kakoune regex syntax is based on the ECMAScript syntax, as defined by the ECMA-262 standard (see <>). Kakoune's regex always run on Unicode codepoint sequences, not on bytes. == Literals Every character except the syntax characters `\^$.*+?[]{}|().` match themselves. Syntax characters can be escaped with a backspace so `\$` will match a literal `$` and `\\` will match a literal `\`. Some literals are available as escape sequences: * `\f` matches the form feed character. * `\n` matches the line feed character. * `\r` matches the carriage return character. * `\t` matches the tabulation character. * `\v` matches the vertical tabulation character. * `\0` matches the null character. * `\cX` matches the control-X character (X can be in `[A-Za-z]`). * `\xXX` matches the character whose codepoint is XX (in hexadecimal). * `\uXXXX` matches the character whose codepoint is XXXX (in hexadecimal). == Character classes The `[` character introduces a character class, matching one character from a set of characters. A character class contains a list of literals, character ranges, and character class escapes surrounded by `[` and `]`. If the first character inside a character class is `^`, then the character class is negated, meaning that it matches every character not specified in the character class. Literals match themselves, including syntax characters, so `^` does not need to be escaped in a character class. `[*+]` matches both the `*` character and the `+` character. Literal escape sequences are supported, so `[\n\r]` matches both the line feed and carriage return characters. The `]` character needs to be escaped for it to match a literal `]` instead of closing the character class. Character ranges are written as `-`, so `[A-Z]` matches all upper case basic letters. `[A-Z0-9]` will match all upper cases basic letters and all basic digits. The `-` characters in a character class that are not specifying a range are treated as literal `-`, so `[A-Z-+]` matches all upper case characters, the `-` character, and the `+` character. Supported character class escapes are: * `\d` which matches all digits. * `\w` which matches all word characters. * `\s` which matches all whitespace characters. * `\h` which matches all horizontal whitespace characters. Using an upper case letter instead of a lower case one will negate the character class, meaning for example that `\D` will match every non-digit character. Character class escapes can be used outside of a character class, `\d` is equivalent to `[\d]`. == Any character `.` matches any character, including new lines. == Groups Regex atoms can be grouped using `(` and `)` or `(?:` and `)`. If `(` is used, the group will be a capturing group, which means the positions from the subject strings that matched between `(` and `)` will be recorded. Capture groups are numbered starting at 1. They are numbered in the order of appearance of their `(` in the regex. A special capture group 0 is for the whole sequence that matched. * `(?:` introduces a non capturing group, which will not record the matching positions. * `(?` introduces a named capturing group, which, in addition to being referred by number, can be, in certain contexts, referred by the given name. == Alternations The `|` character introduces an alternation, which will either match its left-hand side, or its right-hand side (preferring the left-hand side) For example, `foo|bar` matches either `foo` or `bar`, `foo(bar|baz|qux)` matches `foo` followed by either `bar`, `baz` or `qux`. == Quantifier Literals, Character classes, Any characters and groups can be followed by a quantifier, which specifies the number of times they can match. * `?` matches zero or one times. * `*` matches zero or more times. * `+` matches one or more times. * `{n}` matches exactly n times. * `{n,}` matches n or more times. * `{n,m}` matches n to m times. * `{,m}` matches zero to m times. By default, quantifiers are *greedy*, which means they will prefer to match more characters if possible. Suffixing a quantifier with `?` will make it non-greedy, meaning it will prefer to match as few characters as possible. == Zero width assertions Assertions do not consume any character, but will prevent the regex from matching if they are not fulfilled. * `^` matches at the start of a line, that is just after a new line character, or at the subject begin (except if specified that the subject begin is not a start of line). * `$` matches at the end of a line, that is just before a new line, or at the subject end (except if specified that the subject's end is not an end of line). * `\b` matches at a word boundary, when one of the previous character and current character is a word character, and the other is not. * `\B` matches at a non word boundary, when both the previous character and the current character are word, or are not. * `\A` matches at the subject string begin. * `\z` matches at the subject string end. * `\K` matches anything, and resets the start position of the capture group 0 to the current position. More complex assertions can be expressed with lookarounds: * `(?=...)` is a lookahead, it will match if its content matches the text following the current position * `(?!...)` is a negative lookahead, it will match if its content does not match the text following the current position * `(?<=...)` is a lookbehind, it will match if its content matches the text preceding the current position * `(?*:: when in insert mode or in a prompt, insert the value stored in the *c* register (single character) *"*:: in normal mode, select the ** register (single character) == Alternate names Non alphanumeric registers have an alternative name that can be used in contexts where only alphanumeric identifiers are possible. == Default registers All normal-mode commands using a register default to a specific one if not specified: *"* (dquote):: default delete / copy / paste / replace register, used by: *c*, *d*, *y*, *p*, **, *

*, **, *R* and ** */* (slash):: default search / regex register, used by: */*, **, *?*, **, *n*, **, *N*, **, ***, **, *s*, *S*, ** and ** *@* (arobase):: default macro register, used by: *q* and *Q* *^* (caret):: default mark register, used by: *z*, **, *Z* and ** *|* (pipe):: default shell command register, used by commands that spawn a subshell: *|*, **, *!* and ** == Special registers Some registers are not general purposes, they cannot be written to, but they contain some special data *%* (percent):: current buffer name *.* (dot):: current selection contents *#* (hash):: selection indices (first selection has 1, second has 2, ...) *_* (underscore):: null register, always empty *:* (colon):: last entered command == Integer registers Registers *1* to *9* hold the grouped sub-matches of the regular expression used to make the last selection. Example: applying the following regular expression to the date of the day would put the day of the week in register *1*, the month in register *2*, and the day of the month in register *3*, but select the entire date: -------------------- (\w+) (\w+) (\d+) .+ -------------------- kakoune-2019.07.01/doc/pages/scopes.asciidoc000066400000000000000000000060521350637360100204170ustar00rootroot00000000000000= Scopes == Description Scopes are groups in which a particular Kakoune object can have different values depending on the group the value was declared in. These scoped objects are: - aliases (See <>) - faces (See <>) - highlighters (See <>) - hooks (See <>) - keymaps (See <>) - options (See <>) == Names and hierarchy Scopes are named as follows: *window*:: context linked to the window displaying a buffer. In Kakoune, the concept of a *window* must not be confused with the concept of a window at the OS level. In other terms, a window is *not* a client (like a terminal or GUI) but one of many 'views' into a buffer. There is a N:1 relationship between windows and buffers; once a window is linked to a buffer, the window's buffer never changes. Windows store a set of selections and the scroll position. *buffer*:: context linked directly to the buffer *global*:: global context linked to the instance of Kakoune The following order of priority applies to the above scopes: -------------------------- window ]> buffer ]> global -------------------------- The above priority line implies that objects can have individual values that will be resolved first in the *window* scope (highest priority), then in the *buffer* scope, and finally in the *global* scope (lowest priority). Normally, the *buffer* scope keyword means the scope associated with the currently active buffer, but it's possible to specify any existing buffer by adding an `=` and the value of `%val{buffile}` for that buffer (See <>). For example, to set the `indentwidth` option for the `/etc/fstab` buffer:: ---- set-option buffer=/etc/fstab indentwidth 8 ---- The `set-option` and `unset-option` commands also accept *current* as a valid scope name. It refers to the narrowest scope the option is set in. == Uses The scope paradigm is very useful as it allows the user to customize the behavior of the editor without modifying the configuration globally, as is the case with other editors who only have a single *global* scope by default. Examples: *filetype*:: A single buffer opened in two separate windows can have different filetypes declared in the *window* scope with 'set-option'. (See <>) *status line*:: All the buffers of the current session can have the same information displayed in the status line, except for a specific buffer (the 'modelinefmt' option can be declared in the *global* scope, and customized in the *buffer* scope with 'set-option'. (See <>) == Execution context Some commands work in a specific context that might exclude one or several scopes altogether, consequently ignoring some values of a given object. Example: the *window* scope is never considered when resolving the values of options when writing a buffer (e.g. 'BOM', 'eolformat'). kakoune-2019.07.01/doc/screenshot-i3.gif000066400000000000000000001060061350637360100175010ustar00rootroot00000000000000GIF89aP     "!&#2'"""%$$,++)(&2-(63,333543<<;:95.1. !C8)C=9S=0>A;FE:QG5kP:>>@C>A(Uw>AALLKGGDRMJNQMRRMYTIHNPNMQXXVPPQfXIc]Yu]F^a\fd[vhS_gj^aafeekjgslivtjzyvopoa^a[*^1b-d4j5l:g9r=u;k;pWzZwj}wzl|h]LwXtBzE|KyJ}RvL}c~z]{{yoilvsyzل]MYSX[Ȉi׈dɕmהkɗvԙuˍregihwssפxˤxxwpLxAi.~ќѬ騇곐η콬坄ŨǸηūȳɳг᾿!! ImageMagickgamma=0,PAH*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜ)R͛8sɳϟ@ JѣH*]ʴӧPJJիXʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷٬ LÈ+^̸1R#KL˘3k̹s[ǠCӒiKO&ͺװ=˞Mjͭ۶ﶼ!M8\؁U4]:j }T:6C?}zv˻GO]{wzξ{]{OWݑߕo 7 Zי8m>!vx \ަኑ^Se'x@wQ6&u8O>Tdz:ި{L6$a}8afMaYT%QR-`]|d8_ h&I^ѩġXW [{|= UBKS;"hxޥ=HjcjZ9|U WI_Қf'zl:'r+:Zhv  ZvvArYӸbAQ\*mܒ7/{)K$z#GlXRҺ}ʩئJ[gq^| ZQ2ZƊ |e"˥ 'c,eF[K7=ժ|tgy^`ʮٚMpҫ$nw=b6y* jFGhBJ,P&P4I:dnlTNzR !A<=Shŝj];!K-Q33+O7mt̓u'^<5mm-p䈻m(t?i-? cCnKs%0~˝nZ/Ӻngr` ]nr9>kz{ZW:f:^ WeMYk yDZ {Ъ7ZeHSW\;2\i*Ex'(|3 7hwyQnX:2x|3t =7d&!y;1rętHJru^VW)M;^ĹY҆YYJၒL&Y14ץ}qXGFceѧ0w3`4mnE9d'ɫ d죵7 T%"YB..DB o2<?iOI;$ jZCUJJt3?tm4GG&<uHߨ/*~T(9~4%uxR/wiS5LR5ysCFg[ê FHt2H,JiB@SXI C"IArwVgXŚ׾&\˚ժiy.u0HJdKʒ&-xZhq\"!*+>K(uyYiWk˺lY PenilKV r:CtKVͮv&4 xKMzcb|K ؊MLN;'L [ΰ7{ ‡GL(NW0V n8αw-1L"HN ׸¤`L*[X氐,{`ް2L1h5p.ǐo<9xγ yπ4\fAk/)hE7ы iOzuC{Ӡ&r |I34jUKFa=`ZsŵLf:r?;uGilMm֥t)/@ͭhz[ܡv ~6dpㅇн_,o{>rO ics6I-SߐHygxmG.nZ69^]4xK~tTzsMt7K=N7u[YƝs_6#󶓸J8o^dwWzIgoIwg]Z<o]xg~C>~qo[5<9?n3سϼf;goaKzoMpkL_/'{C#GSɫܩGyď_w~}ʗȎړO־Grs3_Z'| wWxT|t}uv~gzwg~Gox~G{grrz~Wvd''ʀ2X`p'~{*{uF6B8>gz Wx}}<g}Kx'Ih~X؀/hfFCX7FUHhbv>xfׇ#8WVMxȀNׄ(w^|%`z0BȆL|_cƂׂ9V`|xv~urE'uvtu(?wTȋ{_t(F7ux`hnj7g{؃X_|h<&h|78{a8明chix|8x`y ِBȏ9Fy(o$a(T"6t`_1I`P5_7c3ya;):֓SfR&?9`FYbI`FXV耉a Vy0fn>I8:a@,֔WFE0jamqpXz)eZ93I=@&L_bccba 94fI7wp{9dy6Ipɕ)))`ii`9ٛ0) ٛHɜI )霷ٜ۩ٜIq䉛19)VgqΨpycY`ٕy0 ) ir9ZJٟI *ڕf Z *ږyZ+jƖ-z`0:/w7%V9D`z,L";JT z*:٢))aU2ʥ3gjN; Vh oiI]m;HAZz#:j*{ʧ鞐 uzOZ+fʨy;Y:oy*xZo:*ٚ$xZ7ZK:< 99&E:Ȧ꧝ڡکVժڦ*ڨʪꭳ*:~**ʣ*xJa}t :zzw +[*`1J !亦*I:})k*ZGHf8ZIIʠ﹫@kfꟘʫM۴[O˝Z VN{CIL[p*Z4 D I*qk9|d,}{76ekhy`7۸JI)Igx+P&w [4ȹf&S9 ˺;]gu +ͫ:6 pzӘaBM=J={Џ"Ԓ< [r h T#l `m6ڦ*R謲slˏ=Ī(a zǷm۷׵-hveMĭ`t&gܔb]aKs ꩤS,qZoΣl)mXR[C=n P,]GYqݤڝ\\܋Ȑ^a`N{^/נ=b !^tӯf*~#."@'6. <8}B~`ܻDMCmJ>DL$NZneGzka@[ɁX^joJ~m\],lF)}ع~椇~hzM=K^|@ȓ酗|zɘZ& Nܕ^p[9ܩX>'Ĝ pM\9]4H ~e͌wNٸʍ}ǾN9վK잞趮ٷ[ָ>׎܂ns\ݜ읢N]3Ys &e-~ f J?S&HEf:";C94l50ob|a>aYkϻb>V^L/%mQ.Kaҋ@A ^8 ]]MI=^JV(?%c_ه~_aj4dt7ҋ_=tH޽S|dթmޞÀoa3O~ʠ'~.<=٩MR OHO/j~>^ᝠ=չ?&{fa}_o߅@ DhR…6T1DR(PČ=R ȍMr$8Ő3$seI5CvI%ˍ)myR&ɜ9evĘN<UTU^ŚU֩7nhАṮˊVZmݾW\uśWUAP= 0Ǩ8-|R }dNo"i4ř%kܒihMKڙ磔Fz^ڵm - \pōG\}Eطe֗IGvYkǧ*]geKݎZ+iտ_4+ 8dA0B ksn($& J6RzCDU$:HDSdq6F !1=xpTģ`$Hi|i$F&JlKA+K/3L*JK1H4K[M7’-3ߤN;O23O?m2@$+p> eQG4=Z4RK/4SKTTSO?56'RUQWeյ8BdCB#\IVSP0[lX~.:Zo `{SU֭XwYfv8muUR JͭTE ]FtF|Hu1|pzvۂ̐`>̩5ޞ5b)N[p9f9A8!RC=}bwxՂFf69e'aEk˂خΒ+ߴD9[pneiz=&;OgNmys{w/-[~F#@:iƅ6Vőn`z\reMq}{;_v{{r 7eCws \Y1s֧bcsե+s*捡$&oG>FtI0$ǢfD*鳷H{F5?ćط[;s%o9 hr!XGy-b]*1mPx/MoW9 ^ЂZVHi* n`ØY%}ۙw3{!J^x(hoCvG<3R/n@tTd:"nT`Xd5daA&zƭ{ P&$!#81@Bҡ x!G.zU9PT*&1g%*c[9E-2]6VҫGLb~E+GR#xHGf6әJK ٸ>*/y;$h@*$C9I0q Br'd':tώ;d?ls(BT|*Igrbvj)9a$BգK1?)E>"Qc2w7ԧ"W's^m,MA u.&=5٭uZc$O9TN.,jw4wt#yJ.S)g\O$jK\2^hY/Z\SQY'X6vc>`T[x.gdwG6f2jaWejWgQ#֩]EM4C KRE+LV"+:Mp . Zʴǃw[+Jҝepyf0:sշx}!_7 f} p@<XI+0>'!)«~l1)l92\<%jZS^ߪ)CrL,{ %rZbiPЕfb1O[tw\7̋nmӦ.́ORϹUך7 ɟt}M̶[vuw{o$5 jJ{:wW~K5-K{?u읕9xO6sk|uo7j͙?/>iNԞ<;?绾!_胰{nN?p(I\AEF/?_lfԍ&( /k}K3/#%n0C9@k5CAܒL =:l4A#tA#D? 3$RC'$;ksY(ȸw+B(?XeZ@/$Cw;cS,-2|B0;3>8C;Cr5B+`C!CNcATsC1I)9H\Ѱ0ٞIE:%{b2VT6)!6ِb S(j.[\.@WBħBd̳Ft]rÏX[L+A[4#Eq.e@b:r3flG|ƌDE@[Ra-zFs?pl= @~HPALCi-ǍZ+EH Ǿӻȍ=DȐTxĽW$+RUCE&zɚd-Xd ŎFh0QEDLt{ SJDIBp{ʩI pIʯ"DFxG4KJe`˶d˳˪K˺ ?BqK˾$Ct 8|rqclKLɠsJ,̨hF,6J |LH >Lgr)Ĕ\M,ML!#TMlM F̖r,Y}IKMHMƤ u4ɮ.2T\ʔ HODMO4δσO POϘPOt{N:+ N ΥR;FEX)8J j]8+ODt֐_f \8yKC0M#0v^O7a# fᨀ]`Dc1H11+&nQԈw$J[bE:[[45N Cb\Փ=_:S*v#2c7fZ)ͪ;_#>$edIvl䲭\WVXPI ^]QSL>dMa60#GUePe0)+B>Tz+Fe)焪^kN 6idvxH:T]wK=@EnHB:HHAfde1z 2d x%U0Mj B݋nZm!nBdmQ[?a i nUn`9;i D@K8!9pgflv @ m eouQqeވΕΜ4˒:zcdFM ibeW,qiVېTQqU2ccy;kS::1"l&aߥo)*] l\a/>fNq>&\sl_m[/GQ? BLmT4=7scc*d8'veHq?S6iXt!GoP#H%?nF''tcLNoqb]%.7/'t@Mj. o3Qa7ꮳs;Ӧatl  ? '{hkXXvt0Qnscl&퇇VnQ{\xwx7Ky٣%M3toxxOfmsB8xL2m6IHyXO`?>8+hNs?vCO޷h{4mTNorCn]y`Tlwtam9g|sy!0vp[ǣF" Ȱ?ˏ>+W'wt",S&ƯqnJFʧ6}'ןOp m|eli ٗ"}R۽]}c?*j}`M}nWFI@~g۟\u}G}uRzZ痿'_`ԔI ,H`A&LaÇ #B9S9kΝm9Y.桛~JPu^:ΦR/R]5V1Ejl>jfq 7jf[]!kb첪Ψ9ӉF~yS5yݨ<`#WH=Fv2i{ ̼;Qņ~1QA/$ V.g _.=Єml!OR% \< ӽ A ^LL^V7ꐆa z"[,DO&R#Ԭh q2",$@aeF,cerҺ0.yObvSBz\c!ܶ-}0^itp9*ݰ5ts䉊 %w](#?Ml 付JRf([KVb4L88;rMB\E>*`iDȴCR31 4PB(̡%-)VG%W9 Q$e,a .Yr Tx6)O O<2?Pi4jrԚ3t'?M᳜P#R8s<%@TS.ɒLSdMS:Ius,gIAE3Lm"='G3) -*z3"B_Ӄ[F9͎5)׬NWo2\)[Nln%\Jp+)^I3,*W슩]r}r6[WWaՒUa++h9ȸ47k]ld۩wj/CJXթ=gOqs"Ej__[|^]^{;3m +Tq`|4uU`0 -x:NQfVF⯭\zC>\[ q+.ʷ^ٸ[F/~[عk ɦJXvazDde1cݣ]ظ /(GMOCSR4RN1>f< NMq)gN2efˌ&,mc>T J]{f1s!J&BG>mgƌnHFz&ѳ~A-k "C'-sli uȩ{ a1:?[z)ۑ ˣn&?;(~k@=eUs<;Ygg̭;;BՅ#֪ ]RdtL;t9]_y{{r,cL{)Tzxޠ=k7p[pv}~K߾T33<7%7MnOΩ[K .iyy|,]Hg 'eN͗JǠk;O6px{.7f-gPH/ R8:g}vq\c\g񺶤Luz&pQ]doew3$0Rџ'/S=e>/ϯ aAwWLI:IS ^^&N }TkI\%Β!Zy V-E E` VrLPb^P & _.NhqpY|=Tzaa|L$QR!֡6!_B8 !!"V_""v`JrTr͑xQ) Fb [ E͏$)Yٝ\J1W^]ZAqzL֮ ]R Ea1!> 4+b5: 4n>.lVKV/t`1և1%#9#J>r#?J4b665*`Cb?d !әl;Saڕi"C0R,E\B!6I*$^Z5P;֜:f$|ձ-crmFn}H#L6d@Z# fT:U_"*F#G{\ŝEQaMe-xڭ%DERR^%_b%JB f&U%b>%AY>#.exl͡T*1eb~&gg&ibZ_eZ`Dci^%mRj&oBk" fh2hq'rJaV2&Pso~e^2 gr^'vur{qLG!ID*:F&({*q#|s4T!#RL2V$_#Abz@6v2߁vV%AVzc_(&ƅc. p"gcgA(T%LI~p*heJh.m~&3z&_6i`R'&vt~cZ>kB&bc'/͖z&h{v)f(q*ih3ک.iNfgZ^τ%Wf=f\[_<*69*[NY݁!Q2*_瘒ꍑݝ*zj:Y_hݞRg jF%`>hA6i& rA>h( :+BJ)5>"46kazkVbkZ_(F뽺kjrka+aVE~FQLEE 1Fb_ #YB W%Z]v'j'Yj†/J"g߁$Rh*V%,B%VcJ$z.(V+bm)V,>-N+l,rm+b)}/R(.jlj.Z(́f.Vf ȢD$m-*rQEn&+-m^-dVm6J؆-6R)z.bmF%׮nZ.v*궢Bj.玭bi]P#ܺ*WO2dq1X*]}˶,MG*B".0훴'OV]d(hD.~m*nk,!.pn/3n@kʮB֮ή"pjpm\*B/[A^ 7m5[B$;=Kib& ^oR.^0n~nKR- ߬w(#R-Nmn0ڂv0,pڒ#UzijqԽy1"U$2f&n&^RMa>WO"lfp;?1KBi-*q..[Ϛ2_).{1qz 3ew&Z,N"ޝo8(\f0^\:Wze&yjYґ}{-.Q:M3vQTM [*jN%OT. v*@r精AkaNA3&Z+n4b(:hE-J0E+4ީ@O(tBϲ(QS#S8=sG6b3/7qv.5S7uVszT?FQ c 5SwWAV5YU3b a5[[MKuYjDc[^M_ /%$6O̢ AF5t:>R@C6b2_wz#) 20O#6 ֳ%QIJ+nnudO-g6^'L_D, N'ޫ)^`Fc.M#)n{m׬*f6wXcNtj*s2!Mm 7(ô2kA7G3pF/4FkH+R4ew7g7h$6-CV%bRrB=2s4'vdk3J~whS0C:5cG23owr& 2&&: #xSNb3*(vxzl'.A.oGv@2oyXO8xsɕK,dzirHXtɯdԚfcwZ2GtGRzn˹)wx9:yx89!lJ "+g0{[n2r פH 6Tx+nfج|zG>On??)D;1ײ-Ne?wWYNs;?sdzɳblݔ{v}7]csLhu84tCx J+&fwnȯ|o\69ucggϼG#?]}]&ϣRG}w"5_f|V/qK=؇}L=Ncgbvz-=}~g0U<g<ק;|=#>݋ӌ?~GG!Wws6~w>/FdX~BH9)cד0{=K{=s6[l~g~q.HG)>_%s`=}~MẊñ볱0f{'7dg;W C~5b#뫹K(R?B>@@J`AD8paC!.TbE1fԸcGA9dI'QTF (Qĉ(r!?PG54RN:ӟ,ZiԢ_;lYgѦUm[oƕ;nYnxiMo ̓paÇ'VqcǏ ٷM ) |8,Tc='%:4ѩWZEmWFaו=vm۷qֽ[ݼ{^;`!'WysϡGW.Yfb֌sjŒ5Ew=liǗ?~}ի/);([?LPlMΠk"@=pSM("1?FDq+Sd[GĊ9,i݉Z^*Z`+[咓Í&@-ΰt `_Ze*ۯyֵY{ZR/eg-xR7[4~wxێR42L3]ݬwD_ kp`sqS_wCMǜa xźM~$&xE ;'NTțE[Ib1vc<׾+uhˠϹ-2d[P(mse,W2Dݘ٣lo&i5zg4;l6tK2xAӥ&l~t]#*~ SwQ-aV\2Cs1dR$Ui]M[16ey`٧<2miOնmmonq6ѝnuvoxK.Fljmg˛p7ppe|%qQBúoo~Dǿqj#6Ý-waNnwhrxǤX*G xQsCvѕ#]fѡuw|mnq.&'>9T5>uc/{Ϯmw>c[W6[,YU1&E!I~2iK?Njlw|ғNyh|߼}{/}O͟ww^敤q_bjEsH_[H<<}哯p+}_}O}C>a~^#mdYg$oix3_9#ڪoƯ-0OȄ/PtBl$ (쏱!\npTly50 9>P, l$8BWТe )0P p'' P  . S0Р*p uPq0#&010E1jloSȈZČf NlMP@xNT/AQxM/ޒ|q1ѭj1w'n莑Q1Qѭ/%1ձC 1\Q r!#) 5c %'Έ! l _׬ SD"?e0b RSV"X^2Zb&"&!btj&t$2d'qbbv'ɀ2)uf*&)bEdl)Ed))R*('r!jz:G-3J-[-MRLr(W&A'iR/*%0W'R(2s0+!2*%&1-*Ť)'1L'C3Y%E.GK-C$r..Ue"@S7$l7)x~C8K/04S1(S/i!0SD43Ldr423;4osA^#+ 2H͉L0>k#k6i`Pr(J0r`22381)3'+R9s8C5T0s1?T4[2r4K 9b)+DJEEF4\$EJD$vsB21.TGC3"/r(A#1d爉0|O?TE6WHtHS4H%M;;-N+17C90EByDED3;5EOMYZtE+L$Q@uFQK"GDt2;;3:?o3B3I@_ӹV˶oI]-3e +6kJtL LN3zt2XYO'Z5ON7YUY3Z5!DomP?KFKW* #ːy5_a"V6ðOW7r*g9r{b}9y9y9y9y5~ckēgY ]$ d3%:9y:z ùRўsXJid>G=<rx֢K? v%8璁%@`imq:uzy}:z:z:z}_~Gœ0YzBK?Z`Y7k+[jFXZlaWn_;{ ;{!;%{)-1;5{9={d ,Vc`G5E::ut%쳁;{;{#;GHCωa-aI07aquPjv:j,W׭麵{{--;뻿<{;9Zкϸ{J-aMzֶV&G|I\O\S{c%V|e\MO{{QŅ|ȉȋi<yºk}Lv,z;ïv;N}| <5 |{I=}5{qˤm^UJ}+}zlW~ǶI\pۮ99 ٯ֛=~1ZI9s<]ν]͇}yߝYuIQ̓E^~艾'>&޹;ͽܩ^~݃^ >M<>Q]둝c]E~㍾~^oi]~e~_q׍]޹^cA?ӯ%f6}IY_٢=RuDKȩ }'G~=??q1=5>_޹E_Z] E9VC<#aS$nرס;^M_’5$hAK&,ȐC#Ja…9^qōI<)2%FlK(kڼ3Ν<{ 4СD=RRJ6eiSQN5֭\z 6Ԫb˚{6Wjۺ=-Ut뢵wn޽u`->x'/;~ 9ɔ+[f,5fV; hZZVOMzhϜlکOS*ڧYFnso&|wtmn\༗'w.v̱-r׏K= eRNIeV^dC'd^J#r%LE4Y=]٦o(}tWiʘnuHۈM.h:dX㞝aini~ꘖ|ejEj|}8(A2gFf\Hj/녖i\FI(iޗ, #u*;lUnKn枋nn oKoދoo pNjjb9k_*,lBggZ;1*~|+&G%Ƽvld tBMtFM*ҟ'\CzrTj{2<&CZ3ԀuX0ڮ=sbuÀ 1ٗ&t~ xNx_4ᡍy`q9ޡ9%3Z]?;_÷9n^qZpwnscNgV[f{$ߎ/|?}ו_0K=5XUo~~[OW׏Ͼ mf+Ԋ4۟](7rC|Y,w٪S9p$, OE1 s,&~ڌf|rQn&$GPB MЖ\Z5̙X yx%*/mr1 Ѐ /*WiJiQlnd&΄<$1:#檍ܦ9s6hlQ ="7Uzwͥ ({‰W]v-QT*dyp e uEEST T)?*!ԶODTZ;ڪ4Y -e&u-,ں36lpM.ϫѝd`QV5ca,;~LX̫P*'6ej]Qb6d bqV[v=m(רlc͸mfc ]N.x\hٴ4ͮlE+SQb\ڎ,m`w+Oȃ׫CPj9ik Ire:lܚ'ERvQu/ `͖pvrz[ b+_W_Ǿj:.\*:7V1dO>zb"Wy\2k0y bɌ4jnߌ80; t3}ٜcNb{!l (Vi?g ?Sk$+;'ള/MXJ6D]mMޘME(]T2/y2ԘǬ2zh6@Wmxr '<{u2~_L3R[F%&Zh YE״뺝oc0,ؼh/=ؐvq}3o)z=%b]UUͦGeZ<'7\gmp|; \s=٣M! ZpwsIjO MQunuҎyXQs˗'YӻP[Og%Y|[Zo?ۿ)׽R'R 9G֒Գ,eo|~:[&*plނr>6v'9/+V9oeyGxrtT$\mwdPuVtuqlD]m+o{JQowm|ǧ|-,|\]c}_E@:x]4l8U[ӁSyuv}Gcq3thtdU(6YAhw$# ZV)]XuZ jjFznvgYbH4%{gvrg(wOh;k]uヨLg7Z]5<5dsB?[Tx(wW{hXC]^XReRvHXuXzU7^6Tjx8zJ1˴w 'hǍ0r͸aer48T~"t&`G7H XytF[rhhnٓ_o~}W12ov a-~#p28D:}Cd7`~rP H#t7~7a*:I$=*[x4MqV s匑H4xsC^rSFIV=؊PPՄ`n9c SD=kG̓Mwד=A^Hy2f9ȉWYzqU߶;7XUGoz@e!s"i'D7iq*<~{x|w7ɗ7I`S5} W}Fa`[xETToCUoo(9y;FUy*3`iiTܹg'EuY8Չiɞyfٞi虞@5 }cji9kt( JѠg|49]Ibdžꓙmm@&<+ 1 4j)I86n7ɇr^2 EDI 4z78: eJZLFTYڙ'> 7K 8i'm_X qcYy]!Dƃ4V%nPxAS:{Z_-ꢐJ8CR(;TCy3\Sᨕʟz u:\BIvڎāSl̄=꠪J:Bwjɚ4I2 8JҗLA5١{Wt :ڪN.JJz תڨTσj'2ڭz8)˝hYqΚ+ICkE awiMG{g JW;fLKS+񊵽Uck>P4]{UqKG{EgJ[NǷ{GS$6t\u[V;_}z"[jbj%4+ʥ_痆㩺Ʃku㕷{kkKK4+Gy}NoЊer{X˼Ozw:Lpb Kt[{8ջtj;[}Rԯc#W+kqvz p@:=ṣ>"  ;a+[('31Oຳ+,7z8:= ˓DĢ?Kj~ૠL+Ul*iEKVT_w Aet*o'|o,3앛27yǶŻxypălȁǢ:{ ǍuRȕ \,w!|l[ ]-lʥe M/-̳ mMҎ'-üm~bxwN;?)r8*|^)ۘ匦7-S[lSkF>i[AͭGQ$LjQ_Q-Պ wd }Gx fGpyqw׸,{9pGZ*cM|8VlA5Y̻Ѹ;h9D8Cy؈}2P(T% N{YlӻUc;r-نN (y݀ӉQK{J}Y]ع ZФEخwۧx(6=mG[Sxur;y߳ Ie$ >C7kq ,nCz_-fRʿm<#..i6)M i6Mf4wE&Mj0U~#-+ұle^,:! ) \FuXl; 7xfw؛]p7O& ͌l}6^Am'>ުp'ǫ1b罖d_q;(Ȳ]NLzܲ~ָݥCݰn-DFܫ-GXn,۬uŎϮ垧!nT✳xM"8NtgG;;$d߬.8̳}> mnJ^bä6}~r-vZ!7JzTv-yJn:1C02O@}?9] RCcHe=u1Һ'rRb2&OoaZXk"^JZ{}ݷTGܥr*; ѧ<[_joᏏmޖbO\>5[[_ǥؐ֘M?aD-jSLix~[;ET)ğͮ\ݽvȔO{ 9މ:  $XA .dC%NXA 5\G!E$YI)Ud˂7HfM8ԉŸ{,ؓgQ-"ӦQd:iULfz+N^,&m֭aZ׮XyPf_&\aĉkcǏ!Ӕ|#2)yheʠwNUh?|PgC/u=76igdz,h[p붾[:x.^pcٵow|>ayѧ {Egf!TpAI"A +B 3@CCqċ#8STqE[Cg\Ӫ&J+*A =)٠MQh;OG 4J0ҹls7R[h>K-)OSSUu +A2ӮT,\{kNaX@cuYPeYhODT6iS[k)a_i qnBSiYy^%VdWEMWpG&;_voݕ_|3^;nN\xأ6VicY.]w=uTgXjQYtQ ֕r+~釁-qVKg;UWqѪ6ٳ9jT*xA| 7* |$Kq=3GIh@|L?SW]1^u3,cZWw{B߃;h`x+H @0.D$EoQ/ջ9ƹ'}-{~/OdYcQ&RY~Xh`@ f0$shַ)F ~CPf<-Rёs6} #&J˔svMngįo7]DddbaHS;""4 a[߹%3dVܚ길eZ{D(R v#,4<'*1FKDE59nZU89&c,SR%e A2K## vHFё 'ise\VD54XW 5u둏/;ɕXIjh*fJ>XN^'(LMz\gJ>RfA )ӟ5R(lfΪYsc$b8i6Zg2]O1(:9ҕa36Rn3 7"SLd=JDz407|st(QDe"7tW!)׶ fȥ0%+֠MNQ^*'a6qz'{MWO%fVb+>V=7W$v%Qd9Y{}M|fA{'5hGmji{۠,Iq 8%l[\⫲\TXe8ɥu<[]4%s+!j%/a[^H+ G vMo}u\MewDzWV ,%vW%Kl`r~Uˆ" xcqUXxLR]!X_e;cqsXX+H|ĜKEXea6닔Œ%YBe3tPd d&Y/ VY=#9Ds^Gi$wGf5%l~ggَτ΂:z[ {P}m7Փ1\¹i5RqÍV< jvJ5QK]Ul*^d\j3_T>ogXGLZ[LZN4ZQ] 5tIba؃(&Rbҁr9JY.|3yQy';}=Tw.O]Lj'Զv?^Nk"} y)\#mm*ojr󍬉.;!ijgH Nf׍Bl8_2Ŭgkn때BqT9c89QnĻEJ[mJnQtZsN׶].!3w ŘW|! q߽=IUW&<z񻑰OysTse|DPOOHUS|55oEz K6> E}-}Tcmfx̍>ԡnlx{.sח?k2Ü{k?LA.b[ T/@ˑ@A?KLA=SA?,8'[?׋jA9@ABA"d2#<#\#ö!:'<&BKBBA-$A,.* CB#C$B4?35\1|CA#<9ı81=| >dC5t@B=>LcD1DHCJ/:4Q* J@NTJEQORtQ S|U$V ŃņhEZUEX Y4^/KDJO9=`\EXFF`L eDTŅ^,mmgF FbL/c(;jFnt p4wTGqdxzlFN G_,CI,G5BxcuE`EnLEzEdƅd_GfEDHŅGGȈņWlȏDȑ$IS,I\IHl,Ȃɓ$.rGdȘEtIzFȢȄH%T85T%SS [7僶)[>ĸ3YӪG:\S?ʾR(;"ZKG*TKU,D;٣C4MMwiϛDS‡B=:=ֺc%^0|ϒVeSkuO#UM#WMs$sIDC-^30WU 8[2)Pc6]:@j⾸sӾzM*rVgڷV~=sWa XO]p={eU,[j%UVѽX]7|T؎6ɐWżr3%ӻِ#x:>zOCΓ#ыםū.EUS@OM>3j*/냿ZwO)tRcl-ڲ4}l!EDCS JYRǕ#ͻMO)U̵ܵ>RЅ=WJuUeI] $DUSxU]oTs .ᕯN]u]^ A2"RZM^aKvU E\N5^E\M_}]pއ^e_[_ٚ =-r=1=Y/%R< U^ 杭]60Z_ `U N8\vZa6(ȭ7\7a\fbBa"ޜ#^"T+Y'&XtbA2b-n-b(b1e2^*NXka651v6a<^,cD=2cc dC D DndZ_8dC ddL%M.(dqDQP.eƚcT`ѭCZ#F-[+:òA 4]v ?^vam3[ RU_\&IclU$ ߥTEbfmNGo+h.nVq^9ae^Dž}sWSpnqp>gIfydufW\X⵰ͪYR[U**?Z IQUT떊mFii&YUT U&Xh&ii]KiZՔ"~@=hX:c7m=[:5*`(e;sZ $=hqjSfb紱,j~moa\DZXQBݍ0R)dZ6@6IFZhOLye$:*`bU1ZjnjbI3)颕FW5(FPf1yc|J(⚫j9(dZmYia)+,Ҿj`9-曰:{WκwۮkЯ(>jjN{-Riw--< 9mHki{¦/qwfռ2u1Kz6\βbG[w i4ә󥴢,d[[sV5b/]kmDvO¦Yub=@v˝{6}fo8AݸC˄cydߍ柃zC+駣u޺뼑<8]fZN*ݾP)ѻ|a _4oW\T&=-Ƽ;cs lhZj ^_Vlv-U Xjz5+guJ"UYgٶh=-j:Z'QUV,n.$9Ѫoժb7nrc(e} Wnn5kj+[JwQu.z`յ+"_WoG<"[qaBlblmlaա?^qHW!>n 0-ilʴ5j?RzW s,`Nhq/V{5LNJ調~N3Qh9߫F&ː4$MKҘΕ{!5pα̩P }j"zӲgND&b-rCZ:D蚿T-`WKJX7;|Ӵs~VIU1٤6`YTc}.}e(۶-mvs\Hۋ'/,WǝO-݄+<B'=Q3En|9mksYqϪ^ wŶ6VZJ3~bx]*qt?­-rݫx'Jn=ytÝ],{c^uD~r9Յ[w6I 5Z?;=򆚻cw*ڱEz}-7ㄗjăWɣ^׏OG\l4a΁9}lܤ^4IBՇ쫏$[?LJ{?_?!ۏK? o??` `U"`*2`:B`JR`Zb`jr`z`` ` ` ` ` `fM@;kakoune-2019.07.01/doc/screenshot-tmux.gif000066400000000000000000001230211350637360100201570ustar00rootroot00000000000000GIF89aPAi;!,PI8ͻ`(dihlp,tmx|pH,Ȥrl:ШtJZ,zxaڕ1˘OL9U:3͠c֑ϪBjBy:sf+_ҚŲq<^4uËaXBXO}{Э>5iVrdvU9)r6`g@`I&YxCf!Ex,5 "xsg|8V|GAxx=w܂SS!IsM~'%iH6IaA 'cMF%nv.9QyT}:Hvz%qgEI~gWFG6*Œhh&^BD1BF槟IҘ!'~yƗ (zjbV>9(+9!8a [ K\yHV:Ykw4ʉ)A~;j{'l^[&o/KbKBi6zhk.g9z&LTM߱9.Jh*JiM>)UYmUenk6xkF+6!(+>4лz F{-CG8ڱ:@ '`mc[ߢL%IRרJ%I! ?F =#:|3 ] P1|9Yej 㕤art(,>B7Qx:d G+^r3;QnjC3NjrZc(Mw$1G:/E#GT!*4Er1l*,ϑ$g91\eh9%`j&*?S:S0e.O&-CIkΒ.l/LJU9`xK|%w3w#Pŵ=Y/0Q]M 7C؝aczǕ0_> PB:e\04C7mPGuhAC\(`Y+x|a/&Lde|*Eۙ7bYy:m??]=yC?Rl+0v}ylvN^beov7^^ZͪqyWV7񋿻]eU9]+ysK#1 Ġ J(\z/?ZOw`YU+!ϣg/@&<<Jym| }C+>q 0F'F2=DMFwvPnid[7~܅vANGmTyV&G:pؤtWg@2w}4vIRmw- Ȁ~RX$8s;npuHQuy:CwrMXoxm0Kǀ}Jn"6edNtWKstCJM8wFm}w8Nm&F`nqy؂?'_dKp*3@76CuenPU:eW?'Px~ӇFa#g_ta[si%`HP扤{s,;/GXsȨ^Zsɤsp0Ќ ֘.tHW(RȊ_*uc`pX&%nwPx_xwSxwih5F>y @@E, MU7)u7]kՔbǘ6nvIqQ#l)qTT+ZxNє?G9h(FQqvY9d~4:IUřǹy'?iE. ohgHIٚ؞81s3).~T!Gtڢ|(yp*T=WjѹOٔɕ$0Q#:q w4R,\XY]:kCϷp 6zA%eipyjs_ڍ`* D@uDŽ2ZxE`PRxmkZHC7):PږA]*%:J<ʢ%ĺғ(:uajD'% z :JJ4Pyew8Ɏ40U |8ɯMWbkw{z.F;$hȨ]p":[WhxR`z窮*p= ksSHg&z6$Xj(6,2Dw5gbbgd;>K$˄'+蚲Pj+&!}ᴆkY6ڃ:9h{W; )Si Kk{uBқʝи b۲,K!{uƶ% &B/;T17+2睭ⶩz1b ⰴɂ+6{<{D#yGpص;Xi5wg.jwKrcڷ *>Ƚo9`hۙ0ETƺX  A) Ij [y9kZ[^4ڕiaꚮ-;SOx4XzVZFm[Ay@fˎ,ˑR,P]f)B{Kg$[lXؽr3yʺnn ,jZtLfeȁr<ȌH׋rgHp4I ɪ[bXLBVo ڬ+쏐zw̚D ]ʋ&~>oJ봦ܤ˛J˨2{MR ZܛPxHzz'5#F`)pDͬ{7wZXؘ$z$n(̓=k^Z" K]̣odTv,<ЋHо N~Ҭ"lW}i >_x >K--҂J\CK)m&}le( uݺ v]bтA]^xlԵ6ۢ3Qf[-KFc! ICml}>!y։  J|x>y\ 2@}@ zԋ=ӍX-,yjE,ݕSz{-μneLLmS܃DV\ŹQz7i<l)&⽟p}ޥ\mG }߱qY-XF5-Z Sb˜R!] :`{ή=_rsȫ ̬}Msu!^Ż:K{L“Q=fgXx1KlUN-Q.5: 2UxK̞{̇L'zH*6-,Ԗ !oh.v-a癬W v`l"ZY|hܽ:L\L].(ޱܒ|[vi=Lqh8Aѭf;2Eܗ H{ћu⽗k[+6ڙVgi2˚-Չ~>;(՜h6=5|(.Jsr{ܗ '}Z߭}ӦnMP뜝ޗE>JN! Nۃ}݃/+U{j;~AnT~Nh,k[v9P=4 l_ Y>'KkM7&\*ooݮ< >r߷.~}E4 u[Go,ԚL.f߉<mB妾>_J=Lr/&Iy:9)8J/~_0 QM׆ 7A\r] ׿~9M"(/4Mf? 箯'NVV9up@%Z$ )ESQGROէvۊ9\cGղXhEu@~u W) _j}RaJ a4=ãFT1H͡7[Ch2 3bb 6Tp萦M4sjQ{'#5/ ʯv=#j=aŌKnIfZe|O~< V: ӴllA@\弍>±ۂ CB怋0B41)v* Xbh2lp-գqGsq0Y/>r ? I_$Rcф!m2F~Ľ/J̍20 ,DJ8|G=9c>OD/J>ea(]zמ5ζ{5|hyW}g}G?~,@s?_Cms3 `N'P 14 G#"r`Hb!KZ2`X؝pq;$tbD](FA":R^`P.@]*,aG̱jDK0B`:1xHpK)EKa`QL&Y Zg#@Jm TB/MQ[lj8rh8,K&ř-♄inHRc tx%EBԡ{>uJ/3m >ӣ? dS|;Q4n|](k'aRN GCaGgFy;#.!F24UP-1T y *}`6Em3kZZ7jK9G!YWtpl9Z~lKڎ:9 P%m*c I1"D:QRee)w%8ƨFmY;7utT?IyTPˬ\ն[z”3촊0& @`JІUmBbw@EU\RئAH+Z khdTBLD3b֮|fdhc@K^\jM \e-{Zmr8zw89ҸXx}|,u/:+YpʐﶺR"42oLJI::yy*XFlLiOO|(f7G"eLQ : Tdt_v8cN3H9_j5gg⼙w;]vstu7v+t]yAw >p'o\^>АxuvծtZbzƫ^L#=S8۬j[N%3Nt9ܩ-'^a+~x痿I]O1'ċ3 @LTs>S(ĕo*^C!7CV @a2&C$tsB@ "hS٦l/5 A5[\>`A,r[4uPg3 =I{ !ܙ"?SKc'D9(+'j{¾ur2iJQR-s00 &<<ˣ8DPu(8c#C,9A--4뫹3-Ñ"Rr+#'FDG\6O>[D4(5T* 7@7(ݢ;z ]@))a0Y0 >3 ;$?M8!BEhCLOOqOJ{OdO4ϋh@OO PP-P=PMP]PPO-PhP P P P=+CBK},Qo pQ P3AK#teO!5"B$U` 21rOІQ Rљ$]bq#eR%R8P7Q$mSB(eEˢO!- S ? ,3MRnSJ6S9SLMNO<>:$D2N̲ۺNb*N4M#NAT&Lj>^_U`E`pPcGPN3{*0sIc&# N_Sn]ҋV]V+rKbDDs=lNlmWM|T)I3ȿ7 <́0R5T:Tg2dʍXxUD֟,Ud̪AU][Vٕ]]75[e[Ծ]\ߍ]>ۖ ^]mO ZRK +Z_JHR/U;죾BR5Qڥ=0ŁY%^]]ޞ_^E-^m^SLe!\A Ws` Vm/Ee߻s:_[]5a_>>b]Y ˕sΆ3M J(eT=̝3M M+MA Z4`b,1I|E[#TwvnXEWWδW$dz[CYD.{DFVbR7!DJ5R>eTNe&}z,L+TXUnZe\e#YeOO_f]fb.fcnOfh`YRecfjUn`yidP)}EU9,].- pfS9E"3$UU4xgγה\?TcS'T]睵;]b.LYvrf[슭*%tF:nXqص(Sq&ԓ.SmhMbachFh^mAAwԓJ\j ̤ ju; gSsi雵iS陶PiF4S)(.3V32;gݐͻ߻[) _>!¾".VlѴA:U$H66$f*8LWoN$LI6muͯc?}bKlҥlZ}]\mT%˾3fs4۽+nj1V֚Wݩfilm6bޜb&ֆل~onP5U}.jc4ZbM'=)p4Xo~ϛnwnx^ʨޣ;CXTnRɡ"#>hvŪa$ oU7qRu8[FEt]L.; <n3lh({4(ɂtNH9ohoc#fo! u^vb3ՠ7I,hGK]Kޮ-6 g!uu,%Km*E:nhion?&oAC/tcbEoVGtiO<trZntH  GRST>q;kk?pG-sd=>jma'?__Gt^ERYb` ZF;>:v(*0.ghk@~i]!Ɣl/^snflT7sҲ#)Qlchacb;Z 롟"jsWخ8hu]AzBbdLdx e%~eUkDdTtX{bGWw he?|Oe/|W#nn|W |ʗ{|H ;|?p/}?y}Տ#:}8ǿ}wI\O:R>~S?D}~ܮvf˸s~}hKoZ7~*iCj/z?#Y'+ۺ/3]w8«l#2\2'4*m +6rJ3:^=7<.v/Y?``ߞ`!bb K"d$c%f&eg(^FjL g,k-S,LoiƐ0q a3*v6'0rp2,1Q9K<)Vt>|o8سG{ MI@cB2ʵ&M#h%caE dǥ@~)!HAcMe;Boɠ2ReåmE ZQfI>%3ۦb-QO ̀ޭEb SX̸ ^U-Vr Ӈ5/7/^ݞTբ[50t9=Qw\.^9a?uؽ3'sQ9oڞcַ}#>7]H#}GxRxz`Ugu܄]8Ȝ}!g^XiH]Ʊxb5"vՍhHX%^8c$H Wc)מ|9(Ad_~W!_Es0NefV ި{b* f;L:y9]iRId=U`kM.Imp(&;EWQ$bIyEe9~9}x>*[IVk*'xw9&g ӤV`fa .*LتoG[ߵuazcX튖R)-i>ia];V+bej0Y:'D룲@u70:[&o!.'j,Sn'K{#έ &R s"G|Iks\kMm,V/2-ӛ*hyNmelkŝ9)x†|խf#~ֺleMΪC-4cwjނUFc#0$?esg\Gթc *o4? T_ݳ>|\_諿G>?l?|Xn'0ng -rO T<=CBJ#ԡFӥ^;eAL*LF *Vխr^*X*Ve=+ֵn}+\*׹ҵv+^׽~+`zNei(ƪ2},c+R,f3@(Dv$6I[}-lc+[{\q;Ywm^}+nmnp)KuqjT1!cT3@+^,5{@HKl8jҷV%~Ņ+pW/MnYBG~X -Eib7]5VĪvׅ/c,cŢնepVe0uwCl{,`L(_ %ˆegb+ RxܱC cf5/mvsYg,9UD.pvc K^..94%, X{N|d;+Еf}gE:ї z=iJk.fؗM|ieq3̹7&5uVЄ,0Zxlr|b\n:jD&s ^@j0d=эns~kV*Փ&s R?p1oSդ4tz7'j qOV.k3u̞*٢BQ٢ymlK{b_{fmEX@t3qv:.5ꫮwp:m[bxտpjo;nŎoF!~?OF ,֬//_0("9Rι?;!ji aܚ1/t9L_Ѽ橳.ݭҩ^5c?{+\^/N|͇֗Owɱk/>aZTP.6  6Mb21EpdN[ݩo-] )߃׾5N]WyB:_j2u`M}-O ^F%>@\٠ \ ʟD2UٰG% U^*_ޑ`Z`ݝm]5ff\Z Yf{m  *"C!UFyQ d(]b}blZ]ZV+ڦ΢bb ZÁ`YrX,V.3*#fla"w]YXiX ^m@W\%bz:B#>"$TAc )#lMI?#@`<#BB#>6d $DFDN$EnA^RBf+8Gjd)(H#q|JIH\%OLdKMuX"ѐ=`OvOWHd7LW[և 9#hSr;X"Q*WL5VBXV٣WN]XfXUnt }R:YTB[% LLew+$'tb%&+ &d %^VBDNS# L~dVaN YX)N q(zb^'&V}&gfj[e" aMz1`1ˁֲi&cq>flBAIQvZtv^'a>a6g<.K +5&e#ҥ㹧 "S \y&e_eufgw.!x(&WdRx~u[Bl*8%g![zѧ!FeZcb[~hS㴁(&ij(s; !n(viFhx_z2bJ&BbMBV)ʩd܈Ω!i)bcNy _j)rBii6h(隲אMiv蓒~~g|橖褂 f&'n&('諪fhjj)i&ꜝ!rpJi.ko`qf\pnR+sc| kArJ~kv+cII&{녽ƫE'֫m+Z++=ګ ܥ$ҥ,CA*` xlԉ+Mjh n%F:Ic&;&iFM֋ÊkYߋ_cy,6l`pX, n⁰[g~^YZRe`Ɛ_#6+bҦ&&1^)=eq-QX}(5Ƣfƪgj>p&c5&V 1ݚ0QrDъZ&G "BUjڨjkߢ*ɂ򀢖i)&j6nakYe+ b H6ƭMn|#*UDNzubPeTPo)vflg2"k1o&\!h_0m)RxS:a/-. B!K硠"%!`(Bd"& 0< ]7zC. t"/@m§(&CڮS/BS kMelUo z'ְfs1!)'i'1 iNpbCLgr  ?}q%j&/z) Ϩ 1^Z^p . jY912rY-oJ4N#&.n *k&6nX=.;Fk uWFPq18bna!;sD[γN:gmD,H@R)%Il?sf4EsЮpFtFwHkEtA/Gcږ4JcC{Htt44L4$]:f_~l& ŎqA2Jt",!< 68P7"|XilW59(*DWYS;G@5ǡ:c"`Xy] 5JaURo+—aЬ`3 ᶦj3ONi2/V捒qƂ_5Ѻc3@D&.RrTfs1w jeu.@_ 1kc6.n6iB4\NB &*%)brR^at ?-?ZJ +T{# '.?!f5"D7h%{w&$psP+%Xb_bz{1p-f̆2!/Jn{Oqió jpFxp4(?x"/tx[8sx='tOF1HiOw.Cs3T.̎wrv#_;$%gwK8W't+xc)[ò:xI28CI.G{k׈w9| 8m^S{s ҬbXsN#?*u޹{7A38x㫟,cXPw0*Ÿ~#{9qDzZfE ӷ+I/kN2y&3CZv3ff+gkի/9yj1N݀nT6i\JE;OnKbrڙ 7!u0k3w>߻sk㾰9kؖ&moVFn̺2K5?ţp73SOSğ4|Xh̏~&y ոS=Ayk*nXhZiBki=篲_yOS ?4{OI\,LTͩT'3 >k5ğt+a?+p,7?Jk\R`(?? @gy ő,MՕMb`ng ~C!-MNUum3Z5$d|Vl.j},1ī KȇhD Q4Tt4U4 Mv-VOvmnOxx5Yyɳ3U&UbHH6c$<=]}w?__P0 !xYXaB 8ذ>)VbFdH#IoӪ82K߫*u+u פH85N-s2ExRM+P1 CY%m=T(%L)tN־36&$fz<-.XLjUG3atxC[f]9|ݗԺwG~ Ӄ^>}7Z'*^h=EM>Aӗ YmVR}}#gba.i*n^=QZYiY)\N>?w=U_oڻ'= ]xGș8' /n;+Sf?k.uS?ũNm'afߣ>`>mt(G Fm-Ⱦِ$pC+Zs(+dŏ&QX@ZQ3< ;u0}p/u1+ lZWfbA C-DHfO$וn=p"mĕ5r$,8I'RrThDvr!w/f04e)QGV`7 O>߹]=@Ћh1iZC$brq.I*lb6Enj&cٜ@iO!4*Ufя!/9Xe%P8] )a`2wrrQwm(&../!iΒ楠 U)<[Yxrm.aȥ-XǃKЖ$3-&5餢7KvӣVWœn_GJZUfZY Qց7'y ^K̅>;tQ{.0P]V Y^WMg}Y Lv]~kvخz;ޢewi=̿"^M@|[P7/kQy2$$Rw/SG`8Uo9ahHTr cTh<(). *'Qpi ΀""`SaGVr|'X)+X`GL[H0yFlSeŭCyK^AΆ^mUC: \!/9Wҥՠd (CNO G?ґ)]iK_ә9iOԡI]jSթVYjW֏_mnp!'3(O^zU^޺_#kq4jΘ#x%D>t/ ntJA+.D[_lT tf[AJv $=tg!9{~PY|+L>3?X-s2; ςP`'?+ťG=;_m $ߝү 8[7`8@$p(P,PFF@o/(0/Mc&DD O@T=/:P.4:?  A! QtP* Ҵp 0H\ @da,+<%"K)SD;]"d%؎V0"l"m̌Lwm:Q/Vo^+\ gp01^4.oooT#[/u utylnq=g_q0Qy/Q5 /jqq1SQQoW1qAEOt fD?Xd,WxW0!'W(SOT3-2:.Yj~spxM&$U0ErD.LL`rq L|v5@*!1P)))+R)(1+2)r,-r((2-,.2).- /o$=P QPZ"5r$2.03#?3H(> 3R%0=.fRCZRZ0Kp%9$6sM$7gDL2(//qo-O1|r*3*+p+20,)s0s;2./ӓ-r03<=2<>(.3>h&׌21p  3F }"124-%0WTBPC+MZ44U'I6M`%%?n#%MBODmnP'Kj8Yp,ɳH>Qk:*ٓ?QP+2?0a<39Ӕ>MM=TL;-۴/L09Z1 ]PEKt3-Q-/34wRTF 7=DO"5O7YrZ6%m8sVSdPBlWEOY*U3Zt\.=U.VX,{KU\e\+?ie;@ @  0 ag E[#,mB;n C/# S iE%OqLr1TQq.i#妍dpk, Ustn\N'Ue SJ/JtJ sOw wwqH[O/1\TSWxxuhH4kzwxe1zO92c"k*3b4Y1UI(7P~~Wv$WH US}%B~ p2.7eaV()$XXbOGPւ-΃I BxY{"U'ro3&-$`7w A),&PkGeq m w-#pWYUxV, |ShjsO׊Btx3aoX%8Dݕ]5)ʏc@)X Sf[ !%Dp‹/gmYjj [gӓjug5],U+]4V|moUzdEé2_y_w`/R:Ȳzbg吝{Sfg[VdG4wЫ%!c374Z%iVֱi#54 {V{i}V?Kh3{Xta`P@<1W[Z{3 U=2yaT'wmF!\Ts`ey?:+g\T\1;i}7S17"|#ʋѝ>4X:isLx# '3/?%7-,?5G!lx^T =tU9S< y=?8]Iۣym>Ln_ۃ^07OVcTE[\AGo C{ dQUϩ?m?kbzG m]zzꛛMZZ_R퉫'~WHwŇxU1Le0Z^DqNe %Q-+a1OGWs [< ^mpt֥&'R5G͂G&`?V[fFcFWwRQ)\4 "/hwAIP9e,j hU8 pbC[-IiV0WT%}hdS夝i9qr5F{,'l=tkJU+~fpRZVuYJCV))h~*aK":bgj:+xo/:*/VH=ɩ_0J륊ҋi ,Lb,H/BKjm*rjKFތsk m ?&% )I;:JET5EtҚ!G5qu4pfkWO+~3 p,+*p l h5! C ,K_xOy!7}0`䒲xv:p4 XT @1y%2R~BCkSn,jqaX8A{E6Z!ŨB3RHMJ#&z/? +&KysV`*ky˪#FƢK.y9C̼0c2˷]Ot8rcnz$?zkVtG VJk`7 )[:z MRԬ&VZ]dYM`:.O,c+^A?{sn6hO޲ jmݺB%nlݍAV5+-dTzȴ x1aL`o\{4JM[GVsc'N4!}ӕMg5tv Q6wXIQªmwCFr]'>z#I؇p|5M3ޚ{C*ڄeVj)C]a_ٛ~zDoӝGxY>S9%}ʃԋd2G{a.hn /4# }5Y_yWtz}Gzw}shkO |uR7[[ w2}{vx{r{ xR(|ubkn>Vht\UtOU:9k%.u]vYWvd%o'{@sܷOX*@qs`sfsFci]R'i!`uvyȇZĆ}b5='f\|>S%m@VLFp;؉qOdu<]p?|c4Z'7G|-8megr}ag* (c%Ȩr'& t(~vW'1Tp6;X9v]֌ΈGo73(pONJG"'x)Xe*IQGM%騎[T2(ȁq?1u2ysvb؂lD)s8xu$x)$\eK3'x-x)x({1n$(Y)-#Y(0ɌCI46}|xEPʵ(M$ex胏xaӮ<;>k@Kh*DL۞宫YZXO+7tź y㒶[jVY}r+㚱jd 7Ze=SJ4Iuყtwԁ u%;tT$zX]E=nIAՎP2Kqgbv!(XڭZ%ǃFYUXe<;*0[s }ؿ;LH |n4;Qy(B:6C܈ E$,`PN8ԝXI?7{99 A-#lk^.,|vqv@#E4ø:!lD,ٟrB2T%o**ŶCűҡ*5Dx0Z|:&t8#L!ᙋ9ڰe"%Ⱦ&'4Hj;qąv6Hv0¹%궭UZ~K[q,PLTZG!Αʀ(G_v^\Ô\\͑,i_=t̺G+Z9vȑӌΨț'M҅ >CL7vn#ڃ^!pF Уj_ncT(T(4Nn Aŭ3U/ ~ngt+ζ͠#J[rP`ÿ'-,j-c& J"o;>?>dx%63^rv=OqA2,/V=?F_Mm,inNoXN`1ɓ<ۤL |$! DgJD3Xʆ0ǑD|߃z隿IGz1/͟-o.^UL?[`5"|jk οZR wH༽Cpo`+rU8—h,ݟ"@Mָ:^iK^?]nਏߓgw>z\~zG-{7υ)MG] u6OEĆzQ-sZ>|1`;g1 jQk,z!ch`a1 a Kgb$f㰖}Rve5E0VPU CC"p}*go$-D=}>ʟ2'yY/ &XWⰈ2,_&7|GԚxQieRvEf!2׬5-biTZ9"S[vׄLvzxLP ǹaS%2+!H@U--R0ГӤ%9Kb2 C oe J7ڒRzJ &HJ2ї̤Δ1t3w(3@&6(No,ز}XA.Pw{MC%z:xkhPâћut+ԭ+&Z-N[LuJ&QxĨle|SUXI%z^B̠\+aG!TENq>sẔԬӞ#ꖵ+`7aJVrMk^V 8vE`ְX6ֱld%;YVֲlf5YvֳmhEXֲ5mjUZֵֶm;[w&V mnu[ַ-j;\׸-dRY4J ]jAv7mq]v׻.f^ƒwnzջ^·t.+0!A/G`r;`o<`/d{7>3$䦰](IW7,$ ! &H6G ?/EnӤ7TeFHY,-mrh>C± WLZ:ޟ:cMGd|{5c&3݌iDjѫnNYcu{h0'֋5ek^ze.CiO[t9XcIOK R]NTS,Ykr_Vur[$'Uh?4C(yz.vGlzy۔r YqoxYWx[ yÊ |/Q`Lf,35=[wx;u׷΅N M&iq83X*.V,>=p:͢vv~{,;;;-l t|ϡ3c0{՛2^om(xG`0z >A˻Y'k 2ġ::bi;, f+ӪB6*¡?T;A D0>#?,929\8Բ=>.@=+DC4@p7C8\p[PCdC:Tt˾|@KDDTƋ EC-˲ Gl?$n@GsGmydr|Fx :t\@gGzTBzœE +Q_ !(T<%oʿ}ce#GuG]ǑCy<ɓDDIy<{iIL=uDIvGwɅAjəGFDIt$ʀ"ExE2쥙Y%*`[6Eh*5K1U;HJ>ƖlI|Go,sTLIKâ,ʣE|<,L}I$Ev~lLń@s3dDSLGtLütDebJ[ |)I˴j͗ZKbTHLN܋t!\1μ̾ˤ Id0kLfTʚTɹLD JBGIK éL;(tjI͉φ\?̦ 3K-NgJ$Oz\ΗLzlKO̞ν< IфNLDL=L PG}4ı+4ũj%5R˭!ѯd&Tjm з #]Q47˹Sę=LPL$@E S-CNVtD,E<=;mDD=-5\OX,;/O sVJK|Bˏj̃MHXIO$! wL[\ݠTPg]s;3]-F]$&|ORާJ;iʥ ]OYMץΡL=S\P\M{ѱe\B7T\_\_7A}RgZ#̘pgNYuQ81[2[uM\Jl%^4=`y_0m#ܬ @^N[ &CU_ Q-Q(5dԓ!R\al N݄f9[5c'1Hr.t{EPQ%QBm)A]:4aZѣr6BiұB #Fs͛)F&±޳hZ4ҶdBe&}C)-E#Sx;_ [.V$`bdeM%e:nV`ah.1bNYcVT U,UhLrWU|fv6WLo]- Ђֿ,}ËM_c~VUW} "u4>Xΰ0fUc~h*}Vg(Fh"醊T&K/lB&:֪j,d#5-jh >K|Ķn뤆b]j)e* EQzì<6#Uve]漹FD.3+5܀z~Kc6ީ"Ni}^in@\Pʖ\iF'-c'>aՐ'%]-ckBVlFlsm 6t٦OZM-k[mm0vJ%h@~nǎ['nO ZzS3]&e`V^gVp۠lblipY% KTkMK.2jRRWUFXQ'`@^`RBT vg. L-f rmz$t`q(GX{rann'op)ru1ߎ,-^/gAq%83eWno<V*=o#@OAbČ'7./lWs>-k/CIJErgQsiA'xYD@^{VCsMWsW{uyvuO0/bw>uYK\Du6Ptutj*6Acw3>j/=,K@$USVq_KTZL0.oMS;7^xx`DzWDXy~o+3cq  qUtW %Nngneo;X|4Q@n?ؕ/O>xllWyzy]_z6%k`c+ z|lyLщye㡯5_y5 z>P&۵MIﳿnb&uwį?jWtk,4OoD$EwͶ_gz=}ԾO||z}ez3yg7{5_i|> j _Fwp$.֟P{ئ7}ZOyHH e}i uy~4ooYU퇀!b[gie dˊj,!K8, !`|BRqjb-1l>5F JgSyxi q(z0<0Y1PB.Vzv:pR^ZNv fRb~ fFҮѽMSW[_cgkosw{Cř (^6!Lp!ÆBf\r!8pcb? )r$ɒL _Œ)s&͚6R$cسP *t(ѢF"M*eNB*u*Շ9\xJK+Ӹl4>mW7k옢lm,'fj2{(]6 ".ީL~\mxD{}@6;5 lT r jMdB.9EqA|FBt眧޶H#s˷h Z7u]o+<~h1x:حozc/ _Y5mHi((]ʙP7HC*s\y+ |Y{g >8sL|#MUf4H Ed0:G?&d O//+F|_ NED'×PA nP"/DObZ\"(/1$]^h31ָh1r#h2Ez#6v iC"2ӪGB FHEb2d!x:08%)KuC,]юHzt8ˣm M+Qx˱ |Jd%#"3Δ\&3Da.EQ9d.URK$ !tEbEBfw*7~X/$ @&'> :," 3(BPX$HÃrd:D&&COpFҐ-4bVHSXzK/DKg$& /XҨYI>M[r+Ejիb9ubͅF{g6& j4&|EóM Jlj˄enbniy_kb5,JlG_ ܧSEnö٣纶ֽ&4vk=V/laXfT}x\.BV].s%jdz5`uzViDNn!mU[=ѪP>tjXh^yw %`P_gwqwQ 82R{ GXxE% xիd /avw%Ɯ1ˬL rpeO,9ij': jbWp܂RU#ָY]X;Tjc#;'C(gC[y΂mkc;ۍhxh;<"Cj`ٕ$.ݚ*O^ɱ|&b4L~. 7 gfvoY!]IDpI&ng>y2 n;sl>|1f'poc|﷡E9ы.r"dyN*Ո8uMY7~TTs)}Ӱ/0!aYW 5v߷xda,+?e2[Ś!./q~w!-jk;o~zRy<[ol>x%?T;m^n=7)Uyc@xMyxT3 6LRBbؔ+Xt_̛ ֭]ctT-ޔAp[r1`AK-iO-y\QMa^Sui`vN 6 |%- A z U)うL >W_UGr\O0anܗiH}!`pYչTfRXa^JЕݕV/ kYzUKݙ+@"!~]&rLb)bF'* '^A((,Ң(]*b.r+Z,/c0b1!/N/ 22c3JHAy%%|4@r96F#*I 1#::c8naQ5p_5R_O68‰͹ܼcB*Y ;R >=#.#P @ʩ(΁El-I6eMp UOH5*1OGƤ&DQaRdUZe/AK!W*?^ɣM Lc9><%`Fɕ##~aY[ Uf`bD&ЁeWreX&aBe%tXŒɈLdBeFZ\]~^^6ݤf)`fkGUWҦbfWrf d6fVdL[༘Xfnzf&faZ{L\>f{Jf<[g ʧ!%sg'j>aQu (;NL A٩ ٘o^pKdMGn^r(Jc~Q0U"FE]h&*A|ni2JsJ闂ibjiFH隲)QiEi ⩴)7i&;jhY2j$%iJ.;DFfjjD Rjj6deQnjƓ}HFjnx* ⪨½o(Zhk)=)kvCiRk'kj k*hemkk9c~k{kkufNhokBQhI#):A *bl[PlǞRƊzNQN ʲl˺llllm m"m*2B#R-lbmjrmzׂm؊ؒmlFb)ôch=$­mjզ\ ,Ժm:m>&6n,,2..JnBnZfn.Ң-ZL^6Zj-F$GFݾ+~noo&n/ /FoJ-| Lk#EJQ\6fyҮ\n}Zol:.-~-oV/ok. @ANCKp+N0XݨtlPn0rcP(wѵ/J6 p/.Kn np*1## 0+ڰ01?ng㮱-@A1PrKf>`*ҍ 6*2!07nq;%W2˱_rs2&0(+/%'c.*2N/&orr*&2+202%k2+rq#$TEZ2h ZSnl-"kFLL02**1'/s-;:ϳ:=/=3sS<)sa6OCuRNGATd.sVceGWpXktGtGsy 6KY)J/Zk޵Db6cv+ vb6d3O6e o5pgs<eovR+;/`kqa;RZh=R3Sy3A{zo[5p4eJ3[K wptnDŽR1u+ n'qtwv/8;7wW٢1s7@o5)q1fcq2xvS88Mx1Fxx+3yngS9` cyksKy>VyOŕwyy{I6j3Z9rۭ{p{|#*e&z5f1ulT.B7v?wWn:i$7ޮ:fuE]ڱ|&z>u;;rc+gW:u/w{zya\jFvÅaJ{ǫ_;v)scokiw︲,Szvvb:/;7[ _~dp` CP)Z흿xu§xY{' 81+xWxO11< /1<˗#C>>k?ut䳶[}[\wnzze|dN=6u~3T;{uNctCAJo%{OA1<[49Mź}q0U)Wo,&Zw )wK3X^Y\t>qyM|nƳ $ 2))%1+'!EA7MG'>O]_acegikmogʈfx~X{}{ar͵ QKq-J/Q5j{rJX ?Sx࿆Uu3BYa)_I'QTiR_LmS"]:bH '6,|Lh ͹3m1Vyhҧߚfպyq죕ՔhImڱmڞy;QYs}m[O܋޶",0Iz:^1}„tφ=ti2-h"Q(ִmw(Q+sv#s!\5iw5Ow^|;{J?|B2z]?|׿4js, LP\!p β 1Ͱ 9,iA QO;QYlaQ0Hq̱xQ!п"0@%D'R)+2-/8I&3LS1 (SL#N\S7ͨS=C㓌9˜#Ps DC̕ĸ%PZߦMk{߰HH'dRG-r $Ȉ kmcѮ[o\uk-&R ڌmGйEw[H_5BSMF5YV>/It]zw[Ua'yS}{|ˏgշkůY '76ne[BG%[+@isp⋝m}cx8K[e%5n-,rK\.jQB "PBtBG#2z0Ld 0\^mǽЎ_!>/Kps8:äa:r$[%\a8EI1[XT>f%/xG/}Ό+^ r+ۚ(GЗ؜EQ\TeH>n3U$98ύF$Fppw? %U3)ƶhhgIj`LpSL<HLb3C*?ƍ~ӡ$3^ i7G8?QA֫OTγ \=yJ}*%$a f_7}7>>G,u>eg %ikTцD%i:Ѿ5M=,6Hڸ.*X͚ <[)Vv]`ܞ k KCM[EڽQm'm[D=.)M67e!vw Z}!3;ڍI,nX^FR`L9K7Juz*ce)~Z4kH,sE{#--P;%lhP`.x MNO8UEMz{koƌm&czòqbuuoeg=DJ}bЁ/khEc ϊZPҕt|MRK&rAjQԥ6QjUխvakYϚֵqk]׽la6le/׋cmiOնmmomAq/r ]b[r\=xo}]U[)(#n7MpW; 7;-mާ8Ar%7Qrbܩ[qc~9[~ #8/q ʑt/Mwӡt4'zƏ^t,:׷>HB˞su[Qwwϝu'"׭un5N{S78n}ݐx-]myo;_'/x[_z\wpoP 00R&]a0e000V{PoӍX0 g 0 p _O岐obosBĜ ٰ 0 !0p6 1q!1%qd)-115q9=A1EqIMQ1UqY]a1eqimq1uqy}1q1q1q!-;kakoune-2019.07.01/doc/writing_scripts.asciidoc000066400000000000000000000113511350637360100212540ustar00rootroot00000000000000Writing kak scripts =================== Interaction with external tools from a Kakoune session is supported through the use of scripts. Once loaded by the editor (either automatically or manually), they allow extending the functionalities provided by default through commands and hooks. Their implementation should be kept as simple as possible, as they are not meant to be generic tools themselves but a mere API to actual software. --------------------------------------------------- +------+ +--> | tmux | | +------+ | +---------+ | +------+ | Kakoune | <-------> scripts +-+--> | X11 | +---------+ | +------+ | | +------+ +--> | ... | +------+ --------------------------------------------------- Dependencies ------------ The amount of dependencies of a given script should be kept to a minimum for practicality reasons, and have to be reasonable and expected considering the purpose of the script itself. Examples: * the `clang.kak` script provides with code completion using the `clang` compiler * the `tmux.kak` script provides with terminal splitting using the `tmux` multiplexer * the `ctags.kak` script provides with symbol lookups using the `readtags` utility provided by some `ctags` implementations Naming convention ----------------- All options and commands declared in a Kakoune script have to be prefixed with the name of the script, or a one word description of the purpose of the script. Examples: * in `tmux.kak`: command `tmux-new-window` * in `comment.kak`: option `comment_line` The following conventions apply as well: * *options*: if a separator is needed to separate a multiple word option name, an underscore should be used to allow shell scopes to use them * *commands*: if a separator is needed, a hyphen is usually used to differentiate a command name from an option's Documentation ------------- Non-hidden commands and options should always be declared with a documentation string, so that their purpose is clearly described whenever completed upon interactively from the prompt. POSIX shell ----------- Shell expansions are a useful tool to interact with an external utility, and the shell code that they contain should be as portable as possible. As such, scripts that rely on those expansions have to be implemented with POSIX in mind, most shells follow this standard nowadays which somewhat guarantees that the script will be portable across the most common systems. Common shell patterns --------------------- Printing variables ~~~~~~~~~~~~~~~~~~ In order to print a string that contains a variable expansion, prefer `printf` to `echo`, as the latter is implementation defined and may interpret some characters differently depending on the shell (e.g. flags, backslashes). ---------------------------------- printf %s\\n "${var}" printf "value: %s\\n" "${var}" ---------------------------------- The following won't cause any issues, as the string to print doesn't contain ambiguous characters: ------------------------------------- echo "set global scrolloff 999,0" ------------------------------------- Variable base name ~~~~~~~~~~~~~~~~~~ Replace `$(basename "${var}")` with `"${var##*/}"`. Testing ~~~~~~~ The `[[` keyword is provided by `bash`, and should be replaced with `[`. Standard error redirection ~~~~~~~~~~~~~~~~~~~~~~~~~~ Redirecting both standard and error streams is simplified in the `bash` shell with the `&>` operator, however this syntax is not portable and has to be replaced with the following: `>/dev/null 2>&1`. Regular expression ~~~~~~~~~~~~~~~~~~ The `bash` shell provides with a `[[` keyword that supports the `=~` operator to match a regular expression against a variable. This functionality can be implemented with the `expr` utility: * `expr "${var}" : '[a-z]*' >/dev/null` returns successfully when the variable is empty or only contains lowercase characters, otherwise a non-zero exit code is returned * `expr "${var}" : '\([a-z]*\)'` prints the variable when empty or only contains lowercase characters Note that the regular expression matches the whole string, using the `^` and `$` anchors is an undefined behavior. Running a process in the background ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In order to get a process running in the background without having it quit when the shell scope that spawns it terminates, use the following syntax: -------------------------------- { command } /dev/null 2>&1 & -------------------------------- kakoune-2019.07.01/gdb/000077500000000000000000000000001350637360100143105ustar00rootroot00000000000000kakoune-2019.07.01/gdb/kakoune.py000066400000000000000000000136071350637360100163260ustar00rootroot00000000000000import gdb.printing class ArrayIterator: def __init__(self, data, count): self.data = data self.count = count self.index = 0 def __iter__(self): return self def next(self): if self.index == self.count: raise StopIteration index = self.index self.index = self.index + 1 return ('[%d]' % index, (self.data + index).dereference()) def __next__(self): return self.next() class ArrayView: """Print a ArrayView""" def __init__(self, val): self.val = val def display_hint(self): return 'array' def children(self): return ArrayIterator(self.val['m_pointer'], self.val['m_size']) def to_string(self): type = self.val.type.template_argument(0).unqualified().strip_typedefs() return "ArrayView<%s>" % (type) class LineAndColumn: """Print a LineAndColumn""" def __init__(self, val): self.val = val def to_string(self): value_type = self.val.type.unqualified() return "%s(%s, %s)" % (value_type, self.val['line'], self.val['column']) class BufferCoordAndTarget: """Print a BufferCoordAndTarget""" def __init__(self, val): self.val = val def to_string(self): value_type = self.val.type.unqualified() return "%s(%s, %s, %s)" % (value_type, self.val['line'], self.val['column'], self.val['target']) class BufferIterator: """ Print a BufferIterator""" def __init__(self, val): self.val = val def to_string(self): line = self.val['m_coord']['line'] column = self.val['m_coord']['column'] if self.val['m_buffer']['m_ptr'] != 0: buf = self.val['m_buffer']['m_ptr'].dereference()['m_name'] return "buffer<%s>@(%s, %s)" % (buf, line, column) else: return "buffer@(%s, %s)" % (line, column) class String: """ Print a String""" def __init__(self, val): self.val = val def to_string(self): data = self.val["m_data"] if (data["s"]["size"] & 1) != 1: ptr = data["l"]["ptr"] len = data["l"]["size"] else: ptr = data["s"]["string"] len = data["s"]["size"] >> 1 return "\"%s\"" % (ptr.string("utf-8", "ignore", len)) class StringView: """ Print a StringView""" def __init__(self, val): self.val = val def to_string(self): len = self.val['m_length']['m_value'] return "\"%s\"" % (self.val['m_data'].string("utf-8", "ignore", len)) class StringDataPtr: """ Print a RefPtr""" def __init__(self, val): self.val = val def to_string(self): ptr = self.val['m_ptr'] str_type = gdb.lookup_type("char").pointer() len = ptr.dereference()['length'] refcount = ptr.dereference()['refcount'] content = (ptr + 1).cast(str_type).string("utf-8", "ignore", len) return "\"%s\" (ref:%d)" % (content.replace("\n", "\\n"), refcount) class RefPtr: """ Print a RefPtr""" def __init__(self, val): self.val = val def to_string(self): ptr = self.val['m_ptr'] return "\"refptr %s\"" % (ptr) class Option: """ Print a Option""" def __init__(self, val): self.val = val def to_string(self): return self.val["m_value"] class CharCount: """Print a CharCount""" def __init__(self, val): self.val = val def to_string(self): return self.val["m_value"] class ColumnCount: """Print a ColumnCount""" def __init__(self, val): self.val = val def to_string(self): return self.val["m_value"] class ByteCount: """Print a ByteCount""" def __init__(self, val): self.val = val def to_string(self): return self.val["m_value"] class LineCount: """Print a LineCount""" def __init__(self, val): self.val = val def to_string(self): return self.val["m_value"] class Color: """Print a Color""" def __init__(self, val): self.val = val def to_string(self): named_color = gdb.lookup_type("Kakoune::Color::NamedColor") if self.val["color"] == named_color["Kakoune::Color::RGB"].enumval: return "%s #%02x%02x%02x" % (self.val["color"], self.val["r"], self.val["g"], self.val["b"]) else: return self.val["color"] class Regex: """Print a Regex""" def __init__(self, val): self.val = val def to_string(self): return "regex%s" % (self.val["m_str"]) def build_pretty_printer(): pp = gdb.printing.RegexpCollectionPrettyPrinter("kakoune") pp.add_printer('ArrayView', '^Kakoune::(Const)?ArrayView<.*>$', ArrayView) pp.add_printer('LineAndColumn', '^Kakoune::(Buffer|Display)Coord$', LineAndColumn) pp.add_printer('BufferCoordAndTarget', '^Kakoune::BufferCoordAndTarget$', BufferCoordAndTarget) pp.add_printer('BufferIterator', '^Kakoune::BufferIterator$', BufferIterator) pp.add_printer('String', '^Kakoune::String$', String) pp.add_printer('StringView', '^Kakoune::(StringView|SharedString)$', StringView) pp.add_printer('StringDataPtr', '^Kakoune::StringDataPtr$', StringDataPtr) pp.add_printer('StringDataPtr', '^Kakoune::RefPtr$', StringDataPtr) pp.add_printer('RefPtr', '^Kakoune::RefPtr<.*>$', RefPtr) pp.add_printer('Option', '^Kakoune::Option$', Option) pp.add_printer('LineCount', '^Kakoune::LineCount$', LineCount) pp.add_printer('CharCount', '^Kakoune::CharCount$', CharCount) pp.add_printer('ColumnCount', '^Kakoune::ColumnCount$', ColumnCount) pp.add_printer('ByteCount', '^Kakoune::ByteCount$', ByteCount) pp.add_printer('Color', '^Kakoune::Color$', Color) pp.add_printer('Regex', '^Kakoune::Regex$', Regex) return pp kakoune-2019.07.01/rc/000077500000000000000000000000001350637360100141605ustar00rootroot00000000000000kakoune-2019.07.01/rc/detection/000077500000000000000000000000001350637360100161365ustar00rootroot00000000000000kakoune-2019.07.01/rc/detection/editorconfig.kak000066400000000000000000000060461350637360100213100ustar00rootroot00000000000000# http://editorconfig.org/#file-format-details # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*[.](editorconfig) %{ set-option buffer filetype ini set-option buffer static_words indent_style indent_size tab_width \ end_of_line charset insert_final_newline trim_trailing_whitespace root \ latin1 utf-8 utf-8-bom utf-16be utf-16le lf cr crlf unset space tab max_line_length } declare-option -hidden bool editorconfig_trim_trailing_whitespace false define-command editorconfig-load -params ..1 -docstring "editorconfig-load [file]: set formatting behavior according to editorconfig" %{ remove-hooks buffer editorconfig-hooks evaluate-commands %sh{ command -v editorconfig >/dev/null 2>&1 || { echo 'echo -markup "{Error}editorconfig could not be found"'; exit 1; } editorconfig "${1:-$kak_buffile}" | awk -F= -- ' /indent_style=/ { indent_style = $2 } /indent_size=/ { indent_size = $2 == "tab" ? 4 : $2 } /tab_width=/ { tab_width = $2 } /end_of_line=/ { end_of_line = $2 } /charset=/ { charset = $2 } /trim_trailing_whitespace=/ { trim_trailing_whitespace = $2 } /max_line_length=/ { max_line_length = $2 } END { if (indent_style == "tab") { print "set-option buffer indentwidth 0" print "set-option buffer aligntab true" } if (indent_style == "space") { print "set-option buffer indentwidth " (indent_size == "tab" ? 4 : indent_size) print "set-option buffer aligntab false" } if (indent_size || tab_width) { print "set-option buffer tabstop " (tab_width ? tab_width : indent_size) } if (end_of_line == "lf" || end_of_line == "crlf") { print "set-option buffer eolformat " end_of_line } if (charset == "utf-8-bom") { print "set-option buffer BOM utf8" } if (trim_trailing_whitespace == "true") { print "set-option buffer editorconfig_trim_trailing_whitespace true" } if (max_line_length && max_line_length != "off") { print "set window autowrap_column " max_line_length print "autowrap-enable" print "add-highlighter window/ column %sh{ echo $((" max_line_length "+1)) } default,bright-black" } } ' } hook buffer BufWritePre %val{buffile} -group editorconfig-hooks %{ evaluate-commands %sh{ if [ ${kak_opt_editorconfig_trim_trailing_whitespace} = "true" ]; then printf %s\\n "try %{ execute-keys -draft %{ %s\h+$d } }" fi } } } kakoune-2019.07.01/rc/detection/file.kak000066400000000000000000000012631350637360100175470ustar00rootroot00000000000000hook global BufOpenFile .* %{ evaluate-commands %sh{ if [ -z "${kak_opt_filetype}" ]; then mime=$(file -b -i -L "${kak_buffile}") mime=${mime%;*} case "${mime}" in application/*+xml) filetype="xml" ;; image/*+xml) filetype="xml" ;; #SVG message/rfc822) filetype="mail" ;; text/x-shellscript) filetype="sh" ;; text/x-*) filetype="${mime#text/x-}" ;; text/*) filetype="${mime#text/}" ;; application/*) filetype="${mime#application/}" ;; esac if [ -n "${filetype}" ]; then printf "set-option buffer filetype '%s'\n" "${filetype}" fi fi } } kakoune-2019.07.01/rc/detection/modeline.kak000066400000000000000000000103531350637360100204240ustar00rootroot00000000000000## ## modeline.kak by lenormf ## ## Currently supported modeline format: vim ## Also supports kakoune options with a 'kak' or 'kakoune' prefix ## Only a few options are supported, in order to prevent the ## buffers from poking around the configuration too much declare-option -docstring "amount of lines that will be checked at the beginning and the end of the buffer" \ int modelines 5 define-command -hidden modeline-parse-impl %{ evaluate-commands %sh{ # Translate a vim option into the corresponding kakoune one translate_opt_vim() { readonly key="$1" readonly value="$2" tr="" case "${key}" in so|scrolloff) tr="scrolloff ${value},${kak_opt_scrolloff##*,}";; siso|sidescrolloff) tr="scrolloff ${kak_opt_scrolloff%%,*},${value}";; ts|tabstop) tr="tabstop ${value}";; sw|shiftwidth) tr="indentwidth ${value}";; tw|textwidth) tr="autowrap_column ${value}";; ff|fileformat) case "${value}" in unix) tr="eolformat lf";; dos) tr="eolformat crlf";; *) printf %s\\n "echo -debug 'Unsupported file format: ${value}'";; esac ;; ft|filetype) tr="filetype ${value}";; bomb) tr="BOM utf8";; nobomb) tr="BOM none";; *) printf %s\\n "echo -debug 'Unsupported vim variable: ${key}'";; esac [ -n "${tr}" ] && printf %s\\n "set-option buffer ${tr}" } # Pass a few whitelisted options to kakoune directly translate_opt_kakoune() { readonly key="$1" readonly value="$2" case "${key}" in scrolloff|tabstop|indentwidth|autowrap_column|eolformat|filetype|BOM);; *) printf %s\\n "echo -debug 'Unsupported kakoune variable: ${key}'" return;; esac printf %s\\n "set-option buffer ${key} ${value}" } case "${kak_selection}" in *vi:*|*vim:*) type_selection="vim";; *kak:*|*kakoune:*) type_selection="kakoune";; *) echo "echo -debug Unsupported modeline format";; esac [ -n "${type_selection}" ] || exit 1 # The following subshell will keep the actual options of the modeline, and strip: # - the text that leads the first option, according to the official vim modeline format # - the trailing text after the last option, and an optional ':' sign before it # It will also convert the ':' seperators beween the option=value pairs # More info: http://vimdoc.sourceforge.net/htmldoc/options.html#modeline printf %s "${kak_selection}" | sed \ -e 's/^[^:]\{1,\}://' \ -e 's/[ \t]*set\{0,1\}[ \t]//' \ -e 's/:[^a-zA-Z0-9_=-]*$//' \ -e 's/:/ /g' \ | tr ' ' '\n' \ | while read -r option; do name_option="${option%%=*}" value_option="${option#*=}" [ -z "${option}" ] && continue case "${type_selection}" in vim) tr=$(translate_opt_vim "${name_option}" "${value_option}");; kakoune) tr=$(translate_opt_kakoune "${name_option}" "${value_option}");; esac [ -n "${tr}" ] && printf %s\\n "${tr}" done } } # Add the following function to a hook on BufOpenFile to automatically parse modelines # Select the first and last `modelines` lines in the buffer, only keep modelines # ref. options.txt (in vim `:help options`) : 2 forms of modelines: # [text]{white}{vi:|vim:|ex:}[white]{options} # [text]{white}{vi:|vim:|Vim:|ex:}[white]se[t] {options}:[text] define-command modeline-parse -docstring "Read and interpret vi-format modelines at the beginning/end of the buffer" %{ try %{ evaluate-commands -draft %{ execute-keys \%s\A|.\z %opt{modelines}k %opt{modelines}X \ s^\S*?\s+?(vim?|kak(oune)?):\s?[^\n]+ evaluate-commands -draft -itersel modeline-parse-impl } } } kakoune-2019.07.01/rc/filetype/000077500000000000000000000000001350637360100160015ustar00rootroot00000000000000kakoune-2019.07.01/rc/filetype/arch-linux.kak000066400000000000000000000001551350637360100205440ustar00rootroot00000000000000# package build description file hook global BufCreate (.*/)?PKGBUILD %{ set-option buffer filetype sh } kakoune-2019.07.01/rc/filetype/asciidoc.kak000066400000000000000000000034151350637360100202520ustar00rootroot00000000000000# http://asciidoc.org/ # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .+\.(a(scii)?doc|asc) %{ set-option buffer filetype asciidoc } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook -group asciidoc-highlight global WinSetOption filetype=asciidoc %{ require-module asciidoc add-highlighter window/asciidoc ref asciidoc hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/asciidoc } } provide-module asciidoc %{ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/asciidoc group add-highlighter shared/asciidoc/ regex (\A|\n\n)[^\n]+\n={2,}\h*$ 0:title add-highlighter shared/asciidoc/ regex (\A|\n\n)[^\n]+\n-{2,}\h*$ 0:header add-highlighter shared/asciidoc/ regex (\A|\n\n)[^\n]+\n~{2,}\h*$ 0:header add-highlighter shared/asciidoc/ regex (\A|\n\n)[^\n]+\n\^{2,}\h*$ 0:header add-highlighter shared/asciidoc/ regex (\A|\n\n)=\h+[^\n]+$ 0:title add-highlighter shared/asciidoc/ regex (\A|\n\n)={2,}\h+[^\n]+$ 0:header add-highlighter shared/asciidoc/ regex ^\h+([-\*])\h+[^\n]*(\n\h+[^-\*]\S+[^\n]*)*$ 0:list 1:bullet add-highlighter shared/asciidoc/ regex ^(-{3,})\n[^\n\h].*?\n(-{3,})$ 0:block add-highlighter shared/asciidoc/ regex ^(={3,})\n[^\n\h].*?\n(={3,})$ 0:block add-highlighter shared/asciidoc/ regex ^(~{3,})\n[^\n\h].*?\n(~{3,})$ 0:block add-highlighter shared/asciidoc/ regex ^(\*{3,})\n[^\n\h].*?\n(\*{3,})$ 0:block add-highlighter shared/asciidoc/ regex \B(?:\+[^\n]+?\+|`[^\n]+?`)\B 0:mono add-highlighter shared/asciidoc/ regex \b_[^\n]+?_\b 0:italic add-highlighter shared/asciidoc/ regex \B\*[^\n]+?\*\B 0:bold add-highlighter shared/asciidoc/ regex ^:[-\w]+: 0:meta # Commands # ‾‾‾‾‾‾‾‾ } kakoune-2019.07.01/rc/filetype/awk.kak000066400000000000000000000064221350637360100172570ustar00rootroot00000000000000# Detection # --------- hook global BufCreate .*\.awk %{ set-option buffer filetype awk } # Initialization # -------------- hook global WinSetOption filetype=awk %{ require-module awk hook window InsertChar \n -group awk-indent awk-indent-on-new-line hook window ModeChange insert:.* -group awk-trim-indent awk-trim-indent hook -once -always window WinSetOption filetype=.* %{ remove-hooks window awk-.+ } } hook -group awk-highlight global WinSetOption filetype=awk %{ add-highlighter window/awk ref awk hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/awk } } provide-module awk %@ # Highlighters # ------------ add-highlighter shared/awk regions add-highlighter shared/awk/code default-region group add-highlighter shared/awk/comment region '#' '$' fill comment add-highlighter shared/awk/string region '"' (?|\?|~ 0:operator evaluate-commands %sh{ # Grammar patterns="BEGIN END BEGINFILE ENDFILE" variables="BINMODE CONVFMT FIELDWIDTHS FPAT FS IGNORECASE LINT OFMT OFS ORS PREC ROUNDMODE RS SUBSEP TEXTDOMAIN ARGC ARGV ARGIND ENVIRON ERRNO FILENAME FNR NF FUNCTAB NR PROCINFO RLENGTH RSTART RT SYMTAB" keywords="break continue delete exit function getline next print printf return switch nextfile func if else while for do" functions="atan2 cos exp int intdiv log rand sin sqrt srand asort asort1 gensub gsub index length match patsplit split sprintf strtonum sub substr tolower toupper close fflush system mktime strftime systime and compl lshift or rshift xor isarray typeof bindtextdomain dcgettext dcngetext" join() { sep=$2; eval set -- $1; IFS="$sep"; echo "$*"; } # Add the language's grammar to the static completion list printf %s\\n "hook global WinSetOption filetype=awk %{ set-option window static_words $(join "${patterns} ${variables} ${keywords} ${functions}" ' ') }" # Highlight keywords printf %s\\n "add-highlighter shared/awk/code/ regex \b($(join "${patterns}" '|'))\b 0:type" printf %s\\n "add-highlighter shared/awk/code/ regex \b($(join "${variables}" '|'))\b 0:meta" printf %s\\n "add-highlighter shared/awk/code/ regex \b($(join "${keywords}" '|'))\b 0:keyword" printf %s\\n "add-highlighter shared/awk/code/ regex \b($(join "${functions}" '|'))\b 0:function" } # Commands # -------- define-command -hidden awk-indent-on-new-line %[ evaluate-commands -draft -itersel %[ # preserve previous line indent try %[ execute-keys -draft \; K ] # cleanup trailing whitespaces from previous line try %[ execute-keys -draft k s \h+$ d ] # indent after line ending in opening curly brace try %[ execute-keys -draft k \{\h*(#.*)?$ j ] ] ] define-command -hidden awk-trim-indent %{ try %{ execute-keys -draft \; s ^\h+$ d } } @ kakoune-2019.07.01/rc/filetype/c-family.kak000066400000000000000000000577731350637360100202150ustar00rootroot00000000000000hook global BufCreate .*\.(cc|cpp|cxx|C|hh|hpp|hxx|H)$ %{ set-option buffer filetype cpp } hook global BufSetOption filetype=c\+\+ %{ hook -once buffer NormalIdle '' "set-option buffer filetype cpp" } hook global BufCreate .*\.c$ %{ set-option buffer filetype c } hook global BufCreate .*\.h$ %{ try %{ execute-keys -draft %{%s\b::\b|\btemplate\h*|\bclass\h+\w+|\b(typename|namespace)\b|\b(public|private|protected)\h*:} set-option buffer filetype cpp } catch %{ set-option buffer filetype c } } hook global BufCreate .*\.m %{ set-option buffer filetype objc } hook global WinSetOption filetype=(c|cpp|objc) %[ require-module c-family evaluate-commands "set-option window static_words %%opt{%val{hook_param_capture_1}_static_words}" hook -group "%val{hook_param_capture_1}-trim-indent" window ModeChange insert:.* c-family-trim-indent hook -group "%val{hook_param_capture_1}-insert" window InsertChar \n c-family-insert-on-newline hook -group "%val{hook_param_capture_1}-indent" window InsertChar \n c-family-indent-on-newline hook -group "%val{hook_param_capture_1}-indent" window InsertChar \{ c-family-indent-on-opening-curly-brace hook -group "%val{hook_param_capture_1}-indent" window InsertChar \} c-family-indent-on-closing-curly-brace hook -group "%val{hook_param_capture_1}-insert" window InsertChar \} c-family-insert-on-closing-curly-brace alias window alt "%val{hook_param_capture_1}-alternative-file" hook -once -always window WinSetOption filetype=.* " remove-hooks window %val{hook_param_capture_1}-.+ unalias window alt %val{hook_param_capture_1}-alternative-file " ] hook -group c-highlight global WinSetOption filetype=c %{ add-highlighter window/c ref c hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/c } } hook -group cpp-highlight global WinSetOption filetype=cpp %{ add-highlighter window/cpp ref cpp hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/cpp } } hook -group objc-highlight global WinSetOption filetype=objc %{ add-highlighter window/objc ref objc hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/objc } } provide-module c-family %§ define-command -hidden c-family-trim-indent %{ # remove the line if it's empty when leaving the insert mode try %{ execute-keys -draft 1s^(\h+)$ d } } define-command -hidden c-family-indent-on-newline %< evaluate-commands -draft -itersel %< execute-keys \; try %< # if previous line is part of a comment, do nothing execute-keys -draft /\* ^\h*[^/*\h] > catch %< # else if previous line closed a paren (possibly followed by words and a comment), # copy indent of the opening paren line execute-keys -draft k 1s(\))(\h+\w+)*\h*(\;\h*)?(?://[^\n]+)?\n\z mJ 1 > catch %< # else indent new lines with the same level as the previous one execute-keys -draft K > # remove previous empty lines resulting from the automatic indent try %< execute-keys -draft k ^\h+$ Hd > # indent after an opening brace or parenthesis at end of line try %< execute-keys -draft k s[{(]\h*$ j > # indent after a label try %< execute-keys -draft k s[a-zA-Z0-9_-]+:\h*$ j > # indent after a statement not followed by an opening brace try %< execute-keys -draft k s\)\h*(?://[^\n]+)?\n\z \ mB \A\b(if|for|while)\b j > try %< execute-keys -draft k s \belse\b\h*(?://[^\n]+)?\n\z \ j > # deindent after a single line statement end try %< execute-keys -draft K \;\h*(//[^\n]+)?$ \ K s\)(\h+\w+)*\h*(//[^\n]+)?\n([^\n]*\n){2}\z \ MB \A\b(if|for|while)\b 1 > try %< execute-keys -draft K \;\h*(//[^\n]+)?$ \ K s \belse\b\h*(?://[^\n]+)?\n([^\n]*\n){2}\z \ 1 > # align to the opening parenthesis or opening brace (whichever is first) # on a previous line if its followed by text on the same line try %< evaluate-commands -draft %< # Go to opening parenthesis and opening brace, then select the most nested one try %< execute-keys [c [({],[)}] > # Validate selection and get first and last char execute-keys \A[{(](\h*\S+)+\n "(([^"]*"){2})* '(([^']*'){2})* L # Remove possibly incorrect indent from new line which was copied from previous line try %< execute-keys -draft s\h+ d > # Now indent and align that new line with the opening parenthesis/brace execute-keys 1 & > > > > define-command -hidden c-family-indent-on-opening-curly-brace %[ # align indent with opening paren when { is entered on a new line after the closing paren try %[ execute-keys -draft -itersel h)M \A\(.*\)\h*\n\h*\{\z 1 ] ] define-command -hidden c-family-indent-on-closing-curly-brace %[ # align to opening curly brace when alone on a line try %[ # in case open curly brace follows a closing paren, align indent with opening paren execute-keys -itersel -draft ^\h+\}$hm )M \A\(.*\)\h\{.*\}\z 1 ] catch %[ # otherwise align with open curly brace execute-keys -itersel -draft ^\h+\}$hm1 ] catch %[] ] define-command -hidden c-family-insert-on-closing-curly-brace %[ # add a semicolon after a closing brace if part of a class, union or struct definition try %[ execute-keys -itersel -draft hmB\A\h*(class|struct|union|enum) ';i;' ] ] define-command -hidden c-family-insert-on-newline %[ evaluate-commands -itersel -draft %[ execute-keys \; try %[ evaluate-commands -draft -save-regs '/"' %[ # copy the commenting prefix execute-keys -save-regs '' k 1s^\h*(//+\h*) y try %[ # if the previous comment isn't empty, create a new one execute-keys ^\h*//+\h*$ js^\h*P ] catch %[ # if there is no text in the previous comment, remove it completely execute-keys d ] ] ] try %[ # if the previous line isn't within a comment scope, break execute-keys -draft k ^(\h*/\*|\h+\*(?!/)) # find comment opening, validate it was not closed, and check its using star prefixes execute-keys -draft /\* \*/ \A\h*/\*([^\n]*\n\h*\*)*[^\n]*\n\h*.\z try %[ # if the previous line is opening the comment, insert star preceeded by space execute-keys -draft k^\h*/\* execute-keys -draft i* ] catch %[ try %[ # if the next line is a comment line insert a star execute-keys -draft j^\h+\* execute-keys -draft i* ] catch %[ try %[ # if the previous line is an empty comment line, close the comment scope execute-keys -draft k^\h+\*\h+$ 1s\*(\h*)c/ ] catch %[ # if the previous line is a non-empty comment line, add a star execute-keys -draft i* ] ] ] # trim trailing whitespace on the previous line try %[ execute-keys -draft s\h+$ d ] # align the new star with the previous one execute-keys K1s^[^*]*(\*)& ] ] ] # Regions definition are the same between c++ and objective-c evaluate-commands %sh{ for ft in c cpp objc; do if [ "${ft}" = "objc" ]; then maybe_at='@?' else maybe_at='' fi cat <<-EOF add-highlighter shared/$ft regions add-highlighter shared/$ft/code default-region group add-highlighter shared/$ft/string region %{$maybe_at(?%ggxs\.c_A_INCLUDEDggxyppI#ifndefjI#definejI#endif//O' ;; pragma) echo 'execute-keys ggi#pragmaonce' ;; *);; esac } } hook -group c-family-insert global BufNewFile .*\.(h|hh|hpp|hxx|H) c-family-insert-include-guards declare-option -docstring "colon separated list of path in which header files will be looked for" \ str-list alt_dirs '.' '..' define-command -hidden c-family-alternative-file %{ evaluate-commands %sh{ file="${kak_buffile##*/}" file_noext="${file%.*}" dir=$(dirname "${kak_buffile}") # Set $@ to alt_dirs eval "set -- ${kak_quoted_opt_alt_dirs}" case ${file} in *.c|*.cc|*.cpp|*.cxx|*.C|*.inl|*.m) for alt_dir in "$@"; do for ext in h hh hpp hxx H; do altname="${dir}/${alt_dir}/${file_noext}.${ext}" if [ -f ${altname} ]; then printf 'edit %%{%s}\n' "${altname}" exit fi done done ;; *.h|*.hh|*.hpp|*.hxx|*.H) for alt_dir in "$@"; do for ext in c cc cpp cxx C m; do altname="${dir}/${alt_dir}/${file_noext}.${ext}" if [ -f ${altname} ]; then printf 'edit %%{%s}\n' "${altname}" exit fi done done ;; *) echo "echo -markup '{Error}extension not recognized'" exit ;; esac echo "echo -markup '{Error}alternative file not found'" } } define-command c-alternative-file -docstring "Jump to the alternate c file (header/implementation)" %{ c-family-alternative-file } define-command cpp-alternative-file -docstring "Jump to the alternate cpp file (header/implementation)" %{ c-family-alternative-file } define-command objc-alternative-file -docstring "Jump to the alternate objc file (header/implementation)" %{ c-family-alternative-file } § kakoune-2019.07.01/rc/filetype/cabal.kak000066400000000000000000000054421350637360100175400ustar00rootroot00000000000000# http://haskell.org/cabal # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*[.](cabal) %{ set-option buffer filetype cabal } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=cabal %[ require-module cabal hook window ModeChange insert:.* -group cabal-trim-indent cabal-trim-indent hook window InsertChar \n -group cabal-indent cabal-indent-on-new-line hook window InsertChar \{ -group cabal-indent cabal-indent-on-opening-curly-brace hook window InsertChar \} -group cabal-indent cabal-indent-on-closing-curly-brace hook -once -always window WinSetOption filetype=.* %{ remove-hooks window cabal-.+ } ] hook -group cabal-highlight global WinSetOption filetype=cabal %{ add-highlighter window/cabal ref cabal hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/cabal } } provide-module cabal %[ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/cabal regions add-highlighter shared/cabal/code default-region group add-highlighter shared/cabal/line_comment region (--) $ fill comment add-highlighter shared/cabal/comment region -recurse \{- \{- -\} fill comment add-highlighter shared/cabal/code/ regex \b(true|false)\b|(([<>]?=?)?\d+(\.\d+)+) 0:value add-highlighter shared/cabal/code/ regex \b(if|else)\b 0:keyword add-highlighter shared/cabal/code/ regex ^\h*([A-Za-z][A-Za-z0-9_-]*)\h*: 1:variable # Commands # ‾‾‾‾‾‾‾‾ define-command -hidden cabal-trim-indent %{ # remove trailing white spaces try %{ execute-keys -draft -itersel s \h+$ d } } define-command -hidden cabal-indent-on-new-line %[ evaluate-commands -draft -itersel %[ # copy '#' comment prefix and following white spaces try %[ execute-keys -draft k s ^\h*\K#\h* y gh j P ] # preserve previous line indent try %[ execute-keys -draft \; K ] # filter previous line try %[ execute-keys -draft k : cabal-trim-indent ] # indent after lines ending with { or : try %[ execute-keys -draft k [:{]$ j ] ] ] define-command -hidden cabal-indent-on-opening-curly-brace %[ evaluate-commands -draft -itersel %[ # align indent with opening paren when { is entered on a new line after the closing paren try %[ execute-keys -draft h ) M \A\(.*\)\h*\n\h*\{\z s \A|.\z 1 ] ] ] define-command -hidden cabal-indent-on-closing-curly-brace %[ evaluate-commands -draft -itersel %[ # align to opening curly brace when alone on a line try %[ execute-keys -draft ^\h+\}$ h m s \A|.\z 1 ] ] ] ] kakoune-2019.07.01/rc/filetype/clojure.kak000066400000000000000000000266171350637360100201500ustar00rootroot00000000000000# http://clojure.org # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*[.](clj|cljc|cljs|cljx|edn) %{ set-option buffer filetype clojure } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=clojure %[ require-module clojure set-option window static_words %opt{clojure_static_words} hook window ModeChange insert:.* -group clojure-trim-indent clojure-trim-indent hook window InsertChar \n -group clojure-indent clojure-indent-on-new-line hook -once -always window WinSetOption filetype=.* %{ remove-hooks window clojure-.+ } ] hook -group clojure-highlight global WinSetOption filetype=clojure %{ add-highlighter window/clojure ref clojure hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/clojure } } provide-module clojure %{ require-module lisp # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/clojure regions add-highlighter shared/clojure/code default-region group add-highlighter shared/clojure/comment region '(? ! : "'" } evaluate-commands %sh{ exec awk -f - <<'EOF' BEGIN{ symbol_char="[^\\s()\\[\\]{}\"\\;@^`~\\\\%/]"; in_core="(clojure\\.core/|(? cond->> def definline definterface defmacro defmethod "\ "defmulti defn defn- defonce defprotocol defrecord defstruct deftype fn if "\ "if-let if-not if-some let letfn new ns when when-first when-let when-not "\ "when-some . ..", keywords); split( \ "* *' + +' - -' -> ->> ->ArrayChunk ->Eduction ->Vec ->VecNode ->VecSeq / < "\ "<= = == > >= StackTraceElement->vec Throwable->map accessor aclone "\ "add-classpath add-watch agent agent-error agent-errors aget alength alias "\ "all-ns alter alter-meta! alter-var-root amap ancestors and any? apply "\ "areduce array-map as-> aset aset-boolean aset-byte aset-char aset-double "\ "aset-float aset-int aset-long aset-short assert assoc assoc! assoc-in "\ "associative? atom await await-for bases bean bigdec bigint biginteger "\ "binding bit-and bit-and-not bit-clear bit-flip bit-not bit-or bit-set "\ "bit-shift-left bit-shift-right bit-test bit-xor boolean boolean-array "\ "boolean? booleans bound-fn bound-fn* bound? bounded-count butlast byte "\ "byte-array bytes bytes? cast cat catch char char-array char-escape-string "\ "char-name-string char? chars class class? clear-agent-errors "\ "clojure-version coll? comment commute comp comparator compare "\ "compare-and-set! compile complement completing concat conj conj! cons "\ "constantly construct-proxy contains? count counted? create-ns "\ "create-struct cycle dec dec' decimal? declare dedupe default-data-readers "\ "delay delay? deliver denominator deref derive descendants disj disj! "\ "dissoc dissoc! distinct distinct? do doall dorun doseq dosync dotimes doto "\ "double double-array double? doubles drop drop-last drop-while eduction "\ "empty empty? ensure ensure-reduced enumeration-seq error-handler "\ "error-mode eval even? every-pred every? ex-data ex-info extend "\ "extend-protocol extend-type extenders extends? false? ffirst file-seq "\ "filter filterv finally find find-keyword find-ns find-var first flatten "\ "float float-array float? floats flush fn? fnext fnil for force format "\ "frequencies future future-call future-cancel future-cancelled? "\ "future-done? future? gen-class gen-interface gensym get get-in get-method "\ "get-proxy-class get-thread-bindings get-validator group-by halt-when hash "\ "hash-map hash-ordered-coll hash-set hash-unordered-coll ident? identical? "\ "identity ifn? import in-ns inc inc' indexed? init-proxy inst-ms inst? "\ "instance? int int-array int? integer? interleave intern interpose into "\ "into-array ints io! isa? iterate iterator-seq juxt keep keep-indexed key "\ "keys keyword keyword? last lazy-cat lazy-seq line-seq list list* list? "\ "load load-file load-reader load-string loaded-libs locking long long-array "\ "longs loop macroexpand macroexpand-1 make-array make-hierarchy map "\ "map-entry? map-indexed map? mapcat mapv max max-key memfn memoize merge "\ "merge-with meta methods min min-key mix-collection-hash mod monitor-enter "\ "monitor-exit name namespace namespace-munge nat-int? neg-int? neg? newline "\ "next nfirst nil? nnext not not-any? not-empty not-every? not= ns-aliases "\ "ns-imports ns-interns ns-map ns-name ns-publics ns-refers ns-resolve "\ "ns-unalias ns-unmap nth nthnext nthrest num number? numerator object-array "\ "odd? or parents partial partition partition-all partition-by pcalls peek "\ "persistent! pmap pop pop! pop-thread-bindings pos-int? pos? pr pr-str "\ "prefer-method prefers print print-str printf println println-str prn "\ "prn-str promise proxy proxy-mappings proxy-super push-thread-bindings "\ "pvalues qualified-ident? qualified-keyword? qualified-symbol? quot quote "\ "rand rand-int rand-nth random-sample range ratio? rational? rationalize "\ "re-find re-groups re-matcher re-matches re-pattern re-seq read read-line "\ "read-string reader-conditional reader-conditional? realized? record? recur "\ "reduce reduce-kv reduced reduced? reductions ref ref-history-count "\ "ref-max-history ref-min-history ref-set refer refer-clojure reify "\ "release-pending-sends rem remove remove-all-methods remove-method "\ "remove-ns remove-watch repeat repeatedly replace replicate require reset! "\ "reset-meta! reset-vals! resolve rest restart-agent resultset-seq reverse "\ "reversible? rseq rsubseq run! satisfies? second select-keys send send-off "\ "send-via seq seq? seqable? seque sequence sequential? set set! "\ "set-agent-send-executor! set-agent-send-off-executor! set-error-handler! "\ "set-error-mode! set-validator! set? short short-array shorts shuffle "\ "shutdown-agents simple-ident? simple-keyword? simple-symbol? slurp some "\ "some-> some->> some-fn some? sort sort-by sorted-map sorted-map-by "\ "sorted-set sorted-set-by sorted? special-symbol? spit split-at split-with "\ "str string? struct struct-map subs subseq subvec supers swap! swap-vals! "\ "symbol symbol? sync tagged-literal tagged-literal? take take-last take-nth "\ "take-while test the-ns thread-bound? throw time to-array to-array-2d "\ "trampoline transduce transient tree-seq true? try type unchecked-add "\ "unchecked-add-int unchecked-byte unchecked-char unchecked-dec "\ "unchecked-dec-int unchecked-divide-int unchecked-double unchecked-float "\ "unchecked-inc unchecked-inc-int unchecked-int unchecked-long "\ "unchecked-multiply unchecked-multiply-int unchecked-negate "\ "unchecked-negate-int unchecked-remainder-int unchecked-short "\ "unchecked-subtract unchecked-subtract-int underive unreduced "\ "unsigned-bit-shift-right update update-in update-proxy uri? use uuid? val "\ "vals var var-get var-set var? vary-meta vec vector vector-of vector? "\ "volatile! volatile? vreset! vswap! while with-bindings with-bindings* "\ "with-in-str with-local-vars with-meta with-open with-out-str "\ "with-precision with-redefs with-redefs-fn xml-seq zero? zipmap", core_fns); split( \ "*1 *2 *3 *agent* *clojure-version* *command-line-args* *compile-files* "\ "*compile-path* *compiler-options* *data-readers* *default-data-reader-fn* "\ "*e *err* *file* *flush-on-newline* *in* *ns* *out* *print-dup* "\ "*print-length* *print-level* *print-meta* *print-namespace-maps* "\ "*print-readably* *read-eval* *unchecked-math* *warn-on-reflection*", core_vars); } function print_word_highlighter(words, face, first) { printf("add-highlighter shared/clojure/code/ regex (?"wZ' try %{ # If a special form, indent another (indentwidth - 1) spaces execute-keys -draft '"wze[\s()\[\]\{\}]\A' %opt{clojure_special_indent_forms} '\z' execute-keys -draft '"wzes.{' %sh{printf $(( kak_opt_indentwidth - 1 ))} '}\K.*;"i' } catch %{ # If not special and parameter appears on line 1, indent to parameter execute-keys -draft '"wze[\s()\[\]\{\}]s\h\K[^\s].*;"i' } } try %{ execute-keys -draft '[rl"i' } try %{ execute-keys -draft '[Bl"i' } execute-keys -draft ';"ia&' } } } kakoune-2019.07.01/rc/filetype/cmake.kak000066400000000000000000000024071350637360100175540ustar00rootroot00000000000000hook global BufCreate .+\.cmake|.*/CMakeLists.txt %{ set-option buffer filetype cmake } hook global BufCreate .*/CMakeCache.txt %{ set-option buffer filetype ini } hook global WinSetOption filetype=cmake %{ require-module cmake } hook -group cmake-highlight global WinSetOption filetype=cmake %{ add-highlighter window/cmake ref cmake hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/cmake } } provide-module cmake %{ add-highlighter shared/cmake regions add-highlighter shared/cmake/code default-region group add-highlighter shared/cmake/comment region '#' '$' fill comment add-highlighter shared/cmake/argument region -recurse '\(' '\w+\h*\(\K' '(?=\))' regions add-highlighter shared/cmake/code/ regex '\w+\h*(?=\()' 0:meta add-highlighter shared/cmake/argument/args default-region regex '\$\{\w+\}' 0:variable add-highlighter shared/cmake/argument/quoted region '"' '(? # remove trailing white spaces try %{ execute-keys -draft s \h + $ d } } } define-command -hidden coffee-indent-on-new-line %{ evaluate-commands -draft -itersel %{ # copy '#' comment prefix and following white spaces try %{ execute-keys -draft k s '^\h*\K#\h*' y gh j P } # preserve previous line indent try %{ execute-keys -draft \; K } # filter previous line try %{ execute-keys -draft k : coffee-trim-indent } # indent after start structure try %{ execute-keys -draft k ^ \h * (case|catch|class|else|finally|for|function|if|switch|try|while|with) \b | (=|->) $ j } } } ] kakoune-2019.07.01/rc/filetype/crystal.kak000066400000000000000000000245211350637360100201560ustar00rootroot00000000000000# Crystal # https://crystal-lang.org hook global BufCreate '.*\.cr' %{ set-option buffer filetype crystal } hook global WinSetOption filetype=crystal %{ require-module crystal evaluate-commands set-option window static_words %opt(crystal_keywords) %opt(crystal_attributes) %opt(crystal_objects) add-highlighter window/ ref crystal hook -group crystal window InsertChar '\n' crystal-new-line-inserted hook -always -once window WinSetOption filetype=.* %{ remove-highlighter window/crystal remove-hooks window crystal } } provide-module crystal %🐈 declare-option -hidden str-list crystal_keywords 'abstract' 'alias' 'annotation' 'as' 'asm' 'begin' 'break' 'case' 'class' 'def' 'do' 'else' 'elsif' 'end' 'ensure' 'enum' 'extend' 'false' 'for' 'fun' 'if' 'include' 'instance_sizeof' 'is_a?' 'lib' 'macro' 'module' 'next' 'nil' 'nil?' 'of' 'offsetof' 'out' 'pointerof' 'private' 'protected' 'require' 'rescue' 'responds_to?' 'return' 'select' 'self' 'sizeof' 'struct' 'super' 'then' 'true' 'type' 'typeof' 'uninitialized' 'union' 'unless' 'until' 'verbatim' 'when' 'while' 'with' 'yield' # https://crystal-lang.org/reference/syntax_and_semantics/methods_and_instance_variables.html#getters-and-setters declare-option -hidden str-list crystal_attributes 'getter' 'setter' 'property' declare-option -hidden str-list crystal_operators '+' '-' '*' '/' '//' '%' '|' '&' '^' '~' '**' '<<' '<' '<=' '==' '!=' '=~' '!~' '>>' '>' '>=' '<=>' '===' '[]' '[]=' '[]?' '[' '&+' '&-' '&*' '&**' declare-option -hidden str-list crystal_objects 'Adler32' 'ArgumentError' 'Array' 'Atomic' 'Base64' 'Benchmark' 'BigDecimal' 'BigFloat' 'BigInt' 'BigRational' 'BitArray' 'Bool' 'Box' 'Bytes' 'Channel' 'Char' 'Class' 'Colorize' 'Comparable' 'Complex' 'Concurrent' 'ConcurrentExecutionException' 'CRC32' 'Crypto' 'Crystal' 'CSV' 'Debug' 'Deprecated' 'Deque' 'Digest' 'Dir' 'DivisionByZeroError' 'DL' 'ECR' 'Enum' 'Enumerable' 'ENV' 'Errno' 'Exception' 'Fiber' 'File' 'FileUtils' 'Flags' 'Flate' 'Float' 'Float32' 'Float64' 'GC' 'Gzip' 'Hash' 'HTML' 'HTTP' 'Indexable' 'IndexError' 'INI' 'Int' 'Int128' 'Int16' 'Int32' 'Int64' 'Int8' 'InvalidBigDecimalException' 'InvalidByteSequenceError' 'IO' 'IPSocket' 'Iterable' 'Iterator' 'JSON' 'KeyError' 'Levenshtein' 'Link' 'LLVM' 'Logger' 'Markdown' 'Math' 'MIME' 'Mutex' 'NamedTuple' 'Nil' 'NilAssertionError' 'NotImplementedError' 'Number' 'OAuth' 'OAuth2' 'Object' 'OpenSSL' 'OptionParser' 'OverflowError' 'PartialComparable' 'Path' 'Pointer' 'PrettyPrint' 'Proc' 'Process' 'Random' 'Range' 'Readline' 'Reference' 'Reflect' 'Regex' 'SemanticVersion' 'Set' 'Signal' 'Slice' 'Socket' 'Spec' 'StaticArray' 'String' 'StringPool' 'StringScanner' 'Struct' 'Symbol' 'System' 'TCPServer' 'TCPSocket' 'Termios' 'Time' 'Tuple' 'TypeCastError' 'UDPSocket' 'UInt128' 'UInt16' 'UInt32' 'UInt64' 'UInt8' 'Unicode' 'Union' 'UNIXServer' 'UNIXSocket' 'URI' 'UUID' 'VaList' 'Value' 'WeakRef' 'XML' 'YAML' 'Zip' 'Zlib' add-highlighter shared/crystal regions add-highlighter shared/crystal/code default-region group # Comments # https://crystal-lang.org/reference/syntax_and_semantics/comments.html # Avoid string literals with interpolation add-highlighter shared/crystal/comment region '#(?!\{)' '$' fill comment # String # https://crystal-lang.org/reference/syntax_and_semantics/literals/string.html add-highlighter shared/crystal/string region '"' '(?' regions add-highlighter shared/crystal/pipe-string region '%Q?\|' '\|' regions # Raw # https://crystal-lang.org/reference/syntax_and_semantics/literals/string.html#percent-string-literals # https://crystal-lang.org/reference/syntax_and_semantics/literals/string.html#percent-string-array-literal # https://crystal-lang.org/reference/syntax_and_semantics/literals/symbol.html#percent-symbol-array-literal add-highlighter shared/crystal/raw-parenthesis-string region -recurse '\(' '%[qwi]\(' '\)' fill string add-highlighter shared/crystal/raw-bracket-string region -recurse '\[' '%[qwi]\[' '\]' fill string add-highlighter shared/crystal/raw-brace-string region -recurse '\{' '%[qwi]\{' '\}' fill string add-highlighter shared/crystal/raw-angle-string region -recurse '<' '%[qwi]<' '>' fill string add-highlighter shared/crystal/raw-pipe-string region '%[qwi]\|' '\|' fill string # Here document # https://crystal-lang.org/reference/syntax_and_semantics/literals/string.html#heredoc add-highlighter shared/crystal/heredoc region -match-capture '<<-(\w+)' '^\h*(\w+)$' regions # Raw add-highlighter shared/crystal/raw-heredoc region -match-capture "<<-'(\w+)'" '^\h*(\w+)$' regions add-highlighter shared/crystal/raw-heredoc/fill default-region fill string add-highlighter shared/crystal/raw-heredoc/interpolation region -recurse '\{' '#\{' '\}' fill meta # Symbol # https://crystal-lang.org/reference/syntax_and_semantics/literals/symbol.html add-highlighter shared/crystal/quoted-symbol region ':"' '(?[imx]*' regions add-highlighter shared/crystal/pipe-regex region '%r?\|' '\|[imx]*' regions # Command # https://crystal-lang.org/reference/syntax_and_semantics/literals/command.html add-highlighter shared/crystal/command region '`' '(?' regions add-highlighter shared/crystal/pipe-command region '%x?\|' '\|' regions evaluate-commands %sh[ # Keywords eval "set -- $kak_quoted_opt_crystal_keywords" regex="\\b(?:\\Q$1\\E" shift for keyword do regex="$regex|\\Q$keyword\\E" done regex="$regex)\\b" printf 'add-highlighter shared/crystal/code/keywords regex %s 0:keyword\n' "$regex" # Attributes eval "set -- $kak_quoted_opt_crystal_attributes" regex="\\b(?:\\Q$1\\E" shift for attribute do regex="$regex|\\Q$attribute\\E" done regex="$regex)\\b" printf 'add-highlighter shared/crystal/code/attributes regex %s 0:attribute\n' "$regex" # Symbols eval "set -- $kak_quoted_opt_crystal_operators" # Avoid to match modules regex="(?') # Remove empty line indent try %(execute-keys -draft 'ks^\h+$d') } define-command -hidden crystal-fetch-keywords %{ set-register dquote %sh{ curl --location https://github.com/crystal-lang/crystal/raw/master/src/compiler/crystal/syntax/lexer.cr | kak -f '%1scheck_ident_or_keyword\(:(\w+\??), \w+\)y%aa|sort' } } define-command -hidden crystal-fetch-operators %{ set-register dquote %sh{ curl --location https://github.com/crystal-lang/crystal/raw/master/src/compiler/crystal/syntax/parser.cr | kak -f '/AtomicWithMethodCheck =x1s:"([^"]+)"y%i''a''a' } } define-command -hidden crystal-fetch-objects %{ set-register dquote %sh{ curl --location https://crystal-lang.org/api/ | # Remove Top Level Namespace kak -f '%1sdata-id="github.com/crystal-lang/crystal/(\w+)")y%aa' } } 🐈 kakoune-2019.07.01/rc/filetype/css.kak000066400000000000000000000056101350637360100172630ustar00rootroot00000000000000# http://w3.org/Style/CSS # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*[.](css) %{ set-option buffer filetype css } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=css %[ require-module css hook window ModeChange insert:.* -group css-trim-indent css-trim-indent hook window InsertChar \n -group css-indent css-indent-on-new-line hook window InsertChar \} -group css-indent css-indent-on-closing-curly-brace set-option buffer extra_word_chars '_' '-' hook -once -always window WinSetOption filetype=.* %{ remove-hooks window css-.+ } ] hook -group css-highlight global WinSetOption filetype=css %{ add-highlighter window/css ref css hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/css } } provide-module css %[ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/css regions add-highlighter shared/css/selector default-region group add-highlighter shared/css/declaration region [{] [}] regions add-highlighter shared/css/comment region /[*] [*]/ fill comment add-highlighter shared/css/declaration/base default-region group add-highlighter shared/css/declaration/double_string region '"' (? s \h+$ d } } define-command -hidden css-indent-on-new-line %[ evaluate-commands -draft -itersel %[ # preserve previous line indent try %[ execute-keys -draft \; K ] # filter previous line try %[ execute-keys -draft k : css-trim-indent ] # indent after lines ending with with { try %[ execute-keys -draft k \{$ j ] ] ] define-command -hidden css-indent-on-closing-curly-brace %[ evaluate-commands -draft -itersel %[ # align to opening curly brace when alone on a line try %[ execute-keys -draft ^\h+\}$ m s \A|.\z 1 ] ] ] ] kakoune-2019.07.01/rc/filetype/cucumber.kak000066400000000000000000000060451350637360100203030ustar00rootroot00000000000000# http://cukes.info # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*[.](feature|story) %{ set-option buffer filetype cucumber } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=cucumber %{ require-module cucumber hook window ModeChange insert:.* -group cucumber-trim-indent cucumber-trim-indent hook window InsertChar \n -group cucumber-indent cucumber-indent-on-new-line hook -once -always window WinSetOption filetype=.* %{ remove-hooks window cucumber-.+ } } hook -group cucumber-highlight global WinSetOption filetype=cucumber %{ add-highlighter window/cucumber ref cucumber hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/cucumber } } provide-module cucumber %{ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/cucumber regions add-highlighter shared/cucumber/code default-region group add-highlighter shared/cucumber/language region ^\h*#\h*language: $ group add-highlighter shared/cucumber/comment region ^\h*# $ fill comment add-highlighter shared/cucumber/language/ fill meta add-highlighter shared/cucumber/language/ regex \S+$ 0:value # Spoken languages # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # https://github.com/cucumber/cucumber/wiki/Spoken-languages # # curl --location https://github.com/cucumber/gherkin/raw/master/lib/gherkin/i18n.json # # { # "en": { # "name": "English", # "native": "English", # "feature": "Feature|Business Need|Ability", # "background": "Background", # "scenario": "Scenario", # "scenario_outline": "Scenario Outline|Scenario Template", # "examples": "Examples|Scenarios", # "given": "*|Given", # "when": "*|When", # "then": "*|Then", # "and": "*|And", # "but": "*|But" # }, # … # } # # jq 'with_entries({ key: .key, value: .value | del(.name) | del(.native) | join("|") })' # # { # "en": "Feature|Business Need|Ability|Background|Scenario|Scenario Outline|Scenario Template|Examples|Scenarios|*|Given|*|When|*|Then|*|And|*|But", # … # } add-highlighter shared/cucumber/code/ regex \b(Feature|Business\h+Need|Ability|Background|Scenario|Scenario\h+Outline|Scenario\h+Template|Examples|Scenarios|Given|When|Then|And|But)\b 0:keyword # Commands # ‾‾‾‾‾‾‾‾ define-command -hidden cucumber-trim-indent %{ # remove trailing white spaces try %{ execute-keys -draft -itersel s \h+$ d } } define-command -hidden cucumber-indent-on-new-line %{ evaluate-commands -draft -itersel %{ # copy '#' comment prefix and following white spaces try %{ execute-keys -draft k s ^\h*\K#\h* y gh j P } # preserve previous line indent try %{ execute-keys -draft \; K } # filter previous line try %{ execute-keys -draft k : cucumber-trim-indent } # indent after lines containing : try %{ execute-keys -draft k x : j } } } } kakoune-2019.07.01/rc/filetype/d.kak000066400000000000000000000152331350637360100167200ustar00rootroot00000000000000# http://dlang.org/ # # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*\.di? %{ set-option buffer filetype d } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=d %{ require-module d set-option window static_words %opt{d_static_words} # cleanup trailing whitespaces when exiting insert mode hook window ModeChange insert:.* -group d-trim-indent %{ try %{ execute-keys -draft s^\h+$d } } hook window InsertChar \n -group d-indent d-indent-on-new-line hook window InsertChar \{ -group d-indent d-indent-on-opening-curly-brace hook window InsertChar \} -group d-indent d-indent-on-closing-curly-brace hook -once -always window WinSetOption filetype=.* %{ remove-hooks window d-.+ } } hook -group d-highlight global WinSetOption filetype=d %{ add-highlighter window/d ref d hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/d } } provide-module d %§ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/d regions add-highlighter shared/d/code default-region group add-highlighter shared/d/string region %{(? } # indent after lines ending with { or ( try %[ execute-keys -draft k [{(]\h*$ j ] # cleanup trailing white spaces on the previous line try %{ execute-keys -draft k s \h+$ d } # align to opening paren of previous line try %{ execute-keys -draft [( \A\([^\n]+\n[^\n]*\n?\z s \A\(\h*.|.\z '' & } # copy // comments prefix try %{ execute-keys -draft \;k s ^\h*\K/{2,} yP } # indent after a switch's case/default statements try %[ execute-keys -draft k ^\h*(case|default).*:$ j ] # indent after if|else|while|for try %[ execute-keys -draft \;)MB \A(if|else|while|for)\h*\(.*\)\h*\n\h*\n?\z s \A|.\z 11 ] = ~ define-command -hidden d-indent-on-opening-curly-brace %[ # align indent with opening paren when { is entered on a new line after the closing paren try %[ execute-keys -draft -itersel h)M \A\(.*\)\h*\n\h*\{\z s \A|.\z 1 ] ] define-command -hidden d-indent-on-closing-curly-brace %[ # align to opening curly brace when alone on a line try %[ execute-keys -itersel -draft ^\h+\}$hms\A|.\z1 ] ] § kakoune-2019.07.01/rc/filetype/dart.kak000066400000000000000000000112651350637360100174300ustar00rootroot00000000000000# https://dartlang.org/ # # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*\.dart %{ set-option buffer filetype dart } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=dart %{ require-module dart set-option window static_words %opt{dart_static_words} # cleanup trailing whitespaces when exiting insert mode hook window ModeChange insert:.* -group dart-trim-indent %{ try %{ execute-keys -draft s^\h+$d } } hook window InsertChar \n -group dart-indent dart-indent-on-new-line hook window InsertChar \{ -group dart-indent dart-indent-on-opening-curly-brace hook window InsertChar \} -group dart-indent dart-indent-on-closing-curly-brace hook -once -always window WinSetOption filetype=.* %{ remove-hooks window dart-.+ } } hook -group dart-highlight global WinSetOption filetype=dart %{ add-highlighter window/dart ref dart hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/dart } } provide-module dart %§ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/dart regions add-highlighter shared/dart/code default-region group add-highlighter shared/dart/back_string region '`' '`' fill string add-highlighter shared/dart/double_string region '"' (?)" classes="_?[A-Z][a-zA-Z0-9]*" # Add the language's grammar to the static completion list printf %s\\n "declare-option str-list dart_static_words ${keywords} ${attributes} ${types} ${values}" | tr '|' ' ' # Highlight keywords printf %s " add-highlighter shared/dart/code/ regex \b(${keywords})\b 0:keyword add-highlighter shared/dart/code/ regex \b(${generator_keywords}) 0:keyword add-highlighter shared/dart/code/ regex \b(${attributes})\b 0:attribute add-highlighter shared/dart/code/ regex \b(${types})\b 0:type add-highlighter shared/dart/code/ regex \b(${values})\b 0:value add-highlighter shared/dart/code/ regex \b(${functions}) 2:function add-highlighter shared/dart/code/ regex (${annotations})\b 0:meta add-highlighter shared/dart/code/ regex \b(${classes})\b 0:module " } # Commands # ‾‾‾‾‾‾‾‾ define-command -hidden dart-indent-on-new-line %~ evaluate-commands -draft -itersel %= # preserve previous line indent try %{ execute-keys -draft \;K } # indent after lines ending with { or ( try %[ execute-keys -draft k [{(]\h*$ j ] # cleanup trailing white spaces on the previous line try %{ execute-keys -draft k s \h+$ d } # align to opening paren of previous line try %{ execute-keys -draft [( \A\([^\n]+\n[^\n]*\n?\z s \A\(\h*.|.\z '' & } # copy // comments prefix try %{ execute-keys -draft \;k s ^\h*\K/{2,} yP } # indent after a switch's case/default statements try %[ execute-keys -draft k ^\h*(case|default).*:$ j ] # indent after if|else|while|for try %[ execute-keys -draft \;)MB \A(if|else|while|for)\h*\(.*\)\h*\n\h*\n?\z s \A|.\z 11 ] = ~ define-command -hidden dart-indent-on-opening-curly-brace %[ # align indent with opening paren when { is entered on a new line after the closing paren try %[ execute-keys -draft -itersel h)M \A\(.*\)\h*\n\h*\{\z s \A|.\z 1 ] ] define-command -hidden dart-indent-on-closing-curly-brace %[ # align to opening curly brace when alone on a line try %[ execute-keys -itersel -draft ^\h+\}$hms\A|.\z1 ] ] § kakoune-2019.07.01/rc/filetype/diff.kak000066400000000000000000000007711350637360100174060ustar00rootroot00000000000000hook global BufCreate .*\.(diff|patch) %{ set-option buffer filetype diff } add-highlighter shared/diff group add-highlighter shared/diff/ regex "^\+[^\n]*\n" 0:green,default add-highlighter shared/diff/ regex "^-[^\n]*\n" 0:red,default add-highlighter shared/diff/ regex "^@@[^\n]*@@" 0:cyan,default hook -group diff-highlight global WinSetOption filetype=diff %{ add-highlighter window/diff ref diff hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/diff } } kakoune-2019.07.01/rc/filetype/dockerfile.kak000066400000000000000000000035061350637360100206040ustar00rootroot00000000000000# http://docker.com # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # See https://docs.docker.com/reference/builder # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*/?Dockerfile(\.\w+)?$ %{ set-option buffer filetype dockerfile } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=dockerfile %{ require-module dockerfile set-option window static_words %opt{dockerfile_static_words} } hook -group dockerfile-highlight global WinSetOption filetype=dockerfile %{ add-highlighter window/dockerfile ref dockerfile hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/dockerfile } } provide-module dockerfile %{ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/dockerfile regions add-highlighter shared/dockerfile/code default-region group add-highlighter shared/dockerfile/double_string region '"' '(?|<-|<<|>>|=>) 0:builtin add-highlighter shared/elixir/code/ regex \b(require|alias|use|import)\b 0:keyword add-highlighter shared/elixir/code/ regex \b(__MODULE__|__DIR__|__ENV__|__CALLER__)\b 0:value add-highlighter shared/elixir/code/ regex \b(def|defp|defmacro|defmacrop|defstruct|defmodule|defimpl|defprotocol|defoverridable)\b 0:keyword add-highlighter shared/elixir/code/ regex \b(fn|do|end|when|case|if|else|unless|var!|for|cond|quote|unquote|receive|with|raise|reraise|try|catch)\b 0:keyword add-highlighter shared/elixir/code/ regex '@[\w_]+\b' 0:attribute add-highlighter shared/elixir/code/ regex '\b\d+[\d_]*\b' 0:value # Commands # ‾‾‾‾‾‾‾‾ define-command -hidden elixir-trim-indent %{ # remove trailing white spaces try %{ execute-keys -draft -itersel s \h+$ d } } define-command -hidden elixir-indent-on-new-line %{ evaluate-commands -draft -itersel %{ # copy -- comments prefix and following white spaces try %{ execute-keys -draft k s ^\h*\K--\h* y gh j P } # preserve previous line indent try %{ execute-keys -draft \; K } # indent after line ending with: # try %{ execute-keys -draft k x (do|else|->)$ & } # filter previous line try %{ execute-keys -draft k : elixir-trim-indent } # indent after lines ending with do or -> try %{ execute-keys -draft \\; k x ^.+(do|->)$ j } } } ] kakoune-2019.07.01/rc/filetype/elm.kak000066400000000000000000000051071350637360100172510ustar00rootroot00000000000000# http://elm-lang.org # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*[.](elm) %{ set-option buffer filetype elm } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=elm %{ require-module elm hook window ModeChange insert:.* -group elm-trim-indent elm-trim-indent hook window InsertChar \n -group elm-indent elm-indent-on-new-line hook -once -always window WinSetOption filetype=.* %{ remove-hooks window elm-.+ } } hook -group elm-highlight global WinSetOption filetype=elm %{ add-highlighter window/elm ref elm hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/elm } } provide-module elm %[ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/elm regions add-highlighter shared/elm/code default-region group add-highlighter shared/elm/string region '"' (? s \h+$ d } } define-command -hidden elm-indent-after " execute-keys -draft \\; k x ^\\h*(if)|(case\\h+[\\w']+\\h+of|let|in|\\{\\h+\\w+|\\w+\\h+->|[=(])$ j " define-command -hidden elm-indent-on-new-line %{ evaluate-commands -draft -itersel %{ # copy -- comments prefix and following white spaces try %{ execute-keys -draft k s ^\h*\K--\h* y gh j P } # preserve previous line indent try %{ execute-keys -draft \; K } # align to first clause try %{ execute-keys -draft \; k x X s ^\h*(if|then|else)?\h*(([\w']+\h+)+=)?\h*(case\h+[\w']+\h+of|let)\h+\K.* s \A|.\z & } # filter previous line try %{ execute-keys -draft k : elm-trim-indent } # indent after lines beginning with condition or ending with expression or =( try %{ elm-indent-after } } } ] kakoune-2019.07.01/rc/filetype/etc.kak000066400000000000000000000110261350637360100172440ustar00rootroot00000000000000# Highlighting for common files in /etc hook global BufCreate .*/etc/(hosts|networks|services) %{ set-option buffer filetype etc-hosts } hook global BufCreate .*/etc/resolv.conf %{ set-option buffer filetype etc-resolv-conf } hook global BufCreate .*/etc/shadow %{ set-option buffer filetype etc-shadow } hook global BufCreate .*/etc/passwd %{ set-option buffer filetype etc-passwd } hook global BufCreate .*/etc/gshadow %{ set-option buffer filetype etc-gshadow } hook global BufCreate .*/etc/group %{ set-option buffer filetype etc-group } hook global BufCreate .*/etc/(fs|m)tab %{ set-option buffer filetype etc-fstab } hook global BufCreate .*/etc/environment %{ set-option buffer filetype sh } hook global BufCreate .*/etc/env.d/.* %{ set-option buffer filetype sh } hook global BufCreate .*/etc/profile(\.(csh|env))? %{ set-option buffer filetype sh } hook global BufCreate .*/etc/profile\.d/.* %{ set-option buffer filetype sh } hook global WinSetOption filetype=etc-(hosts|resolv-conf|shadow|passwd|gshadow|group|fstab) %{ require-module "etc-%val{hook_param_capture_1}" } hook -group etc-resolv-conf-highlight global WinSetOption filetype=etc-resolv-conf %{ add-highlighter window/etc-resolv-conf ref etc-resolv-conf hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/etc-resolv-conf } } hook -group etc-hosts-highlight global WinSetOption filetype=etc-hosts %{ add-highlighter window/etc-hosts ref etc-hosts hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/etc-hosts } } hook -group etc-fstab-highlight global WinSetOption filetype=etc-fstab %{ add-highlighter window/etc-fstab ref etc-fstab hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/etc-fstab } } hook -group etc-group-highlight global WinSetOption filetype=etc-group %{ add-highlighter window/etc-group ref etc-group hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/etc-group } } hook -group etc-gshadow-highlight global WinSetOption filetype=etc-gshadow %{ add-highlighter window/etc-gshadow ref etc-gshadow hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/etc-gshadow } } hook -group etc-shadow-highlight global WinSetOption filetype=etc-shadow %{ add-highlighter window/etc-shadow ref etc-shadow hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/etc-shadow } } hook -group etc-passwd-highlight global WinSetOption filetype=etc-passwd %{ add-highlighter window/etc-passwd ref etc-passwd hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/etc-passwd } } # Highlighters provide-module etc-resolv-conf %{ ## /etc/resolv.conf add-highlighter shared/etc-resolv-conf group add-highlighter shared/etc-resolv-conf/ regex ^#.*?$ 0:comment add-highlighter shared/etc-resolv-conf/ regex ^(nameserver|server|domain|sortlist|options)[\s\t]+(.*?)$ 1:type 2:attribute } provide-module etc-hosts %{ ## /etc/hosts add-highlighter shared/etc-hosts group add-highlighter shared/etc-hosts/ regex ^(.+?)[\s\t]+?(.*?)$ 1:type 2:attribute add-highlighter shared/etc-hosts/ regex '#.*?$' 0:comment } provide-module etc-fstab %{ ## /etc/fstab add-highlighter shared/etc-fstab group add-highlighter shared/etc-fstab/ regex ^(\S{1,})\s+?(\S{1,})\s+?(\S{1,})\s+?(\S{1,})\s+?(\S{1,})\s+?(\S{1,})(?:\s+)?$ 1:keyword 2:value 3:type 4:string 5:attribute 6:attribute add-highlighter shared/etc-fstab/ regex '#.*?$' 0:comment } provide-module etc-group %{ ## /etc/group add-highlighter shared/etc-group group add-highlighter shared/etc-group/ regex ^(\S+?):(\S+?)?:(\S+?)?:(\S+?)?$ 1:keyword 2:type 3:value 4:string } provide-module etc-gshadow %{ ## /etc/gshadow add-highlighter shared/etc-gshadow group add-highlighter shared/etc-gshadow/ regex ^(\S+?):(\S+?)?:(\S+?)?:(\S+?)?$ 1:keyword 2:type 3:value 4:string } provide-module etc-shadow %{ ## /etc/shadow add-highlighter shared/etc-shadow group add-highlighter shared/etc-shadow/ regex ^(\S+?):(\S+?):([0-9]+?):([0-9]+?)?:([0-9]+?)?:([0-9]+?)?:([0-9]+?)?:([0-9]+?)?:(.*?)?$ 1:keyword 2:type 3:value 4:value 5:value 6:value 7:value 8:value } provide-module etc-passwd %{ ## /etc/passwd add-highlighter shared/etc-passwd group add-highlighter shared/etc-passwd/ regex ^(\S+?):(\S+?):([0-9]+?):([0-9]+?):(.*?)?:(.+?):(.+?)$ 1:keyword 2:type 3:value 4:value 5:string 6:attribute 7:attribute } kakoune-2019.07.01/rc/filetype/exherbo.kak000066400000000000000000000201061350637360100201240ustar00rootroot00000000000000## Repository metadata files hook global BufCreate .*/metadata/mirrors\.conf %{ set-option buffer filetype paludis-mirrors-conf } hook global BufCreate .*/metadata/licence_groups.conf %{ set-option buffer filetype exheres-0-licence-groups } hook global BufCreate .*/metadata/options/descriptions/.*\.conf %{ set-option buffer filetype exheres-0-licence-groups } hook global BufCreate .*/metadata/.*\.conf %{ set-option buffer filetype exheres-0-metadata } ## News items hook global BufCreate .*/metadata/news/.*/.*\.txt %{ set-option buffer filetype glep42 } ## exheres-0, exlib hook global BufCreate .*\.(exheres-0|exlib) %{ set-option buffer filetype sh } # Paludis configurations hook global BufCreate .*/etc/paludis(-.*)?/bashrc %{ set-option buffer filetype sh } hook global BufCreate .*/etc/paludis(-.*)?/general(\.conf.d/.*.conf|\.conf) %{ set-option buffer filetype paludis-key-value-conf } hook global BufCreate .*/etc/paludis(-.*)?/licences(\.conf.d/.*.conf|\.conf) %{ set-option buffer filetype paludis-options-conf } hook global BufCreate .*/etc/paludis(-.*)?/mirrors(\.conf.d/.*.conf|\.conf) %{ set-option buffer filetype paludis-mirrors-conf } hook global BufCreate .*/etc/paludis(-.*)?/options(\.conf.d/.*.conf|\.conf) %{ set-option buffer filetype paludis-options-conf } hook global BufCreate .*/etc/paludis(-.*)?/output(\.conf.d/.*.conf|\.conf) %{ set-option buffer filetype paludis-key-value-conf } hook global BufCreate .*/etc/paludis(-.*)?/package_(unmask|mask)(\.conf.d/.*.conf|\.conf) %{ set-option buffer filetype paludis-specs-conf } hook global BufCreate .*/etc/paludis(-.*)?/platforms(\.conf.d/.*.conf|\.conf) %{ set-option buffer filetype paludis-specs-conf } hook global BufCreate .*/etc/paludis(-.*)?/repositories/.*\.conf %{ set-option buffer filetype paludis-key-value-conf } hook global BufCreate .*/etc/paludis(-.*)?/repository\.template %{ set-option buffer filetype paludis-key-value-conf } hook global BufCreate .*/etc/paludis(-.*)?/repository_defaults\.conf %{ set-option buffer filetype paludis-key-value-conf } hook global BufCreate .*/etc/paludis(-.*)?/specpath\.conf %{ set-option buffer filetype paludis-key-value-conf } hook global BufCreate .*/etc/paludis(-.*)?/suggestions(\.conf.d/.*.conf|\.conf) %{ set-option buffer filetype paludis-specs-conf } hook global WinSetOption filetype=exheres-0-(metadata|options-descriptions|licence-groups) %{ require-module exheres } hook -group exheres-0-metadata-highlight global WinSetOption filetype=exheres-0-metadata %{ add-highlighter window/exheres-0-metadata ref exheres-0-metadata hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/exheres-0-metadata } } hook -group exheres-0-options-descriptions-highlight global WinSetOption filetype=exheres-0-options-descriptions %{ add-highlighter window/exheres-0-options-descriptions ref exheres-0-options-descriptions hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/exheres-0-options-descriptions } } hook -group exheres-0-licence-groups-highlight global WinSetOption filetype=exheres-0-licence-groups %{ add-highlighter window/exheres-0-licence-groups ref exheres-0-licence-groups hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/exheres-0-licence-groups } } provide-module exheres %{ # Highlighters ## exheres-0 Repository metadata files add-highlighter shared/exheres-0-metadata group add-highlighter shared/exheres-0-metadata/ regex ^#.*?$ 0:comment add-highlighter shared/exheres-0-metadata/ regex ^(?:[\s\t]+)?(\*)?(\S+)(?:[\s\t]+)?=(?:[\s\t]+)?(.+?)?$ 1:type 2:attribute 3:string add-highlighter shared/exheres-0-metadata/ regex ^(?:[\s\t]+)?[\S]+[\s\t]+=[\s\t]+\[.+?[\s\t]+\] 0:string add-highlighter shared/exheres-0-metadata/ regex ^(?:[\s\t]+)?(\S+)\s\[\[$ 0:type add-highlighter shared/exheres-0-metadata/ regex ^(?:[\s\t]+)?\]\]$ 0:type ## exheres-0 options descriptions add-highlighter shared/exheres-0-options-descriptions group add-highlighter shared/exheres-0-options-descriptions/ regex ^#.*?$ 0:comment add-highlighter shared/exheres-0-options-descriptions/ regex ^(?:[\s\t]+)?[\S]+[\s\t]+-[\s\t]+\[.+?[\s\t]+\] 0:string add-highlighter shared/exheres-0-options-descriptions/ regex ^(?:[\s\t]+)?(\S+)\s\[\[$ 0:type add-highlighter shared/exheres-0-options-descriptions/ regex ^(?:[\s\t]+)?\]\]$ 0:type ## metadata/licence_groups.conf add-highlighter shared/exheres-0-licence-groups group add-highlighter shared/exheres-0-licence-groups/ regex [\s\t]+(\S+(?:[\s\t]+))*$ 0:attribute add-highlighter shared/exheres-0-licence-groups/ regex ^(\S+) 0:type add-highlighter shared/exheres-0-licence-groups/ regex ^#.*?$ 0:comment } hook global WinSetOption filetype=paludis-(key-value|options|mirrors|specs)-conf %{ require-module paludis } hook -group paludis-options-conf-highlight global WinSetOption filetype=paludis-options-conf %{ add-highlighter window/paludis-options-conf ref paludis-options-conf hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/paludis-options-conf } } hook -group paludis-key-value-conf-highlight global WinSetOption filetype=paludis-key-value-conf %{ add-highlighter window/paludis-key-value-conf ref paludis-key-value-conf hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/paludis-key-value-conf } } hook -group paludis-mirrors-conf-highlight global WinSetOption filetype=paludis-mirrors-conf %{ add-highlighter window/paludis-mirrors-conf ref paludis-mirrors-conf hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/paludis-mirrors-conf } } hook -group paludis-specs-conf-highlight global WinSetOption filetype=paludis-specs-conf %{ add-highlighter window/paludis-specs-conf ref paludis-specs-conf hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/paludis-specs-conf } } provide-module paludis %{ ## Paludis configurations ### options.conf add-highlighter shared/paludis-options-conf group add-highlighter shared/paludis-options-conf/ regex [\s\t]+(\S+(?:[\s\t]+))*$ 0:attribute add-highlighter shared/paludis-options-conf/ regex (?::)(?:[\s\t]+)(.*?$) 1:attribute add-highlighter shared/paludis-options-conf/ regex [\s\t]+(\S+=)(\S+) 1:attribute 2:value add-highlighter shared/paludis-options-conf/ regex [\s\t](\S+:) 0:keyword add-highlighter shared/paludis-options-conf/ regex [\s\t](-\S+)(.*?) 1:red add-highlighter shared/paludis-options-conf/ regex ^(\S+/\S+) 0:type add-highlighter shared/paludis-options-conf/ regex ^#.*?$ 0:comment ## general.conf, repository.template add-highlighter shared/paludis-key-value-conf group add-highlighter shared/paludis-key-value-conf/ regex ^[\s\t]?(\S+)[\s\t+]=[\s\t+](.*?)$ 1:attribute 2:value add-highlighter shared/paludis-key-value-conf/ regex ^#.*?$ 0:comment ## mirrors.conf add-highlighter shared/paludis-mirrors-conf group add-highlighter shared/paludis-mirrors-conf/ regex ^[\s\t+]?(\S+)[\s\t+](.*?)$ 1:type 2:value add-highlighter shared/paludis-mirrors-conf/ regex ^#.*?$ 0:comment ## package_(unmask|mask).conf, platforms.conf add-highlighter shared/paludis-specs-conf group add-highlighter shared/paludis-specs-conf/ regex [\s\t]+(\S+(?:[\s\t]+))*$ 0:attribute add-highlighter shared/paludis-specs-conf/ regex ^(\S+/\S+) 0:type add-highlighter shared/paludis-specs-conf/ regex ^#.*?$ 0:comment } hook global WinSetOption filetype=glep42 %{ require-module glep42 } hook -group glep42-highlight global WinSetOption filetype=glep42 %{ add-highlighter window/glep42 ref glep42 hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/glep42 } } provide-module glep42 %{ ## News items (GLEP42) add-highlighter shared/glep42 group add-highlighter shared/glep42/ regex ^(Title|Author|Translator|Content-Type|Posted|Revision|News-Item-Format|Display-If-Installed|Display-If-Keyword|Display-If-Profile):([^\n]*(?:\n\h+[^\n]+)*)$ 1:keyword 2:attribute add-highlighter shared/glep42/ regex <[^@>]+@.*?> 0:string add-highlighter shared/glep42/ regex ^>.*?$ 0:comment } kakoune-2019.07.01/rc/filetype/fish.kak000066400000000000000000000061571350637360100174330ustar00rootroot00000000000000# http://fishshell.com # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*[.](fish) %{ set-option buffer filetype fish } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=fish %{ require-module fish hook window InsertChar .* -group fish-indent fish-indent-on-char hook window InsertChar \n -group fish-indent fish-indent-on-new-line hook -once -always window WinSetOption filetype=.* %{ remove-hooks window fish-.+ } } hook -group fish-highlight global WinSetOption filetype=fish %{ add-highlighter window/fish ref fish hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/fish } } provide-module fish %{ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/fish regions add-highlighter shared/fish/code default-region group add-highlighter shared/fish/double_string region '"' (? 1s^(\h+)$ d } } } define-command -hidden fish-indent-on-char %{ evaluate-commands -no-hooks -draft -itersel %{ # align middle and end structures to start and indent when necessary try %{ execute-keys -draft ^\h*(else)$^\h*(if)s\A|.\z1 } try %{ execute-keys -draft ^\h*(end)$^\h*(begin|for|function|if|switch|while)s\A|.\z1 } try %{ execute-keys -draft ^\h*(case)$^\h*(switch)s\A|.\z1 } } } define-command -hidden fish-indent-on-new-line %{ evaluate-commands -no-hooks -draft -itersel %{ # copy '#' comment prefix and following white spaces try %{ execute-keys -draft k s ^\h*#\h* y jgh P } # preserve previous line indent try %{ execute-keys -draft \; K } # cleanup trailing whitespaces from previous line try %{ execute-keys -draft k s \h+$ d } # indent after start structure try %{ execute-keys -draft k^\h*(begin|case|else|for|function|if|while)\bj } } } } kakoune-2019.07.01/rc/filetype/gas.kak000066400000000000000000000113521350637360100172450ustar00rootroot00000000000000# Detection # --------- hook global BufCreate .*\.(s|S|asm)$ %{ set-option buffer filetype gas } hook global WinSetOption filetype=gas %{ require-module gas hook window InsertChar \n -group gas-indent gas-indent-on-new-line hook -once -always window WinSetOption filetype=.* %{ remove-hooks window gas-.+ } } hook -group gas-highlight global WinSetOption filetype=gas %{ add-highlighter window/gas ref gas hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/gas } } provide-module gas %{ add-highlighter shared/gas regions add-highlighter shared/gas/code default-region group add-highlighter shared/gas/string region '"' (? # remove trailing white spaces try %{ execute-keys -draft s \h+$ d } } } define-command -hidden gas-indent-on-new-line %~ evaluate-commands -draft -itersel %< # preserve previous line indent try %{ execute-keys -draft \; K } # filter previous line try %{ execute-keys -draft k : gas-trim-indent } # indent after label try %[ execute-keys -draft k :$ j ] > ~ } kakoune-2019.07.01/rc/filetype/git.kak000066400000000000000000000037561350637360100172670ustar00rootroot00000000000000hook global BufCreate .*(COMMIT_EDITMSG|MERGE_MSG) %{ set-option buffer filetype git-commit } hook global BufCreate .*/NOTES_EDITMSG %{ set-option buffer filetype git-notes } hook global BufCreate .*(\.gitconfig|git/config) %{ set-option buffer filetype ini } hook global BufCreate .*git-rebase-todo %{ set-option buffer filetype git-rebase } hook global WinSetOption filetype=git-(commit|notes|rebase) %{ require-module "git-%val{hook_param_capture_1}" } hook -group git-commit-highlight global WinSetOption filetype=git-commit %{ add-highlighter window/git-commit ref git-commit hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/git-commit } } hook -group git-notes-highlight global WinSetOption filetype=git-notes %{ add-highlighter window/git-notes ref git-notes hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/git-notes } } hook -group git-rebase-highlight global WinSetOption filetype=git-rebase %{ add-highlighter window/git-rebase ref git-rebase hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/git-rebase } } provide-module git-commit %{ add-highlighter shared/git-commit regions add-highlighter shared/git-commit/diff region '^diff --git' '^(?=diff --git)' ref diff # highlight potential diffs from the -v option add-highlighter shared/git-commit/comments region '^\h*#' '$' group add-highlighter shared/git-commit/comments/ fill comment add-highlighter shared/git-commit/comments/ regex "\b(?:(modified)|(deleted)|(new file)|(renamed|copied)):([^\n]*)$" 1:yellow 2:red 3:green 4:blue 5:magenta } provide-module git-notes %{ add-highlighter shared/git-notes regex '^\h*#[^\n]*$' 0:comment } provide-module git-rebase %{ add-highlighter shared/git-rebase group add-highlighter shared/git-rebase/ regex "#[^\n]*\n" 0:comment add-highlighter shared/git-rebase/ regex "^(pick|edit|reword|squash|fixup|exec|break|drop|label|reset|merge|[persfxbdltm]) (\w+)" 1:keyword 2:meta } kakoune-2019.07.01/rc/filetype/go.kak000066400000000000000000000105671350637360100171070ustar00rootroot00000000000000# https://golang.org/ # # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*\.go %{ set-option buffer filetype go } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=go %{ require-module go set-option window static_words %opt{go_static_words} # cleanup trailing whitespaces when exiting insert mode hook window ModeChange insert:.* -group go-trim-indent %{ try %{ execute-keys -draft s^\h+$d } } hook window InsertChar \n -group go-indent go-indent-on-new-line hook window InsertChar \{ -group go-indent go-indent-on-opening-curly-brace hook window InsertChar \} -group go-indent go-indent-on-closing-curly-brace hook -once -always window WinSetOption filetype=.* %{ remove-hooks window go-.+ } } hook -group go-highlight global WinSetOption filetype=go %{ add-highlighter window/go ref go hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/go } } provide-module go %§ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/go regions add-highlighter shared/go/code default-region group add-highlighter shared/go/back_string region '`' '`' fill string add-highlighter shared/go/double_string region '"' (? } # indent after lines ending with { or ( try %[ execute-keys -draft k [{(]\h*$ j ] # cleanup trailing white spaces on the previous line try %{ execute-keys -draft k s \h+$ d } # align to opening paren of previous line try %{ execute-keys -draft [( \A\([^\n]+\n[^\n]*\n?\z s \A\(\h*.|.\z '' & } # copy // comments prefix try %{ execute-keys -draft \;k s ^\h*\K/{2,} yP } # indent after a switch's case/default statements try %[ execute-keys -draft k ^\h*(case|default).*:$ j ] # indent after if|else|while|for try %[ execute-keys -draft \;)MB \A(if|else|while|for)\h*\(.*\)\h*\n\h*\n?\z s \A|.\z 11 ] = ~ define-command -hidden go-indent-on-opening-curly-brace %[ # align indent with opening paren when { is entered on a new line after the closing paren try %[ execute-keys -draft -itersel h)M \A\(.*\)\h*\n\h*\{\z s \A|.\z 1 ] ] define-command -hidden go-indent-on-closing-curly-brace %[ # align to opening curly brace when alone on a line try %[ execute-keys -itersel -draft ^\h+\}$hms\A|.\z1 ] ] § kakoune-2019.07.01/rc/filetype/haml.kak000066400000000000000000000046351350637360100174220ustar00rootroot00000000000000# http://haml.info # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*[.](haml) %{ set-option buffer filetype haml } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=haml %{ require-module haml hook window ModeChange insert:.* -group haml-trim-indent haml-trim-indent hook window InsertChar \n -group haml-indent haml-indent-on-new-line hook -once -always window WinSetOption filetype=.* %{ remove-hooks window haml-.+ } } hook -group haml-highlight global WinSetOption filetype=haml %{ add-highlighter window/haml ref haml hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/haml } } provide-module haml %[ require-module ruby require-module coffee require-module sass # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/haml regions add-highlighter shared/haml/code default-region group add-highlighter shared/haml/comment region ^\h*/ $ fill comment # Filters # http://haml.info/docs/yardoc/file.REFERENCE.html#filters add-highlighter shared/haml/eval1 region -recurse \{ ^\h*%([A-Za-z][A-Za-z0-9_-]*)([#.][A-Za-z][A-Za-z0-9_-]*)?\{\K|#\{\K (?=\}) ref ruby add-highlighter shared/haml/eval2 region ^\h*[=-]\K (? s \h+$ d } } define-command -hidden haml-indent-on-new-line %{ evaluate-commands -draft -itersel %{ # copy '/' comment prefix and following white spaces try %{ execute-keys -draft k s ^\h*\K/\h* y gh j P } # preserve previous line indent try %{ execute-keys -draft \; K } # filter previous line try %{ execute-keys -draft k : haml-trim-indent } # indent after lines beginning with : or - try %{ execute-keys -draft k ^\h*[:-] j } } } ] kakoune-2019.07.01/rc/filetype/haskell.kak000066400000000000000000000120771350637360100201230ustar00rootroot00000000000000# http://haskell.org # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*[.](hs) %{ set-option buffer filetype haskell } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=haskell %{ require-module haskell set-option window extra_word_chars '_' "'" hook window ModeChange insert:.* -group haskell-trim-indent haskell-trim-indent hook window InsertChar \n -group haskell-indent haskell-indent-on-new-line hook -once -always window WinSetOption filetype=.* %{ remove-hooks window haskell-.+ } } hook -group haskell-highlight global WinSetOption filetype=haskell %{ add-highlighter window/haskell ref haskell hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/haskell } } provide-module haskell %[ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/haskell regions add-highlighter shared/haskell/code default-region group add-highlighter shared/haskell/string region (??@\\\^|~=]|$) $ fill comment add-highlighter shared/haskell/code/ regex (?" # Quantifier separator in "forall a . [a] -> [a]" # Enum comprehensions like "[1..]" and "[a..b]" (making ".." and "Module..." illegal) # matches uppercase identifiers: Monad Control.Monad # not non-space separated dot: Just.const add-highlighter shared/haskell/code/ regex \b([A-Z]['\w]*\.)*[A-Z]['\w]*(?!['\w])(?![.a-z]) 0:variable # matches infix identifier: `mod` `Apa._T'M` add-highlighter shared/haskell/code/ regex `\b([A-Z]['\w]*\.)*[\w]['\w]*` 0:operator # matches imported operators: M.! M.. Control.Monad.>> # not operator keywords: M... M.-> add-highlighter shared/haskell/code/ regex \b[A-Z]['\w]*\.[~<=>|:!?/.@$*&#%+\^\-\\]+ 0:operator # matches dot: . # not possibly incomplete import: a. # not other operators: !. .! add-highlighter shared/haskell/code/ regex (?|:!?/.@$*&#%+\^\-\\])\.(?![~<=>|:!?/.@$*&#%+\^\-\\]) 0:operator # matches other operators: ... > < <= ^ <*> <$> etc # not dot: . # not operator keywords: @ .. -> :: ~ add-highlighter shared/haskell/code/ regex (?|:!?/.@$*&#%+\^\-\\])[~<=>|:!?/.@$*&#%+\^\-\\]+ 0:operator # matches operator keywords: @ -> add-highlighter shared/haskell/code/ regex (?|:!?/.@$*&#%+\^\-\\])(@|~|<-|->|=>|::|=|:|[|])(?![~<=>|:!?/.@$*&#%+\^\-\\]) 1:keyword # matches: forall [..variables..] . # not the variables add-highlighter shared/haskell/code/ regex \b(forall)\b[^.\n]*?(\.) 1:keyword 2:keyword # matches 'x' '\\' '\'' '\n' '\0' # not incomplete literals: '\' # not valid identifiers: w' _' add-highlighter shared/haskell/code/ regex \B'([^\\]|[\\]['"\w\d\\])' 0:string # this has to come after operators so '-' etc is correct # Commands # ‾‾‾‾‾‾‾‾ # http://en.wikibooks.org/wiki/Haskell/Indentation define-command -hidden haskell-trim-indent %{ # remove trailing white spaces try %{ execute-keys -draft -itersel s \h+$ d } } define-command -hidden haskell-indent-on-new-line %{ evaluate-commands -draft -itersel %{ # copy -- comments prefix and following white spaces try %{ execute-keys -draft k s ^\h*\K--\h* y gh j P } # preserve previous line indent try %{ execute-keys -draft \; K } # align to first clause try %{ execute-keys -draft \; k x X s ^\h*(if|then|else)?\h*(([\w']+\h+)+=)?\h*(case\h+[\w']+\h+of|do|let|where)\h+\K.* s \A|.\z & } # filter previous line try %{ execute-keys -draft k : haskell-trim-indent } # indent after lines beginning with condition or ending with expression or =( try %{ execute-keys -draft \; k x ^\h*(if)|(case\h+[\w']+\h+of|do|let|where|[=(])$ j } } } ] kakoune-2019.07.01/rc/filetype/hbs.kak000066400000000000000000000076011350637360100172510ustar00rootroot00000000000000# http://handlebarsjs.com/ # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*[.](hbs) %{ set-option buffer filetype hbs } hook global WinSetOption filetype=hbs %{ require-module hbs hook window ModeChange insert:.* -group hbs-trim-indent hbs-trim-indent hook window InsertChar \n -group hbs-indent hbs-indent-on-new-line hook window InsertChar .* -group hbs-indent hbs-indent-on-char hook window InsertChar '>' -group hbs-indent html-indent-on-greater-than hook window InsertChar \n -group hbs-indent html-indent-on-new-line hook -once -always window WinSetOption filetype=.* %{ remove-hooks window hbs-.+ } } hook -group hbs-highlight global WinSetOption filetype=hbs %{ maybe-add-hbs-to-html add-highlighter window/hbs-file ref hbs-file hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/hbs-file } } provide-module hbs %[ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/hbs regions add-highlighter shared/hbs/comment region \{\{!-- --\}\} fill comment add-highlighter shared/hbs/comment_alt region \{\{! \}\} fill comment add-highlighter shared/hbs/block-expression region \{\{[#/] \}\} regions add-highlighter shared/hbs/expression region \{\{ \}\} regions define-command -hidden add-mutual-highlighters -params 1 %~ add-highlighter "shared/hbs/%arg{1}/code" default-region group add-highlighter "shared/hbs/%arg{1}/single-quote" region '"' (? s \h+$ d } } define-command -hidden hbs-indent-on-char %[ evaluate-commands -draft -itersel %[ # de-indent after closing a yielded block tag try %[ execute-keys -draft s ^\h+\{\{/([\w-.]+(?:/[\w-.]+)*)\}\}$ {c\{\{#1,\{\{/1\}\} s \A|.\z 1 ] ] ] define-command -hidden hbs-indent-on-new-line %{ evaluate-commands -draft -itersel %{ # copy '/' comment prefix and following white spaces try %{ execute-keys -draft k s ^\h*\K/\h* y j p } # preserve previous line indent try %{ execute-keys -draft \; K } # filter previous line try %{ execute-keys -draft k : hbs-trim-indent } # indent after lines beginning with : or - try %{ execute-keys -draft k ^\h*[:-] j } } } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ declare-option bool hbs_highlighters_enabled false define-command -hidden maybe-add-hbs-to-html %{ evaluate-commands %sh{ if [ "$kak_opt_hbs_highlighters_enabled" == "false" ]; then printf %s " add-highlighter shared/html/hbs region '\{\{' '\}\}' ref hbs add-highlighter shared/html/tag/hbs region '\{\{' '\}\}' ref hbs set-option global hbs_highlighters_enabled true " fi } } ] kakoune-2019.07.01/rc/filetype/html.kak000066400000000000000000000060451350637360100174420ustar00rootroot00000000000000# http://w3.org/html # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*\.html %{ set-option buffer filetype html } hook global BufCreate .*\.xml %{ set-option buffer filetype xml } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=(html|xml) %{ require-module html hook window ModeChange insert:.* -group "%val{hook_param_capture_1}-trim-indent" html-trim-indent hook window InsertChar '>' -group "%val{hook_param_capture_1}-indent" html-indent-on-greater-than hook window InsertChar \n -group "%val{hook_param_capture_1}-indent" html-indent-on-new-line hook -once -always window WinSetOption "filetype=.*" " remove-hooks window ""%val{hook_param_capture_1}-.+"" " } hook -group html-highlight global WinSetOption filetype=(html|xml) %{ add-highlighter "window/%val{hook_param_capture_1}" ref html hook -once -always window WinSetOption "filetype=.*" " remove-highlighter ""window/%val{hook_param_capture_1}"" " } provide-module html %[ try %{ require-module css require-module javascript } # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/html regions add-highlighter shared/html/comment region fill comment add-highlighter shared/html/tag region < > regions add-highlighter shared/html/style region \K (?=) ref css add-highlighter shared/html/script region \K (?=) ref javascript add-highlighter shared/html/tag/base default-region group add-highlighter shared/html/tag/ region '"' (? s \h+$ d } } define-command -hidden html-indent-on-greater-than %[ evaluate-commands -draft -itersel %[ # align closing tag to opening when alone on a line try %[ execute-keys -draft s ^\h+/(\w+)$ {c1,/1 s \A|.\z 1 ] ] ] define-command -hidden html-indent-on-new-line %{ evaluate-commands -draft -itersel %{ # preserve previous line indent try %{ execute-keys -draft \; K } # filter previous line try %{ execute-keys -draft k : html-trim-indent } # indent after lines ending with opening tag try %{ execute-keys -draft k (?!area)(?!base)(?!br)(?!col)(?!command)(?!embed)(?!hr)(?!img)(?!input)(?!keygen)(?!link)(?!menuitem)(?!meta)(?!param)(?!source)(?!track)(?!wbr)(?!/)(?!>)[a-zA-Z0-9_-]+[^>]*?>$ j } } } ] kakoune-2019.07.01/rc/filetype/i3.kak000066400000000000000000000111551350637360100170070ustar00rootroot00000000000000hook global BufCreate .*(sway|i3)/config %{ set buffer filetype i3 } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=i3 %[ require-module i3 # cleanup trailing whitespaces when exiting insert mode hook window ModeChange insert:.* -group i3-trim-indent %{ try %{ execute-keys -draft s^\h+$d } } hook window InsertChar \n -group i3-indent i3-indent-on-new-line hook window InsertChar \} -group i3-indent i3-indent-on-closing-curly-brace hook -once -always window WinSetOption filetype=.* %{ remove-hooks window i3-.+ } ] hook -group i3-highlight global WinSetOption filetype=i3 %{ add-highlighter window/i3 ref i3 hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/i3 } } provide-module i3 %[ add-highlighter shared/i3 regions add-highlighter shared/i3/code default-region group add-highlighter shared/i3/double_string region %{"} %{"} group add-highlighter shared/i3/single_string region %{'} %{'} group add-highlighter shared/i3/exec region %{((?<=exec )|(?<=--no-startup-id ))(?!--no-startup-id)} "$" fill string add-highlighter shared/i3/comment region "#" "$" fill comment add-highlighter shared/i3/double_string/ fill string add-highlighter shared/i3/single_string/ fill string # Symbols add-highlighter shared/i3/code/ regex "[+|→]" 0:operator add-highlighter shared/i3/code/ regex "\$\w+" 0:variable # keys add-highlighter shared/i3/code/ regex "\b(Shift|Control|Ctrl|Mod1|Mod2|Mod3|Mod4|Mod5|Mode_switch|Return|Escape|Print)\b" 0:value # keywords add-highlighter shared/i3/code/ regex "\b(bind|bindcode|bindsym|assign|new_window|default_(floating_)?border|popup_during_fullscreen|font|floating_modifier|default_orientation|workspace_layout|for_window|focus_follows_mouse|bar|position|colors|output|tray_output|workspace_buttons|workspace_auto_back_and_forth|binding_mode_indicator|debuglog|floating_minimum_size|floating_maximum_size|force_focus_wrapping|force_xinerama|force_display_urgency_hint|hidden_state|modifier|new_float|shmlog|socket_path|verbose|mouse_warping|strip_workspace_numbers|focus_on_window_activation|no_focus|set|mode|set_from_resource)\b" 0:keyword # function keywords add-highlighter shared/i3/code/ regex "\b(exit|reload|restart|kill|fullscreen|global|layout|border|focus|move|open|split|append_layout|mark|unmark|resize|grow|shrink|show|nop|rename|title_format|sticky)\b" 0:function add-highlighter shared/i3/code/ regex "\b(exec|exec_always|i3bar_command|status_command)\b" 0:function # " these are not keywords but we add them for consistency add-highlighter shared/i3/code/ regex "\b(no|false|inactive)\b" 0:value # values add-highlighter shared/i3/code/ regex "\b(1pixel|default|stacked|tabbed|normal|none|tiling|stacking|floating|enable|disable|up|down|horizontal|vertical|auto|up|down|left|right|parent|child|px|or|ppt|leave_fullscreen|toggle|mode_toggle|scratchpad|width|height|top|bottom|client|hide|primary|yes|all|active|window|container|to|absolute|center|on|off|ms|smart|ignore|pixel|splith|splitv|output|true)\b" 0:value add-highlighter shared/i3/code/ regex "\b(next|prev|next_on_output|prev_on_output|back_and_forth|current|number|none|vertical|horizontal|both|dock|hide|invisible|gaps|smart_gaps|smart_borders|inner|outer|current|all|plus|minus|no_gaps)\b" 0:value # double-dash arguments add-highlighter shared/i3/code/ regex "--(release|border|whole-window|toggle|no-startup-id)" 0:attribute # color add-highlighter shared/i3/double_string/ regex "#[0-9a-fA-F]{6}" 0:value add-highlighter shared/i3/single_string/ regex "#[0-9a-fA-F]{6}" 0:value # attributes add-highlighter shared/i3/code/ regex "client\.(background|statusline|background|separator|statusline)" 1:attribute add-highlighter shared/i3/code/ regex "client\.(focused_inactive|focused|unfocused|urgent|inactive_workspace|urgent_workspace|focused_workspace|active_workspace|placeholder)" 1:attribute # Commands # ‾‾‾‾‾‾‾‾ define-command -hidden i3-indent-on-new-line %~ evaluate-commands -draft -itersel %= # copy # comments prefix try %{ execute-keys -draft k s ^\h*#\h* y jgh P } # preserve previous line indent try %{ execute-keys -draft \;K } # indent after lines ending with { try %[ execute-keys -draft k \{\h*$ j ] # cleanup trailing white spaces on the previous line try %{ execute-keys -draft k s \h+$ d } = ~ define-command -hidden i3-indent-on-closing-curly-brace %[ # align to opening curly brace when alone on a line try %[ execute-keys -itersel -draft ^\h+\}$hms\A|.\z1 ] ] ] kakoune-2019.07.01/rc/filetype/ini.kak000066400000000000000000000012661350637360100172550ustar00rootroot00000000000000hook global BufCreate .+\.(repo|ini|cfg|properties) %{ set-option buffer filetype ini } hook global WinSetOption filetype=ini %{ require-module ini } hook -group ini-highlight global WinSetOption filetype=ini %{ add-highlighter window/ini ref ini hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/ini } } provide-module ini %{ add-highlighter shared/ini regions add-highlighter shared/ini/code default-region group add-highlighter shared/ini/comment region '(^|\h)\K[#;]' $ fill comment add-highlighter shared/ini/code/ regex "^\h*\[[^\]]*\]" 0:title add-highlighter shared/ini/code/ regex "^\h*([^\[][^=\n]*)=([^\n]*)" 1:variable 2:value } kakoune-2019.07.01/rc/filetype/java.kak000066400000000000000000000064721350637360100174230ustar00rootroot00000000000000hook global BufCreate .*\.java %{ set-option buffer filetype java } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=java %{ require-module java # cleanup trailing whitespaces when exiting insert mode hook window ModeChange insert:.* -group java-trim-indent %{ try %{ execute-keys -draft s^\h+$d } } hook window InsertChar \n -group java-indent java-indent-on-new-line hook window InsertChar \{ -group java-indent java-indent-on-opening-curly-brace hook window InsertChar \} -group java-indent java-indent-on-closing-curly-brace hook -once -always window WinSetOption filetype=.* %{ remove-hooks window java-.+ } } hook -group java-highlight global WinSetOption filetype=java %{ add-highlighter window/java ref java hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/java } } provide-module java %§ add-highlighter shared/java regions add-highlighter shared/java/code default-region group add-highlighter shared/java/string region %{(? } # indent after lines ending with { or ( try %[ execute-keys -draft k [{(]\h*$ j ] # cleanup trailing white spaces on the previous line try %{ execute-keys -draft k s \h+$ d } # align to opening paren of previous line try %{ execute-keys -draft [( \A\([^\n]+\n[^\n]*\n?\z s \A\(\h*.|.\z '' & } # copy // comments prefix try %{ execute-keys -draft \;k s ^\h*\K/{2,} yP } # indent after a switch's case/default statements try %[ execute-keys -draft k ^\h*(case|default).*:$ j ] # indent after keywords try %[ execute-keys -draft \;)MB \A(if|else|while|for|try|catch)\h*\(.*\)\h*\n\h*\n?\z s \A|.\z 11 ] = ~ define-command -hidden java-indent-on-opening-curly-brace %[ # align indent with opening paren when { is entered on a new line after the closing paren try %[ execute-keys -draft -itersel h)M \A\(.*\)\h*\n\h*\{\z s \A|.\z 1 ] ] define-command -hidden java-indent-on-closing-curly-brace %[ # align to opening curly brace when alone on a line try %[ execute-keys -itersel -draft ^\h+\}$hms\A|.\z1 ] ] § kakoune-2019.07.01/rc/filetype/javascript.kak000066400000000000000000000152421350637360100206430ustar00rootroot00000000000000# Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*[.](js)x? %{ set-option buffer filetype javascript } hook global BufCreate .*[.](ts)x? %{ set-option buffer filetype typescript } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=(javascript|typescript) %{ require-module javascript hook window ModeChange insert:.* -group "%val{hook_param_capture_1}-trim-indent" javascript-trim-indent hook window InsertChar .* -group "%val{hook_param_capture_1}-indent" javascript-indent-on-char hook window InsertChar \n -group "%val{hook_param_capture_1}-indent" javascript-indent-on-new-line hook -once -always window WinSetOption filetype=.* " remove-hooks window %val{hook_param_capture_1}-.+ " } hook -group javascript-highlight global WinSetOption filetype=javascript %{ add-highlighter window/javascript ref javascript hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/javascript } } hook -group typescript-highlight global WinSetOption filetype=typescript %{ add-highlighter window/typescript ref typescript hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/typescript } } provide-module javascript %§ # Commands # ‾‾‾‾‾‾‾‾ define-command -hidden javascript-trim-indent %{ # remove trailing white spaces try %{ execute-keys -draft -itersel s \h+$ d } } define-command -hidden javascript-indent-on-char %< evaluate-commands -draft -itersel %< # align closer token to its opener when alone on a line try %/ execute-keys -draft ^\h+[\]}]$ m s \A|.\z 1 / > > define-command -hidden javascript-indent-on-new-line %< evaluate-commands -draft -itersel %< # copy // comments prefix and following white spaces try %{ execute-keys -draft k s ^\h*\K#\h* y gh j P } # preserve previous line indent try %{ execute-keys -draft \; K } # filter previous line try %{ execute-keys -draft k : javascript-trim-indent } # indent after lines beginning / ending with opener token try %_ execute-keys -draft k ^\h*[[{]|[[{]$ j _ > > # Highlighting and hooks bulder for JavaScript and TypeScript # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ define-command -hidden init-javascript-filetype -params 1 %~ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter "shared/%arg{1}" regions add-highlighter "shared/%arg{1}/code" default-region group add-highlighter "shared/%arg{1}/double_string" region '"' (?])(?!>\()) (|/>) regions add-highlighter "shared/%arg{1}/division" region '[\w\)\]]\K(/|(\h+/\h+))' '(?=\w)' group # Help Kakoune to better detect /…/ literals # Regular expression flags are: g → global match, i → ignore case, m → multi-lines, u → unicode, y → sticky # https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp add-highlighter "shared/%arg{1}/literal/" fill string add-highlighter "shared/%arg{1}/literal/" regex \$\{.*?\} 0:value add-highlighter "shared/%arg{1}/code/" regex [^$_]\b(document|false|null|parent|self|this|true|undefined|window)\b 1:value add-highlighter "shared/%arg{1}/code/" regex "-?\b[0-9]*\.?[0-9]+" 0:value add-highlighter "shared/%arg{1}/code/" regex \b(Array|Boolean|Date|Function|Number|Object|RegExp|String|Symbol)\b 0:type # jsx: In well-formed xml the number of opening and closing tags match up regardless of tag name. # # We inline a small XML highlighter here since it anyway need to recurse back up to the starting highlighter. # To make things simple we assume that jsx is always enabled. add-highlighter "shared/%arg{1}/jsx/tag" region -recurse < <(?=[/a-zA-Z]) (? regions add-highlighter "shared/%arg{1}/jsx/expr" region -recurse \{ \{ \} ref %arg{1} add-highlighter "shared/%arg{1}/jsx/tag/base" default-region group add-highlighter "shared/%arg{1}/jsx/tag/double_string" region =\K" (?) 0:meta add-highlighter "shared/%arg{1}/jsx/tag/expr/" ref %arg{1} # Keywords are collected at # https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Keywords # https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get # https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set add-highlighter "shared/%arg{1}/code/" regex \b(async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|export|extends|finally|for|function|get|if|import|in|instanceof|let|new|of|return|set|static|super|switch|throw|try|typeof|var|void|while|with|yield)\b 0:keyword ~ init-javascript-filetype javascript init-javascript-filetype typescript # Highlighting specific to TypeScript # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/typescript/code/ regex \b(array|boolean|date|number|object|regexp|string|symbol)\b 0:type # Keywords grabbed from https://github.com/Microsoft/TypeScript/issues/2536 add-highlighter shared/typescript/code/ regex \b(as|constructor|declare|enum|from|implements|interface|module|namespace|package|private|protected|public|readonly|static|type)\b 0:keyword § kakoune-2019.07.01/rc/filetype/json.kak000066400000000000000000000037501350637360100174470ustar00rootroot00000000000000# http://json.org # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*[.](json) %{ set-option buffer filetype json } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=json %{ require-module json hook window ModeChange insert:.* -group json-trim-indent json-trim-indent hook window InsertChar .* -group json-indent json-indent-on-char hook window InsertChar \n -group json-indent json-indent-on-new-line hook -once -always window WinSetOption filetype=.* %{ remove-hooks window json-.+ } } hook -group json-highlight global WinSetOption filetype=json %{ add-highlighter window/json ref json hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/json } } provide-module json %( # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/json regions add-highlighter shared/json/code default-region group add-highlighter shared/json/string region '"' (? s \h+$ d } } define-command -hidden json-indent-on-char %< evaluate-commands -draft -itersel %< # align closer token to its opener when alone on a line try %< execute-keys -draft ^\h+[]}]$ m s \A|.\z 1 > > > define-command -hidden json-indent-on-new-line %< evaluate-commands -draft -itersel %< # preserve previous line indent try %{ execute-keys -draft \; K } # filter previous line try %{ execute-keys -draft k : json-trim-indent } # indent after lines beginning with opener token try %< execute-keys -draft k ^\h*[[{] j > > > ) kakoune-2019.07.01/rc/filetype/julia.kak000066400000000000000000000043661350637360100176060ustar00rootroot00000000000000# http://julialang.org # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*\.(jl) %{ set-option buffer filetype julia } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=julia %{ require-module julia } hook -group julia-highlight global WinSetOption filetype=julia %{ add-highlighter window/julia ref julia hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/julia } } provide-module julia %{ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/julia regions add-highlighter shared/julia/code default-region group add-highlighter shared/julia/string region '"' (? } # cleanup trailing white spaces on previous line try %{ execute-keys -draft k s \h+$ "_d } # copy '#' comment prefix and following white spaces try %{ execute-keys -draft k s ^\h*//\h* y jgh P } } } # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/justfile regions add-highlighter shared/justfile/content default-region group add-highlighter shared/justfile/comment region '#' '$' fill comment add-highlighter shared/justfile/double_string region '"' (?)}\]] -group kak-indent kak-indent-on-closing-matching hook window InsertChar (?![[{(<>)}\]])[^\s\w] -group kak-indent kak-indent-on-closing-char # cleanup trailing whitespaces on current line insert end hook window ModeChange insert:.* -group kak-trim-indent %{ try %{ execute-keys -draft \; s ^\h+$ d } } set-option buffer extra_word_chars '_' '-' hook -once -always window WinSetOption filetype=.* %{ remove-hooks window kak-.+ } ~ hook -group kak-highlight global WinSetOption filetype=kak %{ add-highlighter window/kakrc ref kakrc hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/kakrc } } provide-module kak %§ require-module sh # Highlighters & Completion # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/kakrc regions add-highlighter shared/kakrc/code default-region group add-highlighter shared/kakrc/comment region (^|\h)\K# $ fill comment add-highlighter shared/kakrc/double_string region -recurse %{(?' ref sh add-highlighter shared/kakrc/shell5 region -recurse '\{' '(^|\h)\K-shell-script-(completion|candidates)\h+%\{' '\}' ref sh add-highlighter shared/kakrc/shell6 region -recurse '\(' '(^|\h)\K-shell-script-(completion|candidates)\h+%\(' '\)' ref sh add-highlighter shared/kakrc/shell7 region -recurse '\[' '(^|\h)\K-shell-script-(completion|candidates)\h+%\[' '\]' ref sh add-highlighter shared/kakrc/shell8 region -recurse '<' '(^|\h)\K-shell-script-(completion|candidates)\h+%<' '>' ref sh evaluate-commands %sh{ # Grammar keywords="edit write write-all kill quit write-quit write-all-quit map unmap alias unalias buffer buffer-next buffer-previous delete-buffer add-highlighter remove-highlighter hook remove-hooks define-command echo debug source try catch fail nop set-option unset-option update-option declare-option execute-keys evaluate-commands prompt menu on-key info set-face unset-face rename-client set-register select change-directory rename-session colorscheme declare-user-mode enter-user-mode edit! write! kill! quit! write-quit! delete-buffer! provide-module require-module" attributes="global buffer window current normal insert menu prompt goto view user object number-lines show-matching show-whitespaces fill regex dynregex group flag-lines ranges line column wrap ref regions region default-region replace-ranges" types="int bool str regex int-list str-list completions line-specs range-specs" values="default black red green yellow blue magenta cyan white yes no false true" join() { sep=$2; eval set -- $1; IFS="$sep"; echo "$*"; } # Add the language's grammar to the static completion list printf %s\\n "declare-option str-list kak_static_words $(join "${keywords} ${attributes} ${types} ${values}" ' ')'" # Highlight keywords (which are always surrounded by whitespace) printf '%s\n' "add-highlighter shared/kakrc/code/keywords regex (?:\s|\A)\K($(join "${keywords}" '|'))(?:(?=\s)|\z) 0:keyword add-highlighter shared/kakrc/code/attributes regex (?:\s|\A)\K($(join "${attributes}" '|'))(?:(?=\s)|\z) 0:attribute add-highlighter shared/kakrc/code/types regex (?:\s|\A)\K($(join "${types}" '|'))(?:(?=\s)|\z) 0:type add-highlighter shared/kakrc/code/values regex (?:\s|\A)\K($(join "${values}" '|'))(?:(?=\s)|\z) 0:value" } add-highlighter shared/kakrc/code/colors regex \brgb:[0-9a-fA-F]{6}\b 0:value add-highlighter shared/kakrc/code/scopes regex \b(global|shared|buffer|window)(?:\b|/) 0:value add-highlighter shared/kakrc/double_string/fill fill string add-highlighter shared/kakrc/double_string/escape regex '""' 0:default+b add-highlighter shared/kakrc/single_string/fill fill string add-highlighter shared/kakrc/single_string/escape regex "''" 0:default+b # Commands # ‾‾‾‾‾‾‾‾ define-command -hidden kak-indent-on-new-line %{ evaluate-commands -draft -itersel %{ # copy '#' comment prefix and following white spaces try %{ execute-keys -draft k s ^\h*#\h* y jgh P } # preserve previous line indent try %{ execute-keys -draft \; K } # cleanup trailing whitespaces from previous line try %{ execute-keys -draft k s \h+$ d } # indent after line ending with %\w*[^\s\w] try %{ execute-keys -draft k \%\w*[^\s\w]$ j } } } define-command -hidden kak-indent-on-closing-matching %~ # align to opening matching brace when alone on a line try %= execute-keys -draft -itersel ^\h*\Q %val{hook_param} \E$ mGi s \A|.\z 1 = ~ define-command -hidden kak-indent-on-closing-char %{ # align to opening matching character when alone on a line try %{ execute-keys -draft -itersel ^\h*\Q %val{hook_param} \E$gi %val{hook_param} %\w*\Q %val{hook_param} \E$ s \A|.\z gi 1 } } § kakoune-2019.07.01/rc/filetype/kickstart.kak000066400000000000000000000042441350637360100204740ustar00rootroot00000000000000hook global BufCreate .*\.ks %{ set-option buffer filetype kickstart } hook global WinSetOption filetype=kickstart %{ require-module kickstart } hook -group kickstart-highlight global WinSetOption filetype=kickstart %{ add-highlighter window/kickstart ref kickstart hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/kickstart } } provide-module kickstart %{ add-highlighter shared/kickstart regions add-highlighter shared/kickstart/code default-region group add-highlighter shared/kickstart/comment region '(^|\h)\K#' $ fill comment add-highlighter shared/kickstart/double_string region '"' (? 1s^(\h+)$ d } } } define-command -hidden latex-indent-newline %( evaluate-commands -no-hooks -draft -itersel %( # copy '%' comment prefix and following white spaces try %{ execute-keys -draft k s^\h*%\h* y jgh P } # preserve previous line indent try %{ execute-keys -draft K } # cleanup trailing whitespaces from previous line try %{ execute-keys -draft k s\h+$ d } # indent after line ending with { try %( execute-keys -draft k \{$ j ) # indent after line ending with \begin{...}[...]{...}, with multiple # sets of arguments possible try %( execute-keys -draft \ k \ \\begin\h*\{[^\}]+\}(\h|\[.*\]|\{.*\})*$ \ j ) ) ) define-command -hidden latex-indent-closing-brace %( evaluate-commands -no-hooks -draft -itersel %( # Align lone } with matching bracket try %( execute-keys -draft _ \A\}\z m1 ) # Align \end{...} with corresponding \begin{...} try %( execute-keys -draft h 1s\\end\h*\{([^\}]+)\}\z \ \\begin\s*\{.\} 1 ) ) ) ~ kakoune-2019.07.01/rc/filetype/lisp.kak000066400000000000000000000061511350637360100174430ustar00rootroot00000000000000# http://common-lisp.net # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*[.](lisp) %{ set-option buffer filetype lisp } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=lisp %{ require-module lisp hook window ModeChange insert:.* -group lisp-trim-indent lisp-trim-indent hook window InsertChar \n -group lisp-indent lisp-indent-on-new-line hook -once -always window WinSetOption filetype=.* %{ remove-hooks window lisp-.+ } } hook -group lisp-highlight global WinSetOption filetype=lisp %{ add-highlighter window/lisp ref lisp hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/lisp } } provide-module lisp %{ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/lisp regions add-highlighter shared/lisp/code default-region group add-highlighter shared/lisp/string region '"' (?|<=|=|>=) 0:operator add-highlighter shared/lisp/code/ regex \b(def[a-z]+|if|do|let|lambda|catch|and|assert|while|def|do|fn|finally|let|loop|new|quote|recur|set!|throw|try|var|case|if-let|if-not|when|when-first|when-let|when-not|(cond(->|->>)?))\b 0:keyword add-highlighter shared/lisp/code/ regex (#?(['`:]|,@?))?\b[a-zA-Z][\w!$%&*+./:<=>?@^_~-]* 0:variable add-highlighter shared/lisp/code/ regex \*[a-zA-Z][\w!$%&*+./:<=>?@^_~-]*\* 0:variable add-highlighter shared/lisp/code/ regex (\b\d+)?\.\d+([eEsSfFdDlL]\d+)?\b 0:value # Commands # ‾‾‾‾‾‾‾‾ define-command -hidden lisp-trim-indent %{ # remove trailing white spaces try %{ execute-keys -draft -itersel s \h+$ d } } declare-option \ -docstring 'regex matching the head of forms which have options *and* indented bodies' \ regex lisp_special_indent_forms \ '(?:def.*|if(-.*|)|let.*|lambda|with-.*|when(-.*|))' define-command -hidden lisp-indent-on-new-line %{ # registers: i = best align point so far; w = start of first word of form evaluate-commands -draft -save-regs '/"|^@iw' -itersel %{ execute-keys -draft 'gk"iZ' try %{ execute-keys -draft '[bl"i"wZ' try %{ # If a special form, indent another (indentwidth - 1) spaces execute-keys -draft '"wze\A' %opt{lisp_special_indent_forms} '\z' execute-keys -draft '"wzes.{' %sh{printf $(( kak_opt_indentwidth - 1 ))} '}\K.*;"i' } catch %{ # If not "special" form and parameter appears on line 1, indent to parameter execute-keys -draft '"wzes\h\K[^\s].*;"i' } } try %{ execute-keys -draft '[rl"i' } try %{ execute-keys -draft '[Bl"i' } execute-keys -draft ';"ia&' } } } kakoune-2019.07.01/rc/filetype/lua.kak000066400000000000000000000104711350637360100172550ustar00rootroot00000000000000# http://lua.org # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*[.](lua) %{ set-option buffer filetype lua } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=lua %{ require-module lua hook window InsertChar .* -group lua-indent lua-indent-on-char hook window InsertChar \n -group lua-indent lua-indent-on-new-line hook window InsertChar \n -group lua-insert lua-insert-on-new-line alias window alt lua-alternative-file hook -once -always window WinSetOption filetype=.* %{ remove-hooks window lua-.+ unalias window alt lua-alternative-file } } hook -group lua-highlight global WinSetOption filetype=lua %{ add-highlighter window/lua ref lua hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/lua } } provide-module lua %[ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/lua regions add-highlighter shared/lua/code default-region group add-highlighter shared/lua/raw_string region -match-capture '\[(=*)\[' '\](=*)\]' fill string add-highlighter shared/lua/raw_comment region -match-capture '--\[(=*)\[' '\](=*)\]' fill comment add-highlighter shared/lua/double_string region '"' (?^\h*(else)$^\h*(if)s\A|\z) } try %{ execute-keys -draft ^\h*(end)$^\h*(for|function|if|while)s\A|\z) } } } define-command -hidden lua-indent-on-new-line %{ evaluate-commands -no-hooks -draft -itersel %{ # preserve previous line indent try %{ execute-keys -draft K } # remove trailing white spaces from previous line try %{ execute-keys -draft ks\h+$d } # indent after start structure try %{ execute-keys -draft k^\h*(else|elseif|for|function|if|while)\bj } } } define-command -hidden lua-insert-on-new-line %[ evaluate-commands -no-hooks -draft -itersel %[ # copy -- comment prefix and following white spaces try %{ execute-keys -draft ks^\h*\K--\h*yghjP } # wisely add end structure evaluate-commands -save-regs x %[ try %{ execute-keys -draft ks^\h+"xy } catch %{ reg x '' } # Save previous line indent in register x try %[ execute-keys -draft k ^x(for|function|if|while) J}iJ ^x(else|end|elseif)$ # Validate previous line and that it is not closed yet execute-keys -draft oxend ] # auto insert end ] ] ] ] kakoune-2019.07.01/rc/filetype/mail.kak000066400000000000000000000012061350637360100174120ustar00rootroot00000000000000hook global BufCreate .+\.eml %{ set-option buffer filetype mail } hook global WinSetOption filetype=mail %{ require-module mail } hook -group mail-highlight global WinSetOption filetype=mail %{ add-highlighter window/mail ref mail hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/mail } } provide-module mail %{ add-highlighter shared/mail group add-highlighter shared/mail/ regex ^(From|To|Cc|Bcc|Subject|Reply-To|In-Reply-To|Date):([^\n]*(?:\n\h+[^\n]+)*)$ 1:keyword 2:attribute add-highlighter shared/mail/ regex <[^@>]+@.*?> 0:string add-highlighter shared/mail/ regex ^>.*?$ 0:comment } kakoune-2019.07.01/rc/filetype/makefile.kak000066400000000000000000000042541350637360100202530ustar00rootroot00000000000000# Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*(/?[mM]akefile|\.mk) %{ set-option buffer filetype makefile } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=makefile %{ require-module makefile set-option window static_words %opt{makefile_static_words} hook window InsertChar \n -group makefile-indent makefile-indent-on-new-line hook -once -always window WinSetOption filetype=.* %{ remove-hooks window makefile-.+ } } hook -group makefile-highlight global WinSetOption filetype=makefile %{ add-highlighter window/makefile ref makefile hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/makefile } } provide-module makefile %{ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/makefile regions add-highlighter shared/makefile/content default-region group add-highlighter shared/makefile/comment region '#' '$' fill comment add-highlighter shared/makefile/evaluate-commands region -recurse '\(' '\$\(' '\)' fill value add-highlighter shared/makefile/content/ regex ^[\w.%-]+\h*:\s 0:variable add-highlighter shared/makefile/content/ regex [+?:]= 0:operator evaluate-commands %sh{ # Grammar keywords="ifeq|ifneq|ifdef|ifndef|else|endif|define|endef" # Add the language's grammar to the static completion list printf %s\\n "declare-option str-list makefile_static_words ${keywords}" | tr '|' ' ' # Highlight keywords printf %s "add-highlighter shared/makefile/content/ regex \b(${keywords})\b 0:keyword" } # Commands # ‾‾‾‾‾‾‾‾ define-command -hidden makefile-indent-on-new-line %{ evaluate-commands -draft -itersel %{ # preserve previous line indent try %{ execute-keys -draft \;K } ## If the line above is a target indent with a tab try %{ execute-keys -draft Z k ^[^:]+:\s z i } # cleanup trailing white space son previous line try %{ execute-keys -draft k s \h+$ d } # indent after some keywords try %{ execute-keys -draft Z k ^\h*(ifeq|ifneq|ifdef|ifndef|else|define)\b z } } } } kakoune-2019.07.01/rc/filetype/markdown.kak000066400000000000000000000075321350637360100203220ustar00rootroot00000000000000# http://daringfireball.net/projects/markdown # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*[.](markdown|md|mkd) %{ set-option buffer filetype markdown } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=markdown %{ require-module markdown hook window InsertChar \n -group markdown-indent markdown-indent-on-new-line hook -once -always window WinSetOption filetype=.* %{ remove-hooks window markdown-.+ } } hook -group markdown-highlight global WinSetOption filetype=markdown %{ add-highlighter window/markdown ref markdown hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/markdown } } provide-module markdown %{ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/markdown regions add-highlighter shared/markdown/inline default-region regions add-highlighter shared/markdown/inline/text default-region group evaluate-commands %sh{ languages=" awk c cabal clojure coffee cpp css cucumber d diff dockerfile fish gas go haml haskell html ini java javascript json julia kak kickstart latex lisp lua makefile markdown moon objc perl pug python ragel ruby rust sass scala scss sh swift toml tupfile typescript yaml sql " for lang in ${languages}; do printf 'add-highlighter shared/markdown/%s region -match-capture ^(\h*)```\h*%s\\b ^(\h*)``` regions\n' "${lang}" "${lang}" printf 'add-highlighter shared/markdown/%s/ default-region fill meta\n' "${lang}" [ "${lang}" = kak ] && ref=kakrc || ref="${lang}" printf 'add-highlighter shared/markdown/%s/inner region \A```[^\\n]*\K (?=```) ref %s\n' "${lang}" "${ref}" done } add-highlighter shared/markdown/codeblock region -match-capture \ ^(\h*)```\h* \ ^(\h*)```\h*$ \ fill meta add-highlighter shared/markdown/listblock region ^\h*[-*]\s ^\h*((?=[-*])|$) regions add-highlighter shared/markdown/listblock/marker region \A [-*]\s fill bullet add-highlighter shared/markdown/listblock/content default-region ref markdown/inline add-highlighter shared/markdown/inline/code region -match-capture (`+) (`+) fill mono # Setext-style header add-highlighter shared/markdown/inline/text/ regex (\A|\n\n)[^\n]+\n={2,}\h*\n\h*$ 0:title add-highlighter shared/markdown/inline/text/ regex (\A|\n\n)[^\n]+\n-{2,}\h*\n\h*$ 0:header # Atx-style header add-highlighter shared/markdown/inline/text/ regex ^#[^\n]* 0:header add-highlighter shared/markdown/inline/text/ regex (? 0:link add-highlighter shared/markdown/inline/text/ regex ^\[[^\]\n]*\]:\h*([^\n]*) 1:link add-highlighter shared/markdown/inline/text/ regex ^\h*(>\h*)+ 0:comment add-highlighter shared/markdown/inline/text/ regex \H\K\h\h$ 0:PrimarySelection # Commands # ‾‾‾‾‾‾‾‾ define-command -hidden markdown-indent-on-new-line %{ evaluate-commands -draft -itersel %{ # copy block quote(s), list item prefix and following white spaces try %{ execute-keys -draft k s ^\h*\K((>\h*)+([*+-]\h)?|(>\h*)*[*+-]\h)\h* y gh j P } # preserve previous line indent try %{ execute-keys -draft \; K } # remove trailing white spaces try %{ execute-keys -draft -itersel %{ k s \h+$ d } } } } } kakoune-2019.07.01/rc/filetype/mercurial.kak000066400000000000000000000015031350637360100204530ustar00rootroot00000000000000# https://www.mercurial-scm.org/ # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*hg-editor-\w+\.txt$ %{ set-option buffer filetype hg-commit } hook global WinSetOption filetype=hg-commit %{ require-module hg-commit } hook -group hg-commit-highlight global WinSetOption filetype=hg-commit %{ add-highlighter window/hg-commit ref hg-commit hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/hg-commit-highlight } } provide-module hg-commit %{ # Faces # ‾‾‾‾‾ set-face global MercurialCommitComment cyan # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/hg-commit group add-highlighter shared/hg-commit/ regex '^HG:[^\n]*' 0:comment } kakoune-2019.07.01/rc/filetype/moon.kak000066400000000000000000000110151350637360100174370ustar00rootroot00000000000000# http://moonscript.org # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*[.](moon) %{ set-option buffer filetype moon } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=moon %{ require-module moon hook window ModeChange insert:.* -group moon-trim-indent moon-trim-indent hook window InsertChar .* -group moon-indent moon-indent-on-char hook window InsertChar \n -group moon-indent moon-indent-on-new-line alias window alt moon-alternative-file hook -once -always window WinSetOption filetype=.* %{ remove-hooks window moon-.+ unalias window alt moon-alternative-file } } hook -group moon-highlight global WinSetOption filetype=moon %{ add-highlighter window/moon ref moon hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/moon } } provide-module moon %[ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/moon regions add-highlighter shared/moon/code default-region group add-highlighter shared/moon/double_string region '"' (? # remove trailing white spaces try %{ execute-keys -draft s \h + $ d } } } define-command -hidden moon-indent-on-char %{ evaluate-commands -draft -itersel %{ # align _else_ statements to start try %{ execute-keys -draft ^ \h * (else(if)?) $ ^ \h * (if|unless|when) s \A | \z ) } # align _when_ to _switch_ then indent try %{ execute-keys -draft ^ \h * (when) $ ^ \h * (switch) s \A | \z ) ) } # align _catch_ and _finally_ to _try_ try %{ execute-keys -draft ^ \h * (catch|finally) $ ^ \h * (try) s \A | \z ) } } } define-command -hidden moon-indent-on-new-line %{ evaluate-commands -draft -itersel %{ # copy -- comment prefix and following white spaces try %{ execute-keys -draft k s ^ \h * \K -- \h * y gh j P } # preserve previous line indent try %{ execute-keys -draft \; K } # filter previous line try %{ execute-keys -draft k : moon-trim-indent } # indent after start structure try %{ execute-keys -draft k ^ \h * (class|else(if)?|for|if|switch|unless|when|while|with) \b | ([:=]|[-=]>) $ j } # deindent after return statements try %{ execute-keys -draft k ^ \h * (break|return) \b j } } } ] kakoune-2019.07.01/rc/filetype/nim.kak000066400000000000000000000113121350637360100172520ustar00rootroot00000000000000# https://nim-lang.org/ # # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*\.nim(s|ble)? %{ set-option buffer filetype nim } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=nim %{ require-module nim set-option window static_words %opt{nim_static_words} hook window InsertChar \n -group nim-indent nim-indent-on-new-line # cleanup trailing whitespaces on current line insert end hook window ModeChange insert:.* -group nim-trim-indent %{ try %{ exec -draft \; s ^\h+$ d } } hook -once -always window WinSetOption filetype=.* %{ remove-hooks window nim-.+ } } hook -group nim-highlight global WinSetOption filetype=nim %{ add-highlighter window/nim ref nim hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/nim } } provide-module nim %{ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/nim regions add-highlighter shared/nim/code default-region group add-highlighter shared/nim/triple_string region '([A-Za-z](_?\w)*)?"""' '"""(?!")' fill string add-highlighter shared/nim/raw_string region [A-Za-z](_?[A-Za-z])*" (?@$~&%|!?^.:\\*]' opnocol='[=+-/<>@$~&%|!?^.\\*]' suffix="('[iIuU](8|16|32|64)|'[fF](32|64)?|'[dDuU]|[fF])?" floatsuffix="('[fF](32|64)?|'[dD]|[fF])?" hexdigit='[0-9a-fA-F]' octdigit='[0-7]' bindigit='[01]' hexlit="0[xX]${hexdigit}(_?${hexdigit})*" declit="\d(_?\d)*" octlit="0o${octdigit}(_?${octdigit})*" binlit="0[bB]${bindigit}(_?${bindigit})*" intlit="\b(${declit}|${hexlit}|${octlit}|${binlit})${suffix}\b" exponent="([eE][+-]?${declit})" floatlit="\b${declit}(\.${declit}${exponent}?|${exponent})${floatsuffix}\b" keywords="addr as asm bind block break case cast concept const continue converter defer discard distinct do elif else end enum except export finally for from func if import include interface iterator let macro method mixin nil out proc ptr raise ref return static template try type unsafeAddr using var when while yield with without atomic generic" operators="or xor and is isnot in notin of div mod shl shr not" types="int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 float float32 float64 bool char object seq array cstring string tuple varargs typedesc pointer byte set typed untyped void auto" values="false true" join() { sep=$2; set -- $1; IFS="$sep"; echo "$*"; } static_words="$(join "${keywords} ${types} ${operator} ${values}" ' ')" # Add the language's grammar to the static completion list printf %s\\n "declare-option str-list nim_static_words ${static_words}" keywords="$(join "${keywords}" '|')" operators="$(join "${operators}" '|')" types="$(join "${types}" '|')" values="$(join "${values}" '|')" # Highlight keywords printf %s " add-highlighter shared/nim/code/ regex ${opchars}+ 0:operator add-highlighter shared/nim/code/ regex (? s ^\h*#\h* y jgh P } # preserve previous line indent try %{ exec -draft \; K } # cleanup trailing whitespaces from previous line try %{ exec -draft k s \h+$ d } # indent after line ending with type, import, export, const, let, var, ':' or '=' try %{ exec -draft k x (:|=|const|let|var|import|export|type)$ j } } } } kakoune-2019.07.01/rc/filetype/ocaml.kak000066400000000000000000000030001350637360100175550ustar00rootroot00000000000000# http://ocaml.org # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*\.mli? %{ set-option buffer filetype ocaml } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=ocaml %{ require-module ocaml set-option window static_words %opt{ocaml_static_words} } hook -group ocaml-highlight global WinSetOption filetype=ocaml %{ add-highlighter window/ocaml ref ocaml hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/ocaml } } provide-module ocaml %{ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/ocaml regions add-highlighter shared/ocaml/code default-region group add-highlighter shared/ocaml/string region '"' (?s^\h+$d } } hook window InsertChar \n -group perl-indent perl-indent-on-new-line hook window InsertChar \{ -group perl-indent perl-indent-on-opening-curly-brace hook window InsertChar \} -group perl-indent perl-indent-on-closing-curly-brace hook -once -always window WinSetOption filetype=.* %{ remove-hooks window perl-.+ } } hook -group perl-highlight global WinSetOption filetype=perl %{ add-highlighter window/perl ref perl hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/perl } } provide-module perl %§ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/perl regions add-highlighter shared/perl/code default-region group add-highlighter shared/perl/command region (?|\$\?|\$@|\$\[|\$\\|\$\]|\$\^|\$\||\$~|%!|@\+|@-|@_} 0:value add-highlighter shared/perl/code/ regex (%ENV|%INC|%OVERLOAD|%SIG|@ARGV|@INC|@LAST_MATCH_START) 0:value add-highlighter shared/perl/code/ regex %{%\^(H)\b} 0:value add-highlighter shared/perl/code/ regex \$\^(S|T|V|W|X|A|C|D|E|F|H|I|L|M|N|O|P|R)\b 0:value add-highlighter shared/perl/code/ regex \$\^(RE_TRIE_MAXBUF|TAINT|UNICODE|UTF8LOCALE|WARNING_BITS|WIDE_SYSTEM_CALLS|CHILD_ERROR_NATIVE|ENCODING|OPEN|RE_DEBUG_FLAGS)\b 0:value add-highlighter shared/perl/code/ regex \$[0-9]+ 0:attribute add-highlighter shared/perl/code/ regex \b-(B|b|C|c|d|e|f|g|k|l|M|O|o|p|r|R|S|s|T|t|u|w|W|X|x|z)\b 0:attribute add-highlighter shared/perl/code/ regex \$[a-zA-Z_][a-zA-Z0-9_]* 0:variable add-highlighter shared/perl/code/ regex \$(a|b|LAST_REGEXP_CODE_RESULT|LIST_SEPARATOR|MATCH|MULTILINE_MATCHING|NR|OFMT|OFS|ORS|OS_ERROR|OSNAME|OUTPUT_AUTO_FLUSH|OUTPUT_FIELD_SEPARATOR|OUTPUT_RECORD_SEPARATOR)\b 0:value add-highlighter shared/perl/code/ regex \$(LAST_REGEXP_CODE_RESULT|LIST_SEPARATOR|MATCH|MULTILINE_MATCHING|NR|OFMT|OFS|ORS|OS_ERROR|OSNAME|OUTPUT_AUTO_FLUSH|OUTPUT_FIELD_SEPARATOR|OUTPUT_RECORD_SEPARATOR|PERL_VERSION|ACCUMULATOR|PERLDB|ARG|PID|ARGV|POSTMATCH|PREMATCH|BASETIME|PROCESS_ID|CHILD_ERROR|PROGRAM_NAME|COMPILING|REAL_GROUP_ID|DEBUGGING|REAL_USER_ID|EFFECTIVE_GROUP_ID|RS|EFFECTIVE_USER_ID|SUBSCRIPT_SEPARATOR|EGID|SUBSEP|ERRNO|SYSTEM_FD_MAX|EUID|UID|EVAL_ERROR|WARNING|EXCEPTIONS_BEING_CAUGHT|EXECUTABLE_NAME|EXTENDED_OS_ERROR|FORMAT_FORMFEED|FORMAT_LINE_BREAK_CHARACTERS|FORMAT_LINES_LEFT|FORMAT_LINES_PER_PAGE|FORMAT_NAME|FORMAT_PAGE_NUMBER|FORMAT_TOP_NAME|GID|INPLACE_EDIT|INPUT_LINE_NUMBER|INPUT_RECORD_SEPARATOR|LAST_MATCH_END|LAST_PAREN_MATCH)\b 0:value # Commands # ‾‾‾‾‾‾‾‾ define-command -hidden perl-indent-on-new-line %~ evaluate-commands -draft -itersel %= # preserve previous line indent try %{ execute-keys -draft \;K } # indent after lines ending with { or ( try %[ execute-keys -draft k [{(]\h*$ j ] # cleanup trailing white spaces on the previous line try %{ execute-keys -draft k s \h+$ d } # align to opening paren of previous line try %{ execute-keys -draft [( \A\([^\n]+\n[^\n]*\n?\z s \A\(\h*.|.\z '' & } # copy // comments prefix try %{ execute-keys -draft \;k s ^\h*\K/{2,} yP } # indent after a switch's case/default statements try %[ execute-keys -draft k ^\h*(case|default).*:$ j ] # indent after if|else|while|for try %[ execute-keys -draft \;)MB \A(if|else|while|for)\h*\(.*\)\h*\n\h*\n?\z s \A|.\z 11 ] = ~ define-command -hidden perl-indent-on-opening-curly-brace %[ # align indent with opening paren when { is entered on a new line after the closing paren try %[ execute-keys -draft -itersel h)M \A\(.*\)\h*\n\h*\{) s \A|.\z 1 ] ] define-command -hidden perl-indent-on-closing-curly-brace %[ # align to opening curly brace when alone on a line try %[ execute-keys -itersel -draft ^\h+\}$hms\A|.\z1 ] ] § kakoune-2019.07.01/rc/filetype/php.kak000066400000000000000000000107001350637360100172560ustar00rootroot00000000000000# Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*[.](php) %{ set-option buffer filetype php } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=php %{ require-module php hook window ModeChange insert:.* -group php-trim-indent php-trim-indent hook window InsertChar .* -group php-indent php-indent-on-char hook window InsertChar \n -group php-indent php-indent-on-new-line hook -once -always window WinSetOption filetype=.* %{ remove-hooks window php-.+ } } hook -group php-highlight global WinSetOption filetype=php %{ add-highlighter window/php-file ref php-file hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/php-file } } provide-module php %( require-module html # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/php regions add-highlighter shared/php/code default-region group add-highlighter shared/php/double_string region '"' (?' 0:meta add-highlighter shared/php/double_string/ fill string add-highlighter shared/php/double_string/ regex (?\w+)* 0:variable add-highlighter shared/php/double_string/ regex \{(?\w+)*\} 0:variable # Highlight doc comments add-highlighter shared/php/doc_comment/ fill string add-highlighter shared/php/doc_comment/ regex '`.*`' 0:module add-highlighter shared/php/doc_comment/ regex '@\w+' 0:meta # Keywords are collected at # http://php.net/manual/en/reserved.keywords.php add-highlighter shared/php/code/ regex \b(__halt_compiler|abstract|and|array|as|break|callable|case|catch|class|clone|const|continue|declare|default|die|do|echo|else|elseif|empty|enddeclare|endfor|endforeach|endif|endswitch|endwhile|eval|exit|extends|final|finally|for|foreach|function|global|goto|if|implements|include|include_once|instanceof|insteadof|interface|isset|list|namespace|new|or|print|private|protected|public|require|require_once|return|static|switch|throw|trait|try|unset|use|var|while|xor|yield|__CLASS__|__DIR__|__FILE__|__FUNCTION__|__LINE__|__METHOD__|__NAMESPACE__|__TRAIT__)\b 0:keyword # Highlighter for html with php tags in it, i.e. the structure of conventional php files add-highlighter shared/php-file regions add-highlighter shared/php-file/html default-region ref html add-highlighter shared/php-file/php region '<\?(php)?' '\?>' ref php # Commands # ‾‾‾‾‾‾‾‾ define-command -hidden php-trim-indent %{ # remove trailing white spaces try %{ execute-keys -draft -itersel s \h+$ d } } define-command -hidden php-indent-on-char %< evaluate-commands -draft -itersel %< # align closer token to its opener when alone on a line try %/ execute-keys -draft ^\h+[]}]$ m s \A|.\z 1 / > > define-command -hidden php-indent-on-new-line %< evaluate-commands -draft -itersel %< # copy // comments or docblock * prefix and following white spaces try %{ execute-keys -draft s [^/] k s ^\h*\K(?://|[*][^/])\h* y gh j P } # preserve previous line indent try %{ execute-keys -draft \; K } # filter previous line try %{ execute-keys -draft k : php-trim-indent } # indent after lines beginning / ending with opener token try %_ execute-keys -draft k ^\h*[[{]|[[{]$ j _ # append " * " on lines starting a multiline /** or /* comment try %{ execute-keys -draft k s ^\h*/[*][* ]? j gi i * } > > ) kakoune-2019.07.01/rc/filetype/pony.kak000066400000000000000000000076021350637360100174630ustar00rootroot00000000000000# http://ponylang.org # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*[.](pony) %{ set-option buffer filetype pony } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=pony %{ require-module pony set-option window static_words %opt{pony_static_words} hook window InsertChar \n -group pony-indent pony-indent-on-new-line # cleanup trailing whitespaces on current line insert end hook window ModeChange insert:.* -group pony-trim-indent %{ try %{ execute-keys -draft \; s ^\h+$ d } } hook -once -always window WinSetOption filetype=.* %{ remove-hooks window pony-.+ } } hook -group pony-highlight global WinSetOption filetype=pony %{ add-highlighter window/pony ref pony hook -once -always window WinSetOption filetype=.* %{ remove-highlighter pony } } provide-module pony %{ # Highlighters & Completion # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/pony regions add-highlighter shared/pony/code default-region group add-highlighter shared/pony/triple_string region '"""' '"""' fill string add-highlighter shared/pony/double_string region '"' (?' 0:type add-highlighter shared/pony/code/ regex '\b(${keywords})\b' 0:keyword add-highlighter shared/pony/code/ regex ';' 0:keyword add-highlighter shared/pony/code/ regex '^\s*|' 0:keyword add-highlighter shared/pony/code/ regex '\b(${struct})\b' 0:variable add-highlighter shared/pony/code/ regex '\b(${capabilities})\b(!|^)?' 1:builtin 2:builtin " # Highlight types and attributes printf %s " add-highlighter shared/pony/code/ regex '@[\w_]+\b' 0:attribute " } # Commands # ‾‾‾‾‾‾‾‾ define-command -hidden pony-indent-on-new-line %{ evaluate-commands -draft -itersel %{ # preserve previous line indent try %{ execute-keys -draft K } # cleanup trailing whitespaces from previous line try %{ execute-keys -draft k s \h+$ d } # copy '//' comment prefix and following white spaces # try %{ execute-keys -draft k x s ^\h*//\h* y jgh P } # indent after line ending with : try %{ execute-keys -draft k x (do|try|then|else|:|=>)$ j } # else, end are always de-indented try %{ execute-keys -draft k x (else|end):$ k x s ^\h* y j x ^" J } } } } kakoune-2019.07.01/rc/filetype/protobuf.kak000066400000000000000000000067361350637360100203450ustar00rootroot00000000000000# https://developers.google.com/protocol-buffers/ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*\.proto$ %{ set-option buffer filetype protobuf } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=protobuf %[ require-module protobuf set-option window static_words %opt{protobuf_static_words} hook -group protobuf-indent window InsertChar \n protobuf-indent-on-newline hook -group protobuf-indent window InsertChar \{ protobuf-indent-on-opening-curly-brace hook -group protobuf-indent window InsertChar \} protobuf-indent-on-closing-curly-brace hook -once -always window WinSetOption filetype=.* %{ remove-hooks window protobuf-.+ } ] hook -group protobuf-highlight global WinSetOption filetype=protobuf %{ add-highlighter window/protobuf ref protobuf hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/protobuf } } provide-module protobuf %[ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/protobuf regions add-highlighter shared/protobuf/code default-region group add-highlighter shared/protobuf/double_string region '"' (? } # indent after lines ending with { try %[ execute-keys -draft k \{\h*$ j ] # cleanup trailing white spaces on the previous line try %{ execute-keys -draft k s \h+$ d } # copy // comments prefix try %{ execute-keys -draft \;k s ^\h*\K/{2,}(\h*(?=\S))? yP } ] ~ define-command -hidden protobuf-indent-on-opening-curly-brace %[ # align indent with opening paren when { is entered on a new line after the closing paren try %[ execute-keys -draft -itersel h)M \A\(.*\)\h*\n\h*\{\z s \A|.\z 1 ] ] define-command -hidden protobuf-indent-on-closing-curly-brace %[ # align to opening curly brace when alone on a line try %[ execute-keys -itersel -draft ^\h+\}$hms\A|.\z1 ] ] ] kakoune-2019.07.01/rc/filetype/pug.kak000066400000000000000000000071671350637360100172770ustar00rootroot00000000000000# Note: jade is changing its name to pug (https://github.com/pugjs/pug/issues/2184) # This appears to be a work in progress -- the pug-lang domain is parked, while # the jade-lang one is active. This highlighter will recognize .pug and .jade extensions, # http://jade-lang.com (will be http://pug-lang.com) # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*[.](pug|jade) %{ set-option buffer filetype pug } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=pug %{ require-module pug hook window ModeChange insert:.* -group pug-trim-indent pug-trim-indent hook window InsertChar \n -group pug-indent pug-indent-on-new-line hook -once -always window WinSetOption filetype=.* %{ remove-hooks window pug-.+ } } hook -group pug-highlight global WinSetOption filetype=pug %{ add-highlighter window/pug ref pug hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/pug } } provide-module pug %{ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/pug regions add-highlighter shared/pug/code default-region group add-highlighter shared/pug/text region ^\h*\|\s $ regex \h*(\|) 1:meta add-highlighter shared/pug/text2 region '^\h*([A-Za-z][A-Za-z0-9_-]*)?(#[A-Za-z][A-Za-z0-9_-]*)?((?:\.[A-Za-z][A-Za-z0-9_-]*)*)?(? s \h+$ d } } define-command -hidden pug-indent-on-new-line %{ evaluate-commands -draft -itersel %{ # preserve previous line indent try %{ execute-keys -draft \; K } # filter previous line try %{ execute-keys -draft k : pug-trim-indent } # copy '//', '|', '-' or '(!)=' prefix and following whitespace try %{ execute-keys -draft k s ^\h*\K[/|!=-]{1,2}\h* y gh j P } # indent unless we copied something above try %{ execute-keys -draft b s \S g l } } } } kakoune-2019.07.01/rc/filetype/python.kak000066400000000000000000000176501350637360100200230ustar00rootroot00000000000000# http://python.org # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*[.](py) %{ set-option buffer filetype python } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=python %{ require-module python set-option window static_words %opt{python_static_words} hook window InsertChar \n -group python-indent python-indent-on-new-line # cleanup trailing whitespaces on current line insert end hook window ModeChange insert:.* -group python-trim-indent %{ try %{ execute-keys -draft \; s ^\h+$ d } } hook -once -always window WinSetOption filetype=.* %{ remove-hooks window python-.+ } } hook -group python-highlight global WinSetOption filetype=python %{ add-highlighter window/python ref python hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/python } } provide-module python %{ # Highlighters & Completion # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/python regions add-highlighter shared/python/code default-region group add-highlighter shared/python/docstring region -match-capture ("""|''') ("""|''') regions add-highlighter shared/python/double_string region '"' (?>> \K' '\z' ref python add-highlighter shared/python/docstring/ region '\.\.\. \K' '\z' ref python evaluate-commands %sh{ # Grammar values="True False None self inf" meta="import from" # attributes and methods list based on https://docs.python.org/3/reference/datamodel.html attributes="__annotations__ __closure__ __code__ __defaults__ __dict__ __doc__ __globals__ __kwdefaults__ __module__ __name__ __qualname__" methods="__abs__ __add__ __aenter__ __aexit__ __aiter__ __and__ __anext__ __await__ __bool__ __bytes__ __call__ __complex__ __contains__ __del__ __delattr__ __delete__ __delitem__ __dir__ __divmod__ __enter__ __eq__ __exit__ __float__ __floordiv__ __format__ __ge__ __get__ __getattr__ __getattribute__ __getitem__ __gt__ __hash__ __iadd__ __iand__ __ifloordiv__ __ilshift__ __imatmul__ __imod__ __imul__ __index__ __init__ __init_subclass__ __int__ __invert__ __ior__ __ipow__ __irshift__ __isub__ __iter__ __itruediv__ __ixor__ __le__ __len__ __length_hint__ __lshift__ __lt__ __matmul__ __missing__ __mod__ __mul__ __ne__ __neg__ __new__ __or__ __pos__ __pow__ __radd__ __rand__ __rdivmod__ __repr__ __reversed__ __rfloordiv__ __rlshift__ __rmatmul__ __rmod__ __rmul__ __ror__ __round__ __rpow__ __rrshift__ __rshift__ __rsub__ __rtruediv__ __rxor__ __set__ __setattr__ __setitem__ __set_name__ __slots__ __str__ __sub__ __truediv__ __xor__" # built-in exceptions https://docs.python.org/3/library/exceptions.html exceptions="ArithmeticError AssertionError AttributeError BaseException BlockingIOError BrokenPipeError BufferError BytesWarning ChildProcessError ConnectionAbortedError ConnectionError ConnectionRefusedError ConnectionResetError DeprecationWarning EOFError Exception FileExistsError FileNotFoundError FloatingPointError FutureWarning GeneratorExit ImportError ImportWarning IndentationError IndexError InterruptedError IsADirectoryError KeyboardInterrupt KeyError LookupError MemoryError ModuleNotFoundError NameError NotADirectoryError NotImplementedError OSError OverflowError PendingDeprecationWarning PermissionError ProcessLookupError RecursionError ReferenceError ResourceWarning RuntimeError RuntimeWarning StopAsyncIteration StopIteration SyntaxError SyntaxWarning SystemError SystemExit TabError TimeoutError TypeError UnboundLocalError UnicodeDecodeError UnicodeEncodeError UnicodeError UnicodeTranslateError UnicodeWarning UserWarning ValueError Warning ZeroDivisionError" # Keyword list is collected using `keyword.kwlist` from `keyword` keywords="and as assert async await break class continue def del elif else except exec finally for global if in is lambda nonlocal not or pass print raise return try while with yield" types="bool buffer bytearray bytes complex dict file float frozenset int list long memoryview object set str tuple unicode xrange" functions="abs all any ascii bin breakpoint callable chr classmethod compile complex delattr dict dir divmod enumerate eval exec filter format frozenset getattr globals hasattr hash help hex id __import__ input isinstance issubclass iter len locals map max memoryview min next oct open ord pow print property range repr reversed round setattr slice sorted staticmethod sum super type vars zip" join() { sep=$2; eval set -- $1; IFS="$sep"; echo "$*"; } # Add the language's grammar to the static completion list printf %s\\n "declare-option str-list python_static_words $(join "${values} ${meta} ${attributes} ${methods} ${exceptions} ${keywords} ${types} ${functions}" ' ')" # Highlight keywords printf %s " add-highlighter shared/python/code/ regex '\b($(join "${values}" '|'))\b' 0:value add-highlighter shared/python/code/ regex '\b($(join "${meta}" '|'))\b' 0:meta add-highlighter shared/python/code/ regex '\b($(join "${attribute}" '|'))\b' 0:attribute add-highlighter shared/python/code/ regex '\bdef\s+($(join "${methods}" '|'))\b' 1:function add-highlighter shared/python/code/ regex '\b($(join "${exceptions}" '|'))\b' 0:function add-highlighter shared/python/code/ regex '\b($(join "${keywords}" '|'))\b' 0:keyword add-highlighter shared/python/code/ regex '\b($(join "${functions}" '|'))\b\(' 1:builtin add-highlighter shared/python/code/ regex '\b($(join "${types}" '|'))\b' 0:type add-highlighter shared/python/code/ regex '@[\w_]+\b' 0:attribute " } add-highlighter shared/python/code/ regex (?<=[\w\s\d'"_])(<=|<<|>>|>=|<>|<|>|!=|==|\||\^|&|\+|-|\*\*|\*|//|/|%|~) 0:operator add-highlighter shared/python/code/ regex (?<=[\w\s\d'"_])((?!])=(?![=])|[+*-]=) 0:builtin # Commands # ‾‾‾‾‾‾‾‾ define-command -hidden python-indent-on-new-line %{ evaluate-commands -draft -itersel %{ # copy '#' comment prefix and following white spaces try %{ execute-keys -draft k s ^\h*#\h* y jgh P } # preserve previous line indent try %{ execute-keys -draft \; K } # cleanup trailing whitespaces from previous line try %{ execute-keys -draft k s \h+$ d } # indent after line ending with : try %{ execute-keys -draft k :$ j } } } } kakoune-2019.07.01/rc/filetype/r.kak000066400000000000000000000144261350637360100167410ustar00rootroot00000000000000# http://kakoune.org # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate (.*/)?(\.Rprofile|.*\.[rR]) %{ set-option buffer filetype r } # Highlighters & Completion # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/r regions add-highlighter shared/r/code default-region group add-highlighter shared/r/double_string region '"' (?])>|<=|>=|==|!=|!|&{1,2}|\|{1,2}|~|\?) 0:operator # Commands # ‾‾‾‾‾‾‾‾ define-command -hidden r-trim-indent %{ # remove the line if it's empty when leaving the insert mode try %{ execute-keys -draft 1s^(\h+)$ d } } define-command -hidden r-indent-on-newline %< evaluate-commands -draft -itersel %< execute-keys \; try %< # if previous line closed a paren (possibly followed by words and a comment), # copy indent of the opening paren line execute-keys -draft k 1s(\))(\h+\w+)*\h*(\;\h*)?(?:#[^\n]+)?\n\z mJ 1 > catch %< # else indent new lines with the same level as the previous one execute-keys -draft K > # remove previous empty lines resulting from the automatic indent try %< execute-keys -draft k ^\h+$ Hd > # indent after an opening brace or parenthesis at end of line try %< execute-keys -draft k s[{(]\h*$ j > # indent after a statement not followed by an opening brace try %< execute-keys -draft k s\)\h*(?:#[^\n]+)?\n\z \ mB \A\b(if|for|while)\b j > try %< execute-keys -draft k s \belse\b\h*(?:#[^\n]+)?\n\z \ j > # deindent after a single line statement end try %< execute-keys -draft K \;\h*(#[^\n]+)?$ \ K s\)(\h+\w+)*\h*(#[^\n]+)?\n([^\n]*\n){2}\z \ MB \A\b(if|for|while)\b 1 > try %< execute-keys -draft K \;\h*(#[^\n]+)?$ \ K s \belse\b\h*(?:#[^\n]+)?\n([^\n]*\n){2}\z \ 1 > # align to the opening parenthesis or opening brace (whichever is first) # on a previous line if its followed by text on the same line try %< evaluate-commands -draft %< # Go to opening parenthesis and opening brace, then select the most nested one try %< execute-keys [c [({],[)}] > # Validate selection and get first and last char execute-keys \A[{(](\h*\S+)+\n "(([^"]*"){2})* '(([^']*'){2})* L # Remove possibly incorrect indent from new line which was copied from previous line try %< execute-keys -draft s\h+ d > # Now indent and align that new line with the opening parenthesis/brace execute-keys 1 & > > > > define-command -hidden r-indent-on-opening-curly-brace %[ # align indent with opening paren when { is entered on a new line after the closing paren try %[ execute-keys -draft -itersel h)M \A\(.*\)\h*\n\h*\{\z 1 ] ] define-command -hidden r-indent-on-closing-curly-brace %[ # align to opening curly brace when alone on a line try %[ # in case open curly brace follows a closing paren, align indent with opening paren execute-keys -itersel -draft ^\h+\}$hm )M \A\(.*\)\h\{.*\}\z 1 ] catch %[ # otherwise align with open curly brace execute-keys -itersel -draft ^\h+\}$hm1 ] catch %[] ] define-command -hidden r-insert-on-newline %[ evaluate-commands -itersel -draft %[ execute-keys \; try %[ evaluate-commands -draft -save-regs '/"' %[ # copy the commenting prefix execute-keys -save-regs '' k 1s^\h*(#+\h*) y try %[ # if the previous comment isn't empty, create a new one execute-keys ^\h*#+\h*$ js^\h*P ] catch %[ # if there is no text in the previous comment, remove it completely execute-keys d ] ] ] ] ] # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook -group r-highlight global WinSetOption filetype=r %{ add-highlighter window/r ref r hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/r } } hook global WinSetOption filetype=r %~ hook window ModeChange insert:.* r-trim-indent hook window InsertChar \n r-insert-on-newline hook window InsertChar \n r-indent-on-newline hook window InsertChar \{ r-indent-on-opening-curly-brace hook window InsertChar \} r-indent-on-closing-curly-brace hook -once -always window WinSetOption filetype=.* %{ remove-hooks window r-.+ } ~ kakoune-2019.07.01/rc/filetype/ragel.kak000066400000000000000000000061051350637360100175650ustar00rootroot00000000000000# http://complang.org/ragel # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # ragel.kak does not try to detect host language. # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*[.](ragel|rl) %{ set-option buffer filetype ragel } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=ragel %{ require-module ragel hook window ModeChange insert:.* -group ragel-trim-indent ragel-trim-indent hook window InsertChar .* -group ragel-indent ragel-indent-on-char hook window InsertChar \n -group ragel-indent ragel-indent-on-new-line hook -once -always window WinSetOption filetype=.* %{ remove-hooks window ragel-.+ } } hook -group ragel-highlight global WinSetOption filetype=ragel %{ add-highlighter window/ragel ref ragel hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/ragel } } provide-module ragel %§ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/ragel regions add-highlighter shared/ragel/code default-region group add-highlighter shared/ragel/double_string region '"' (?' 0:variable add-highlighter shared/ragel/code/ regex :=|=>|->|:>|:>>|<: 0:operator add-highlighter shared/ragel/code/ regex \b(action|alnum|alpha|any|ascii|case|cntrl|contained|context|data|digit|empty|eof|err|error|exec|export|exports|extend|fblen|fbreak|fbuf|fc|fcall|fcurs|fentry|fexec|fgoto|fhold|first_final|fnext|fpc|fret|from|fstack|ftargs|graph|import|include|init|inwhen|lerr|lower|machine|nocs|noend|noerror|nofinal|noprefix|outwhen|postpop|prepush|print|punct|range|space|start|to|upper|when|write|xdigit|zlen)\b 0:keyword # Commands # ‾‾‾‾‾‾‾‾ define-command -hidden ragel-trim-indent %{ # remove trailing white spaces try %{ execute-keys -draft -itersel s \h+$ d } } define-command -hidden ragel-indent-on-char %< evaluate-commands -draft -itersel %< # align closer token to its opener when alone on a line try %< execute-keys -draft ^\h+[]})]$ m s \A|.\z 1 > try %< execute-keys -draft ^\h+ [*]$ [*]$ s \A|.\z 1 > > > define-command -hidden ragel-indent-on-new-line %< evaluate-commands -draft -itersel %< # copy _#_ comment prefix and following white spaces try %{ execute-keys -draft k s ^\h*\K#\h* y gh j P } # preserve previous line indent try %{ execute-keys -draft \; K } # filter previous line try %{ execute-keys -draft k : ragel-trim-indent } # indent after lines ending with opener token try %< execute-keys -draft k [[{(*]$ j > > > § kakoune-2019.07.01/rc/filetype/restructuredtext.kak000066400000000000000000000117071350637360100221370ustar00rootroot00000000000000# Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*[.](rst) %{ set-option buffer filetype restructuredtext } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=restructuredtext %{ require-module restructuredtext } hook -group restructuredtext-highlight global WinSetOption filetype=restructuredtext %{ add-highlighter window/restructuredtext ref restructuredtext hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/restructuredtext } } provide-module restructuredtext %{ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/restructuredtext regions add-highlighter shared/restructuredtext/content default-region group add-highlighter shared/restructuredtext/code region ::\h*\n ^[^\s] fill meta evaluate-commands %sh{ for ft in c cabal clojure coffee cpp css cucumber ddiff dockerfile \ fish gas go haml haskell html ini java javascript json \ julia kak kickstart latex lisp lua makefile moon objc \ perl pug python ragel ruby rust sass scala scss sh swift \ tupfile yaml; do if [ "$ft" = kak ]; then ref="kakrc"; else ref="$ft"; fi printf 'add-highlighter shared/restructuredtext/%s region %s %s ref %s\n' "$ft" '\.\.\h*'$ft'::\h*c\h*\n' '^\S' "$ref" done } # Setext-style header # Valid header characters: # # ! " $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~ add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(#{3,}\n)?[^\n]+\n(#{3,})$ 0:title add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(!{3,}\n)?[^\n]+\n(!{3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)("{3,}\n)?[^\n]+\n("{3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(\${3,}\n)?[^\n]+\n(\${3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(%{3,}\n)?[^\n]+\n(%{3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(&{3,}\n)?[^\n]+\n(&{3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)('{3,}\n)?[^\n]+\n('{3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(\({3,}\n)?[^\n]+\n(\({3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(\){3,}\n)?[^\n]+\n(\){3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(\*{3,}\n)?[^\n]+\n(\*{3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(\+{3,}\n)?[^\n]+\n(\+{3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(,{3,}\n)?[^\n]+\n(,{3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(-{3,}\n)?[^\n]+\n(-{3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(\.{3,}\n)?[^\n]+\n(\.{3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(/{3,}\n)?[^\n]+\n(/{3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(:{3,}\n)?[^\n]+\n(:{3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(\;{3,}\n)?[^\n]+\n(\;{3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(<{3,}\n)?[^\n]+\n(<{3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(={3,}\n)?[^\n]+\n(={3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(>{3,}\n)?[^\n]+\n(>{3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(\?{3,}\n)?[^\n]+\n(\?{3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(@{3,}\n)?[^\n]+\n(@{3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(\[{3,}\n)?[^\n]+\n(\[{3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(\\{3,}\n)?[^\n]+\n(\\{3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(\]{3,}\n)?[^\n]+\n(\]{3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(\^{3,}\n)?[^\n]+\n(\^{3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(_{3,}\n)?[^\n]+\n(_{3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(`{3,}\n)?[^\n]+\n(`{3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(\{{3,}\n)?[^\n]+\n(\{{3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(\|{3,}\n)?[^\n]+\n(\|{3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(\}{3,}\n)?[^\n]+\n(\}{3,})$ 0:header add-highlighter shared/restructuredtext/content/ regex (\A|\n\n)(~{3,}\n)?[^\n]+\n(~{3,})$ 0:header # Inline markup add-highlighter shared/restructuredtext/content/ regex [^*](\*\*([^\s*]|([^\s*][^*]*[^\s*]))\*\*)[^*] 1:bold add-highlighter shared/restructuredtext/content/ regex [^*](\*([^\s*]|([^\s*][^*]*[^\s*]))\*)[^*] 1:italic add-highlighter shared/restructuredtext/content/ regex [^`](``([^\s`]|([^\s`][^`]*[^\s`]))``)[^`] 1:mono } kakoune-2019.07.01/rc/filetype/ruby.kak000066400000000000000000000214531350637360100174570ustar00rootroot00000000000000# http://ruby-lang.org # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*(([.](rb))|(irbrc)|(pryrc)|(Brewfile)|(Capfile|[.]cap)|(Gemfile|[.]gemspec)|(Guardfile)|(Rakefile|[.]rake)|(Thorfile|[.]thor)|(Vagrantfile)) %{ set-option buffer filetype ruby } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=ruby %{ require-module ruby set-option window static_words %opt{ruby_static_words} hook window InsertChar .* -group ruby-indent ruby-indent-on-char hook window InsertChar \n -group ruby-indent ruby-indent-on-new-line hook window InsertChar \n -group ruby-insert ruby-insert-on-new-line alias window alt ruby-alternative-file hook -once -always window WinSetOption filetype=.* %{ remove-hooks window ruby-.+ unalias window alt ruby-alternative-file } } hook -group ruby-highlight global WinSetOption filetype=ruby %{ add-highlighter window/ruby ref ruby hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/ruby } } provide-module ruby %[ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/ruby regions add-highlighter shared/ruby/code default-region group add-highlighter shared/ruby/double_symbol region ':"' (? fill meta add-highlighter shared/ruby/heredoc region '<<[-~]?(?!self)(\w+)' '^\h*(\w+)$' fill string add-highlighter shared/ruby/division region '[\w\)\]](/|(\h+/\h+))' '\w' group # Help Kakoune to better detect /…/ literals # Regular expression flags are: i → ignore case, m → multi-lines, o → only interpolate #{} blocks once, x → extended mode (ignore white spaces) # Literals are: i → array of symbols, q → string, r → regular expression, s → symbol, w → array of words, x → capture shell result add-highlighter shared/ruby/double_string/ default-region fill string add-highlighter shared/ruby/double_string/interpolation region -recurse \{ \Q#{ \} fill meta add-highlighter shared/ruby/double_symbol/ default-region fill variable add-highlighter shared/ruby/double_symbol/interpolation region -recurse \{ \Q#{ \} fill meta add-highlighter shared/ruby/backtick/ default-region fill meta add-highlighter shared/ruby/backtick/interpolation region -recurse \{ \Q#{ \} fill meta add-highlighter shared/ruby/regex/ default-region fill meta add-highlighter shared/ruby/regex/interpolation region -recurse \{ \Q#{ \} fill meta evaluate-commands %sh{ # Grammar # Keywords are collected searching for keywords at # https://github.com/ruby/ruby/blob/trunk/parse.y keywords="alias|and|begin|break|case|class|def|defined|do|else|elsif|end" keywords="${keywords}|ensure|false|for|if|in|module|next|nil|not|or|private|protected|public|redo" keywords="${keywords}|rescue|retry|return|self|super|then|true|undef|unless|until|when|while|yield" attributes="attr_reader|attr_writer|attr_accessor" values="false|true|nil" meta="require|include|extend" # Add the language's grammar to the static completion list printf %s\\n "declare-option str-list ruby_static_words ${keywords} ${attributes} ${values} ${meta}" | tr '|' ' ' # Highlight keywords printf %s " add-highlighter shared/ruby/code/ regex \b(${keywords})\b 0:keyword add-highlighter shared/ruby/code/ regex \b(${attributes})\b 0:attribute add-highlighter shared/ruby/code/ regex \b(${values})\b 0:value add-highlighter shared/ruby/code/ regex \b(${meta})\b 0:meta " } add-highlighter shared/ruby/code/ regex \b(\w+:(?!:))|(:?(\$(-[0FIKWadilpvw]|["'`/~&+=!$*,:.\;<>?@\\])|(\$|@@?)\w+))|((?[=>]?|<((=>?)|<)?|[+\-]@?|\*\*?|===?|[/`%&!^|~]|(\w+[=?!]?)|(\[\]=?)))|([A-Z]\w*|^|\h)\K::(?=[A-Z]) 0:variable # Commands # ‾‾‾‾‾‾‾‾ define-command ruby-alternative-file -docstring 'Jump to the alternate file (implementation ↔ test)' %{ evaluate-commands %sh{ case $kak_buffile in *spec/*_spec.rb) altfile=$(eval echo $(echo $kak_buffile | sed s+spec/+'*'/+';'s/_spec//)) [ ! -f $altfile ] && echo "echo -markup '{Error}implementation file not found'" && exit ;; *test/*_test.rb) altfile=$(eval echo $(echo $kak_buffile | sed s+test/+'*'/+';'s/_test//)) [ ! -f $altfile ] && echo "echo -markup '{Error}implementation file not found'" && exit ;; *.rb) path=$kak_buffile dirs=$(while [ $path ]; do echo $path; path=${path%/*}; done | tail -n +2) for dir in $dirs; do altdir=$dir/spec && suffix=spec [ ! -d $altdir ] && altdir=$dir/test && suffix=test if [ -d $altdir ]; then altfile=$altdir/$(realpath $kak_buffile --relative-to $dir | sed s+[^/]'*'/++';'s/.rb$/_${suffix}.rb/) break fi done [ ! -d $altdir ] && echo "echo -markup '{Error}spec/ and test/ not found'" && exit ;; *) echo "echo -markup '{Error}alternative file not found'" && exit ;; esac echo "edit $altfile" }} define-command -hidden ruby-trim-indent %{ evaluate-commands -no-hooks -draft -itersel %{ execute-keys # remove trailing white spaces try %{ execute-keys -draft s \h + $ d } } } define-command -hidden ruby-indent-on-char %{ evaluate-commands -no-hooks -draft -itersel %{ # align middle and end structures to start try %{ execute-keys -draft ^ \h * (else|elsif) $ ^ \h * (if) s \A | \z ) } try %{ execute-keys -draft ^ \h * (when) $ ^ \h * (case) s \A | \z ) } try %{ execute-keys -draft ^ \h * (rescue) $ ^ \h * (begin) s \A | \z ) } try %{ execute-keys -draft ^ \h * (end) $ ^ \h * (begin|case|class|def|for|if|module|unless|until|while) s \A | \z ) } } } define-command -hidden ruby-indent-on-new-line %{ evaluate-commands -no-hooks -draft -itersel %{ # preserve previous line indent try %{ execute-keys -draft K } # filter previous line try %{ execute-keys -draft k : ruby-trim-indent } # indent after start structure try %{ execute-keys -draft k ^ \h * (begin|case|class|def|else|elsif|ensure|for|if|module|rescue|unless|until|when|while|.+\bdo$|.+\bdo\h\|.+(?=\|)) \b j } } } define-command -hidden ruby-insert-on-new-line %[ evaluate-commands -no-hooks -draft -itersel %[ # copy _#_ comment prefix and following white spaces try %{ execute-keys -draft k s '^\h*\K#\h*' y j \; P } # wisely add end structure evaluate-commands -save-regs x %[ try %{ execute-keys -draft k s ^ \h + \" x y } catch %{ reg x '' } try %[ evaluate-commands -draft %[ # Check if previous line opens a block execute-keys -draft k ^x(begin|case|class|def|for|if|module|unless|until|while|.+\bdo$|.+\bdo\h\|.+(?=\|))\b # Check that we do not already have an end for this indent level which is first set via `ruby-indent-on-new-line` hook execute-keys -draft }i J ^x(end|else|elsif|rescue)\b ] execute-keys -draft oxend # insert a new line with containing end ] ] ] ] ] kakoune-2019.07.01/rc/filetype/rust.kak000066400000000000000000000105531350637360100174720ustar00rootroot00000000000000# http://rust-lang.org # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*[.](rust|rs) %{ set-option buffer filetype rust } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=rust %[ require-module rust hook window ModeChange insert:.* -group rust-trim-indent rust-trim-indent hook window InsertChar \n -group rust-indent rust-indent-on-new-line hook window InsertChar \{ -group rust-indent rust-indent-on-opening-curly-brace hook window InsertChar [)}] -group rust-indent rust-indent-on-closing hook -once -always window WinSetOption filetype=.* %{ remove-hooks window rust-.+ } ] hook -group rust-highlight global WinSetOption filetype=rust %{ add-highlighter window/rust ref rust hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/rust } } # Configuration # ‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=rust %[ set window formatcmd 'rustfmt' ] provide-module rust %§ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/rust regions add-highlighter shared/rust/code default-region group add-highlighter shared/rust/string region %{(? s \h+$ d } } define-command -hidden rust-indent-on-new-line %~ evaluate-commands -draft -itersel %< # copy // comments prefix and following white spaces try %{ execute-keys -draft k s ^\h*\K//[!/]?\h* y gh j P } # preserve previous line indent try %{ execute-keys -draft \; K } # filter previous line try %{ execute-keys -draft k : rust-trim-indent } # indent after lines ending with { or ( try %[ execute-keys -draft k [{(]\h*$ j ] # indent after lines ending with [{(].+ and move first parameter to own line try %< execute-keys -draft [c[({],[)}] \A[({][^\n]+\n[^\n]*\n?\z L i > > ~ define-command -hidden rust-indent-on-opening-curly-brace %[ evaluate-commands -draft -itersel %_ # align indent with opening paren when { is entered on a new line after the closing paren try %[ execute-keys -draft h ) M \A\(.*\)\h*\n\h*\{\z s \A|.\z 1 ] _ ] define-command -hidden rust-indent-on-closing %[ evaluate-commands -draft -itersel %_ # align to opening curly brace or paren when alone on a line try %< execute-keys -draft ^\h*[)}]$ h m 1 > _ ] § kakoune-2019.07.01/rc/filetype/sass.kak000066400000000000000000000045631350637360100174520ustar00rootroot00000000000000# http://sass-lang.com # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*[.](sass) %{ set-option buffer filetype sass } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=sass %{ require-module sass hook window ModeChange insert:.* -group sass-trim-indent sass-trim-indent hook window InsertChar \n -group sass-indent sass-indent-on-new-line set-option buffer extra_word_chars '_' '-' hook -once -always window WinSetOption filetype=.* %{ remove-hooks window sass-.+ } } hook -group sass-highlight global WinSetOption filetype=sass %{ add-highlighter window/sass ref sass hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/sass } } provide-module sass %{ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/sass regions add-highlighter shared/sass/code default-region group add-highlighter shared/sass/single_string region '"' (? s \h+$ d } } define-command -hidden sass-indent-on-new-line %{ evaluate-commands -draft -itersel %{ # copy '/' comment prefix and following white spaces try %{ execute-keys -draft k s ^\h*\K/\h* y gh j P } # preserve previous line indent try %{ execute-keys -draft \; K } # filter previous line try %{ execute-keys -draft k : sass-trim-indent } # avoid indent after properties and comments try %{ execute-keys -draft k [:/] j } } } } kakoune-2019.07.01/rc/filetype/scala.kak000066400000000000000000000064051350637360100175610ustar00rootroot00000000000000# http://scala-lang.org # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*[.](scala) %{ set-option buffer filetype scala } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=scala %[ require-module scala hook window ModeChange insert:.* -group scala-trim-indent scala-trim-indent hook window InsertChar \n -group scala-indent scala-indent-on-new-line hook window InsertChar \} -group scala-indent scala-indent-on-closing-curly-brace hook -once -always window WinSetOption filetype=.* %{ remove-hooks window scala-.+ } ] hook -group scala-highlight global WinSetOption filetype=scala %{ add-highlighter window/scala ref scala hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/scala } } provide-module scala %[ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/scala regions add-highlighter shared/scala/code default-region group add-highlighter shared/scala/string region '"' (?|<:|:>|=:=|::|&&|\|\|) 0:operator # Commands # ‾‾‾‾‾‾‾‾ define-command -hidden scala-trim-indent %{ # remove trailing white spaces try %{ execute-keys -draft -itersel s \h+$ d } } define-command -hidden scala-indent-on-new-line %[ evaluate-commands -draft -itersel %[ # copy // comments prefix and following white spaces try %[ execute-keys -draft k s ^\h*\K#\h* y gh j P ] # preserve previous line indent try %[ execute-keys -draft \; K ] # filter previous line try %[ execute-keys -draft k : scala-trim-indent ] # indent after lines ending with { try %[ execute-keys -draft k \{$ j ] ] ] define-command -hidden scala-indent-on-closing-curly-brace %[ evaluate-commands -draft -itersel %[ # align to opening curly brace when alone on a line try %[ execute-keys -draft ^\h+\}$ m s \A|.\z 1 ] ] ] ] kakoune-2019.07.01/rc/filetype/scheme.kak000066400000000000000000000142431350637360100177410ustar00rootroot00000000000000# http://www.scheme-reports.org # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate (.*/)?(.*\.(scm|ss|sld)) %{ set-option buffer filetype scheme } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=scheme %{ require-module scheme set-option window static_words %opt{scheme_static_words} set-option buffer extra_word_chars '_' '-' '!' '%' '?' '<' '>' '=' hook window InsertEnd .* -group scheme-trim-indent lisp-trim-indent hook window InsertChar \n -group scheme-indent lisp-indent-on-new-line hook -once -always window WinSetOption filetype=.* %{ remove-hooks window scheme-.+ } } hook -group scheme-highlight global WinSetOption filetype=scheme %{ add-highlighter window/scheme ref scheme hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/scheme } } provide-module scheme %{ require-module lisp # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/scheme regions add-highlighter shared/scheme/code default-region group add-highlighter shared/scheme/string region '"' (? > >=", operators); # Procedures that create a base type and their predicates (for easier type checking) split("list vector bytevector cons string boolean? list? pair? "\ "vector? bytevector? string? char? complex? eof-object? input-port? "\ "null? number? output-port? procedure? symbol?", types); # R5RS available procedures split("abs acos angle append apply asin assoc assq assv atan "\ "caaaar caaadr caaar caadar caaddr caadr "\ "caar cadaar cadadr cadar caddar cadddr caddr cadr "\ "call-with-current-continuation call-with-input-file "\ "call-with-output-file call-with-values car cdaaar cdaadr cdaar "\ "cdadar cdaddr cdadr cdar cddaar cddadr cddar cdddar cddddr cdddr "\ "cddr cdr ceiling char->integer char-alphabetic? char-ci<=? "\ "char-ci=? char-ci>? char-downcase "\ "char-lower-case? char-numeric? char-ready? char-upcase "\ "char-upper-case? char-whitespace? char<=? char=? char>? close-input-port close-output-port cons cos "\ "current-input-port current-output-port denominator display "\ "dynamic-wind else eq? equal? eqv? eval even? exact->inexact "\ "exact? exp expt floor for-each force gcd imag-part inexact->exact "\ "inexact? integer->char integer? interaction-environment lcm "\ "length list list->string list->vector list-ref list-tail load log "\ "magnitude make-polar make-rectangular make-string make-vector "\ "map max member memq memv min modulo negative? newline not "\ "null-environment number->string numerator odd? open-input-file "\ "open-output-file or peek-char positive? quasiquote quote quotient "\ "rational? rationalize read read-char real-part real? remainder "\ "reverse round scheme-report-environment set-car! set-cdr! sin "\ "sqrt string->list string->number string->symbol string-append "\ "string-ci<=? string-ci=? "\ "string-ci>? string-copy string-fill! string-length string-ref "\ "string-set! string<=? string=? string>? "\ "substring symbol->string tan truncate values vector "\ "vector->list vector-fill! vector-length vector-ref vector-set! "\ "with-input-from-file with-output-to-file write write-char zero?", builtins); non_word_chars="[\\s\\(\\)\\[\\]\\{\\};\\|]"; normal_identifiers="-!$%&\\*\\+\\./:<=>\\?\\^_~a-zA-Z0-9"; identifier_chars="[" normal_identifiers "][" normal_identifiers ",#]*"; } function add_highlighter(regex, highlight) { printf("add-highlighter shared/scheme/code/ regex \"%s\" %s\n", regex, highlight); } function quoted_join(words, quoted, first) { first=1 for (i in words) { if (!first) { quoted=quoted "|"; } quoted=quoted "\\Q" words[i] "\\E"; first=0; } return quoted; } function add_word_highlighter(words, face, regex) { regex = non_word_chars "+(" quoted_join(words) ")" non_word_chars add_highlighter(regex, "1:" face) } function print_words(words) { for (i in words) { printf(" %s", words[i]); } } BEGIN { printf("declare-option str-list scheme_static_words "); print_words(keywords); print_words(meta); print_words(operators); print_words(builtins); printf("\n"); add_word_highlighter(keywords, "keyword"); add_word_highlighter(meta, "meta"); add_word_highlighter(operators, "operator"); add_word_highlighter(builtins, "builtin"); add_word_highlighter(types, "type"); add_highlighter(non_word_chars "+('" identifier_chars ")", "1:attribute"); add_highlighter("\\(define\\W+\\((" identifier_chars ")", "1:function"); add_highlighter("\\(define\\W+(" identifier_chars ")\\W+\\(lambda", "1:function"); } EOF } } kakoune-2019.07.01/rc/filetype/scss.kak000066400000000000000000000030201350637360100174370ustar00rootroot00000000000000# http://sass-lang.com # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*[.](scss) %{ set-option buffer filetype scss } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=scss %[ require-module scss hook window ModeChange insert:.* -group scss-trim-indent scss-trim-indent hook window InsertChar \n -group scss-indent scss-indent-on-new-line hook window InsertChar \} -group scss-indent scss-indent-on-closing-curly-brace set-option buffer extra_word_chars '_' '-' hook -once -always window WinSetOption filetype=.* %{ remove-hooks window scss-.+ } ] hook -group scss-highlight global WinSetOption filetype=scss %{ add-highlighter window/scss ref scss hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/scss } } provide-module scss %[ require-module css # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/scss regions add-highlighter shared/scss/core default-region group add-highlighter shared/scss/comment region // $ fill comment add-highlighter shared/scss/core/ ref css add-highlighter shared/scss/core/ regex @[A-Za-z][A-Za-z0-9_-]* 0:meta # Commands # ‾‾‾‾‾‾‾‾ define-command -hidden scss-trim-indent css-trim-indent define-command -hidden scss-indent-on-new-line css-indent-on-new-line define-command -hidden scss-indent-on-closing-curly-brace css-indent-on-closing-curly-brace ] kakoune-2019.07.01/rc/filetype/sh.kak000066400000000000000000000146521350637360100171130ustar00rootroot00000000000000hook global BufCreate .*\.(z|ba|c|k|mk)?sh(rc|_profile)? %{ set-option buffer filetype sh } hook global WinSetOption filetype=sh %{ require-module sh set-option window static_words %opt{sh_static_words} hook window ModeChange insert:.* -group sh-trim-indent sh-trim-indent hook window InsertChar \n -group sh-indent sh-indent-on-new-line hook -once -always window WinSetOption filetype=.* %{ remove-hooks window sh-.+ } } hook -group sh-highlight global WinSetOption filetype=sh %{ add-highlighter window/sh ref sh hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/sh } } provide-module sh %[ add-highlighter shared/sh regions add-highlighter shared/sh/code default-region group add-highlighter shared/sh/double_string region %{(? s \h+$ d } } # This is at best an approximation, since shell syntax is very complex. # Also note that this targets plain sh syntax, not bash - bash adds a whole # other level of complexity. If your bash code is fairly portable this will # probably work. # # Of necessity, this is also fairly opinionated about indentation styles. # Doing it "properly" would require far more context awareness than we can # bring to this kind of thing. define-command -hidden sh-indent-on-new-line %[ evaluate-commands -draft -itersel %[ # copy '#' comment prefix and following white spaces try %{ execute-keys -draft k s ^\h*\K#\h* y gh j P } # preserve previous line indent try %{ execute-keys -draft \; K } # filter previous line try %{ execute-keys -draft k : sh-trim-indent } # Indent loop syntax, e.g.: # for foo in bar; do # things # done # # or: # # while foo; do # things # done # # or equivalently: # # while foo # do # things # done # # indent after do try %{ execute-keys -draft k do$ j } # deindent after done try %{ execute-keys -draft k done$ j K } # Indent if/then/else syntax, e.g.: # if [ $foo = $bar ]; then # things # else # other_things # fi # # or equivalently: # if [ $foo = $bar ] # then # things # else # other_things # fi # # indent after then try %{ execute-keys -draft k then$ j } # deindent after fi try %{ execute-keys -draft k fi$ j K } # deindent and reindent after else - deindent the else, then back # down and return to the previous indent level. try %{ execute-keys -draft k else$ j } # Indent case syntax, e.g.: # case "$foo" in # bar) thing1;; # baz) # things # ;; # *) # default_things # ;; # esac # # or equivalently: # case "$foo" # in # bar) thing1;; # esac # # indent after in try %{ execute-keys -draft k in$ j } # deindent after esac try %{ execute-keys -draft k esac$ j K } # indent after ) try %{ execute-keys -draft k ^\s*\(?[^(]+[^)]\)$ j } # deindent after ;; try %{ execute-keys -draft k ^\s*\;\;$ j } # Indent compound commands as logical blocks, e.g.: # { # thing1 # thing2 # } # # or in a function definition: # foo () { # thing1 # thing2 # } # # We don't handle () delimited compond commands - these are technically very # similar, but the use cases are quite different and much less common. # # Note that in this context the '{' and '}' characters are reserved # words, and hence must be surrounded by a token separator - typically # white space (including a newline), though technically it can also be # ';'. Only vertical white space makes sense in this context, though, # since the syntax denotes a logical block, not a simple compound command. try %= execute-keys -draft k (\s|^)\{$ j = # deindent closing } try %= execute-keys -draft k ^\s*\}$ j K = ] ] ] kakoune-2019.07.01/rc/filetype/sql.kak000066400000000000000000000143451350637360100172770ustar00rootroot00000000000000# https://www.w3schools.com/sql/default.asp # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*/?(?i)sql %{ set-option buffer filetype sql } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=sql %{ require-module sql set-option window static_words %opt{sql_static_words} } hook -group sql-highlight global WinSetOption filetype=sql %{ add-highlighter window/sql ref sql hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/sql } } provide-module sql %{ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/sql regions add-highlighter shared/sql/code default-region group add-highlighter shared/sql/double_string region '"' (?|<|>=|<=|<>|\+=|-=|\*=|/=|%=|&=|^-=|\|\*=' 0:operator add-highlighter shared/sql/code/ regex \bNULL\b 0:value add-highlighter shared/sql/code/ regex \b\d+(?:\.\d+)?\b 0:value } kakoune-2019.07.01/rc/filetype/swift.kak000066400000000000000000000034651350637360100176350ustar00rootroot00000000000000hook global BufCreate .*\.(swift) %{ set-option buffer filetype swift } hook global WinSetOption filetype=swift %{ require-module swift } hook -group swift-highlight global WinSetOption filetype=swift %{ add-highlighter window/swift ref swift hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/swift } } provide-module swift %{ add-highlighter shared/swift regions add-highlighter shared/swift/code default-region group add-highlighter shared/swift/string region %{(? } ## If the line above is a project indent with a tab try %{ execute-keys -draft Z k ^\h*([^:\n]+): z i } # cleanup trailing white spaces on previous line try %{ execute-keys -draft k s \h+$ d } } } } kakoune-2019.07.01/rc/filetype/toml.kak000066400000000000000000000046111350637360100174460ustar00rootroot00000000000000# https://github.com/toml-lang/toml/tree/v0.4.0 # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*\.(toml) %{ set-option buffer filetype toml } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=toml %{ require-module toml hook window ModeChange insert:.* -group toml-trim-indent toml-trim-indent hook window InsertChar \n -group toml-indent toml-indent-on-new-line hook -once -always window WinSetOption filetype=.* %{ remove-hooks window toml-.+ } } hook -group toml-highlight global WinSetOption filetype=toml %{ add-highlighter window/toml ref toml hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/toml } } provide-module toml %{ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/toml regions add-highlighter shared/toml/code default-region group add-highlighter shared/toml/comment region '#' $ fill comment add-highlighter shared/toml/string1 region '"""' (? s \h+$ d } } define-command -hidden toml-indent-on-new-line %{ evaluate-commands -draft -itersel %{ # copy comment prefix and following white spaces try %{ execute-keys -draft k s ^\h*\K#\h* y gh j P } # preserve previous line indent try %{ execute-keys -draft \; K } # filter previous line try %{ execute-keys -draft k : toml-trim-indent } } } } kakoune-2019.07.01/rc/filetype/troff.kak000066400000000000000000000022251350637360100176120ustar00rootroot00000000000000# Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*\.\d+ %{ set-option buffer filetype troff } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=troff %{ require-module troff } hook -group troff-highlight global WinSetOption filetype=troff %{ add-highlighter window/troff ref troff hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/troff } } provide-module troff %{ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/troff group add-highlighter shared/troff/ regex '\\f[A-Z]' 0:attribute add-highlighter shared/troff/ regex '\\fB(.+?)\\f[A-Z]' 1:+b add-highlighter shared/troff/ regex '\\fI(.+?)\\f[A-Z]' 1:+i add-highlighter shared/troff/ regex '^\.[a-zA-Z]{1,2}\b' 0:meta add-highlighter shared/troff/ regex '^\.TH\s+[^\n]+' 0:title add-highlighter shared/troff/ regex '^\.SH\s+[^\n]+' 0:header add-highlighter shared/troff/ regex '^\.IR\s+(\S+)' 1:+i add-highlighter shared/troff/ regex '^\.BR\s+(\S+)' 1:+b add-highlighter shared/troff/ regex '^\.I\s+([^\n]+)' 1:+i add-highlighter shared/troff/ regex '^\.B\s+([^\n]+)' 1:+b } kakoune-2019.07.01/rc/filetype/tupfile.kak000066400000000000000000000025231350637360100201430ustar00rootroot00000000000000# http://gittup.org/tup/ # # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*/?Tup(file|rules)(\.\w+)?$ %{ set-option buffer filetype tupfile } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook -group tupfile-highlight global WinSetOption filetype=tupfile %{ require-module tupfile add-highlighter window/tupfile ref tupfile hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/tupfile } } provide-module tupfile %{ # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/tupfile regions add-highlighter shared/tupfile/code default-region group add-highlighter shared/tupfile/string region '"' (? s \h+$ d } } define-command -hidden yaml-indent-on-new-line %{ evaluate-commands -draft -itersel %{ # copy '#' comment prefix and following white spaces try %{ execute-keys -draft k s ^\h*\K#\h* y gh j P } # preserve previous line indent try %{ execute-keys -draft \; K } # filter previous line try %{ execute-keys -draft k : yaml-trim-indent } # indent after : try %{ execute-keys -draft k x :$ j } } } } kakoune-2019.07.01/rc/tools/000077500000000000000000000000001350637360100153205ustar00rootroot00000000000000kakoune-2019.07.01/rc/tools/autorestore.kak000066400000000000000000000054121350637360100203660ustar00rootroot00000000000000declare-option -docstring "remove backups once they've been restored" \ bool autorestore_purge_restored true ## Insert the content of the backup file into the current buffer, if a suitable one is found define-command autorestore-restore-buffer -docstring "Restore the backup for the current file if it exists" %{ evaluate-commands %sh{ buffer_basename="${kak_buffile##*/}" buffer_dirname=$(dirname "${kak_buffile}") if [ -f "${kak_buffile}" ]; then newer=$(find "${buffer_dirname}"/".${buffer_basename}.kak."* -newer "${kak_buffile}" -exec ls -1t {} + 2>/dev/null | head -n 1) older=$(find "${buffer_dirname}"/".${buffer_basename}.kak."* \! -newer "${kak_buffile}" -exec ls -1t {} + 2>/dev/null | head -n 1) else # New buffers that were never written to disk. newer=$(ls -1t "${buffer_dirname}"/".${buffer_basename}.kak."* 2>/dev/null | head -n 1) fi if [ -z "${newer}" ]; then if [ -n "${older}" ]; then printf %s\\n " echo -debug Old backup file(s) found: will not restore ${older} . " fi exit fi printf %s\\n " ## Replace the content of the buffer with the content of the backup file echo -debug Restoring file: ${newer} execute-keys -draft %{ %d!cat\"${newer}\"d } ## If the backup file has to be removed, issue the command once ## the current buffer has been saved ## If the autorestore_purge_restored option has been unset right after the ## buffer was restored, do not remove the backup hook -group autorestore buffer BufWritePost '${kak_buffile}' %{ nop %sh{ if [ \"\${kak_opt_autorestore_purge_restored}\" = true ]; then rm -f \"${buffer_dirname}/.${buffer_basename}.kak.\"* fi } } " } } ## Remove all the backups that have been created for the current buffer define-command autorestore-purge-backups -docstring "Remove all the backups of the current buffer" %{ evaluate-commands %sh{ [ ! -f "${kak_buffile}" ] && exit buffer_basename="${kak_bufname##*/}" buffer_dirname=$(dirname "${kak_bufname}") rm -f "${buffer_dirname}/.${buffer_basename}.kak."* printf %s\\n " echo -markup {Information}Backup files removed. " } } ## If for some reason, backup files need to be ignored define-command autorestore-disable -docstring "Disable automatic backup recovering" %{ remove-hooks global autorestore } hook -group autorestore global BufCreate .* %{ autorestore-restore-buffer } kakoune-2019.07.01/rc/tools/autowrap.kak000066400000000000000000000042521350637360100176550ustar00rootroot00000000000000declare-option -docstring "maximum amount of characters per line, after which a newline character will be inserted" \ int autowrap_column 80 declare-option -docstring %{when enabled, paragraph formatting will reformat the whole paragraph in which characters are being inserted This can potentially break formatting of documents containing markup (e.g. markdown)} \ bool autowrap_format_paragraph no declare-option -docstring %{command to which the paragraphs to wrap will be passed all occurences of '%c' are replaced with `autowrap_column`} \ str autowrap_fmtcmd 'fold -s -w %c' define-command -hidden autowrap-cursor %{ evaluate-commands -save-regs '/"|^@m' %{ try %{ ## if the line isn't too long, do nothing execute-keys -draft "^[^\n]{%opt{autowrap_column},}[^\n]" try %{ reg m "%val{selections_desc}" ## if we're adding characters past the limit, just wrap them around execute-keys -draft ".{%opt{autowrap_column}}\h*[^\s]*1s(\h+)[^\h]*\zc" } catch %{ ## if we're adding characters in the middle of a sentence, use ## the `fmtcmd` command to wrap the entire paragraph evaluate-commands %sh{ if [ "${kak_opt_autowrap_format_paragraph}" = true ] \ && [ -n "${kak_opt_autowrap_fmtcmd}" ]; then format_cmd=$(printf %s "${kak_opt_autowrap_fmtcmd}" \ | sed "s/%c/${kak_opt_autowrap_column}/g") printf %s " evaluate-commands -draft %{ execute-keys 'p|${format_cmd}' try %{ execute-keys s\h+$ d } } select '${kak_main_reg_m}' " fi } } } } } define-command autowrap-enable -docstring "Automatically wrap the lines in which characters are inserted" %{ hook -group autowrap window InsertChar [^\n] autowrap-cursor } define-command autowrap-disable -docstring "Disable automatic line wrapping" %{ remove-hooks window autowrap } kakoune-2019.07.01/rc/tools/clang.kak000066400000000000000000000212021350637360100170710ustar00rootroot00000000000000hook -once global BufSetOption filetype=(c|cpp) %{ require-module clang } provide-module clang %[ declare-option -docstring "options to pass to the `clang` shell command" \ str clang_options declare-option -hidden str clang_tmp_dir declare-option -hidden completions clang_completions declare-option -hidden line-specs clang_flags declare-option -hidden line-specs clang_errors define-command -params ..1 \ -docstring %{Parse the contents of the current buffer The syntaxic errors detected during parsing are shown when auto-diagnostics are enabled} \ clang-parse %{ evaluate-commands %sh{ dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-clang.XXXXXXXX) mkfifo ${dir}/fifo printf %s\\n "set-option buffer clang_tmp_dir ${dir}" printf %s\\n "evaluate-commands -no-hooks write -sync ${dir}/buf" } # end the previous %sh{} so that its output gets interpreted by kakoune # before launching the following as a background task. evaluate-commands %sh{ dir=${kak_opt_clang_tmp_dir} printf %s\\n "evaluate-commands -draft %{ edit! -fifo ${dir}/fifo -debug *clang-output* set-option buffer filetype make set-option buffer make_current_error_line 0 hook -once -always buffer BufCloseFifo .* %{ nop %sh{ rm -r ${dir} } } }" # this runs in a detached shell, asynchronously, so that kakoune does # not hang while clang is running. As completions references a cursor # position and a buffer timestamp, only valid completions should be # displayed. ( case ${kak_opt_filetype} in c) ft=c ;; cpp) ft=c++ ;; obj-c) ft=objective-c ;; *) ft=c++ ;; esac if [ "$1" = "-complete" ]; then pos=-:${kak_cursor_line}:${kak_cursor_column} header="${kak_cursor_line}.${kak_cursor_column}@${kak_timestamp}" compl=$(clang++ -x ${ft} -fsyntax-only ${kak_opt_clang_options} \ -Xclang -code-completion-brief-comments -Xclang -code-completion-at=${pos} - < ${dir}/buf 2> ${dir}/stderr | awk -F ': ' ' /^COMPLETION:/ && ! /\(Hidden\)/ { id=$2 gsub(/ +$/, "", id) gsub(/~/, "~~", id) gsub(/\|/, "\\|", id) gsub(/[[{<]#|#[}>]/, "", $3) gsub(/#]/, " ", $3) gsub(/:: /, "::", $3) gsub(/ +$/, "", $3) desc=$4 ? $3 "\n" $4 : $3 gsub(/~/, "~~", desc) gsub(/!/, "!!", desc) gsub(/\|/, "\\|", desc) if (id in docstrings) docstrings[id]=docstrings[id] "\n" desc else docstrings[id]=desc } END { for (id in docstrings) { menu=id gsub(/(^|[^[:alnum:]_])(operator|new|delete)($|[^{}_[:alnum:]]+)/, "{keyword}&{}", menu) gsub(/(^|[[:space:]])(int|size_t|bool|char|unsigned|signed|long)($|[[:space:]])/, "{type}&{}", menu) gsub(/[^{}_[:alnum:]]+/, "{operator}&{}", menu) printf "%%~%s|info -style menu %!%s!|%s~ ", id, docstrings[id], menu } }') printf %s\\n "evaluate-commands -client ${kak_client} echo 'clang completion done' set-option 'buffer=${kak_buffile}' clang_completions ${header} ${compl}" | kak -p ${kak_session} else clang++ -x ${ft} -fsyntax-only ${kak_opt_clang_options} - < ${dir}/buf 2> ${dir}/stderr printf %s\\n "evaluate-commands -client ${kak_client} echo 'clang parsing done'" | kak -p ${kak_session} fi flags=$(cat ${dir}/stderr | sed -rne " /^:[0-9]+:([0-9]+:)? (fatal )?error/ { s/^:([0-9]+):.*/'\1|{red}█'/; p } /^:[0-9]+:([0-9]+:)? warning/ { s/^:([0-9]+):.*/'\1|{yellow}█'/; p } " | paste -s -d ' ' -) errors=$(cat ${dir}/stderr | sed -rne " /^:[0-9]+:([0-9]+:)? ((fatal )?error|warning)/ { s/'/''/g; s/^:([0-9]+):([0-9]+:)? (.*)/'\1|\3'/; p }" | sort -n | paste -s -d ' ' -) sed -e "s||${kak_bufname}|g" < ${dir}/stderr > ${dir}/fifo printf %s\\n "set-option 'buffer=${kak_buffile}' clang_flags ${kak_timestamp} ${flags} set-option 'buffer=${kak_buffile}' clang_errors ${kak_timestamp} ${errors}" | kak -p ${kak_session} ) > /dev/null 2>&1 < /dev/null & } } define-command clang-complete -docstring "Complete the current selection" %{ clang-parse -complete } define-command -hidden clang-show-completion-info %[ try %[ evaluate-commands -draft %[ execute-keys {( ^\( b \A\w+\z evaluate-commands %sh[ desc=$(printf %s\\n "${kak_opt_clang_completions}" | sed -e "{ s/\([^\\]\):/\1\n/g }" | sed -ne "/^${kak_selection}|/ { s/^[^|]\+|//; s/|.*$//; s/\\\:/:/g; p }") if [ -n "$desc" ]; then printf %s\\n "evaluate-commands -client $kak_client %{info -anchor ${kak_cursor_line}.${kak_cursor_column} -style above %{${desc}}}" fi ] ] ] ] define-command clang-enable-autocomplete -docstring "Enable automatic clang completion" %{ set-option window completers "option=clang_completions" %opt{completers} hook window -group clang-autocomplete InsertIdle .* %{ try %{ execute-keys -draft (\.|->|::).\z echo 'completing...' clang-complete } clang-show-completion-info } alias window complete clang-complete } define-command clang-disable-autocomplete -docstring "Disable automatic clang completion" %{ evaluate-commands %sh{ printf "set-option window completers %s\n" $(printf %s "${kak_opt_completers}" | sed -e "s/'option=clang_completions'//g") } remove-hooks window clang-autocomplete unalias window complete clang-complete } define-command -hidden clang-show-error-info %{ update-option buffer clang_errors # Ensure we are up to date with buffer changes evaluate-commands %sh{ eval "set -- ${kak_quoted_opt_clang_errors}" shift # skip timestamp desc=$(for error in "$@"; do if [ "${error%%|*}" = "$kak_cursor_line" ]; then printf '%s\n' "${error##*|}" fi done) if [ -n "$desc" ]; then desc=$(printf %s "${desc}" | sed "s/'/''/g") printf "info -anchor %d.%d '%s'\n" "${kak_cursor_line}" "${kak_cursor_column}" "${desc}" fi } } define-command clang-enable-diagnostics -docstring %{Activate automatic error reporting and diagnostics Information about the analysis are showned after the buffer has been parsed with the clang-parse function} \ %{ add-highlighter window/clang_flags flag-lines default clang_flags hook window -group clang-diagnostics NormalIdle .* %{ clang-show-error-info } hook window -group clang-diagnostics WinSetOption ^clang_errors=.* %{ info; clang-show-error-info } } define-command clang-disable-diagnostics -docstring "Disable automatic error reporting and diagnostics" %{ remove-highlighter window/clang_flags remove-hooks window clang-diagnostics } define-command clang-diagnostics-next -docstring "Jump to the next line that contains an error" %{ update-option buffer clang_errors # Ensure we are up to date with buffer changes evaluate-commands %sh{ eval "set -- ${kak_quoted_opt_clang_errors}" shift # skip timestamp for error in "$@"; do candidate=${error%%|*} first_line=${first_line-$candidate} if [ "$candidate" -gt $kak_cursor_line ]; then line=$candidate break fi done line=${line-$first_line} if [ -n "$line" ]; then printf %s\\n "execute-keys ${line} g" else echo "echo -markup '{Error}no next clang diagnostic'" fi } } ] kakoune-2019.07.01/rc/tools/comment.kak000066400000000000000000000134121350637360100174530ustar00rootroot00000000000000# Line comments declare-option -docstring "characters inserted at the beginning of a commented line" \ str comment_line '#' # Block comments declare-option -docstring "characters inserted before a commented block" \ str comment_block_begin declare-option -docstring "characters inserted after a commented block" \ str comment_block_end # Default comments for all languages hook global BufSetOption filetype=asciidoc %{ set-option buffer comment_block_begin '///' set-option buffer comment_block_end '///' } hook global BufSetOption filetype=(c|cpp|dart|go|java|javascript|objc|php|rust|sass|scala|scss|swift|typescript) %{ set-option buffer comment_line '//' set-option buffer comment_block_begin '/*' set-option buffer comment_block_end '*/' } hook global BufSetOption filetype=(cabal|haskell|moon|idris|elm) %{ set-option buffer comment_line '--' set-option buffer comment_block_begin '{-' set-option buffer comment_block_end '-}' } hook global BufSetOption filetype=clojure %{ set-option buffer comment_line '#_' set-option buffer comment_block_begin '(comment ' set-option buffer comment_block_end ')' } hook global BufSetOption filetype=coffee %{ set-option buffer comment_block_begin '###' set-option buffer comment_block_end '###' } hook global BufSetOption filetype=css %{ set-option buffer comment_line '' set-option buffer comment_block_begin '/*' set-option buffer comment_block_end '*/' } hook global BufSetOption filetype=d %{ set-option buffer comment_line '//' set-option buffer comment_block_begin '/+' set-option buffer comment_block_end '+/' } hook global BufSetOption filetype=(gas|ini) %{ set-option buffer comment_line ';' } hook global BufSetOption filetype=haml %{ set-option buffer comment_line '-#' } hook global BufSetOption filetype=(html|xml) %{ set-option buffer comment_line '' set-option buffer comment_block_begin '' } hook global BufSetOption filetype=latex %{ set-option buffer comment_line '%' } hook global BufSetOption filetype=lisp %{ set-option buffer comment_line ';' set-option buffer comment_block_begin '#|' set-option buffer comment_block_end '|#' } hook global BufSetOption filetype=lua %{ set-option buffer comment_line '--' set-option buffer comment_block_begin '--[[' set-option buffer comment_block_end ']]' } hook global BufSetOption filetype=markdown %{ set-option buffer comment_line '' set-option buffer comment_block_begin '[//]' set-option buffer comment_block_end '# (:)' } hook global BufSetOption filetype=perl %{ set-option buffer comment_block_begin '#[' set-option buffer comment_block_end ']' } hook global BufSetOption filetype=pug %{ set-option buffer comment_line '//' } hook global BufSetOption filetype=python %{ set-option buffer comment_block_begin "'''" set-option buffer comment_block_end "'''" } hook global BufSetOption filetype=ragel %{ set-option buffer comment_line '%%' set-option buffer comment_block_begin '%%{' set-option buffer comment_block_end '}%%' } hook global BufSetOption filetype=ruby %{ set-option buffer comment_block_begin '^begin=' set-option buffer comment_block_end '^=end' } define-command comment-block -docstring '(un)comment selections using block comments' %{ evaluate-commands %sh{ if [ -z "${kak_opt_comment_block_begin}" ] || [ -z "${kak_opt_comment_block_end}" ]; then echo "fail \"The 'comment_block' options are empty, could not comment the selection\"" fi } evaluate-commands -save-regs '"/' -draft %{ # Keep non-empty selections execute-keys \A\s*\z try %{ # Assert that the selection has been commented set-register / "\A\Q%opt{comment_block_begin}\E.*\Q%opt{comment_block_end}\E\n*\z" execute-keys "s" # Uncomment it set-register / "\A\Q%opt{comment_block_begin}\E|\Q%opt{comment_block_end}\E\n*\z" execute-keys sd } catch %{ # Comment the selection set-register '"' "%opt{comment_block_begin}" execute-keys P set-register '"' "%opt{comment_block_end}" execute-keys p } } } define-command comment-line -docstring '(un)comment selected lines using line comments' %{ evaluate-commands %sh{ if [ -z "${kak_opt_comment_line}" ]; then echo "fail \"The 'comment_line' option is empty, could not comment the line\"" fi } evaluate-commands -save-regs '"/' -draft %{ # Select the content of the lines, without indentation execute-keys gi try %{ # Keep non-empty lines execute-keys \A\s*\z } try %{ set-register / "\A\Q%opt{comment_line}\E\h?" try %{ # See if there are any uncommented lines in the selection execute-keys -draft # There are uncommented lines, so comment everything set-register '"' "%opt{comment_line} " align-selections-left execute-keys P } catch %{ # All lines were commented, so uncomment everything execute-keys sd } } } } define-command align-selections-left -docstring 'extend selections to the left to align with the leftmost selected column' %{ evaluate-commands %sh{ leftmost_column=$(echo "$kak_selections_desc" | tr ' ' '\n' | cut -d',' -f1 | cut -d'.' -f2 | sort -n | head -n1) aligned_selections=$(echo "$kak_selections_desc" | sed -E "s/\.[0-9]+,/.$leftmost_column,/g") echo "select $aligned_selections" } } kakoune-2019.07.01/rc/tools/ctags.kak000066400000000000000000000207301350637360100171130ustar00rootroot00000000000000# Kakoune CTags support script # # This script requires the readtags command available in universal-ctags declare-option -docstring "minimum characters before triggering autocomplete" \ int ctags_min_chars 3 declare-option -docstring "list of paths to tag files to parse when looking up a symbol" \ str-list ctagsfiles 'tags' declare-option -hidden completions ctags_completions declare-option -docstring "shell command to run" str readtagscmd "readtags" define-command -params ..1 \ -shell-script-candidates %{ realpath() { ( cd "$(dirname "$1")"; printf "%s/%s\n" "$(pwd -P)" "$(basename "$1")" ) } eval "set -- $kak_quoted_opt_ctagsfiles" for candidate in "$@"; do [ -f "$candidate" ] && realpath "$candidate" done | awk '!x[$0]++' | # remove duplicates while read -r tags; do namecache="${tags%/*}/.kak.${tags##*/}.namecache" if [ -z "$(find "$namecache" -prune -newer "$tags")" ]; then cut -f 1 "$tags" | grep -v '^!' | uniq > "$namecache" fi cat "$namecache" done} \ -docstring %{ctags-search []: jump to a symbol's definition If no symbol is passed then the current selection is used as symbol name} \ ctags-search \ %[ evaluate-commands %sh[ realpath() { ( cd "$(dirname "$1")"; printf "%s/%s\n" "$(pwd -P)" "$(basename "$1")" ) } export tagname="${1:-${kak_selection}}" eval "set -- $kak_quoted_opt_ctagsfiles" for candidate in "$@"; do [ -f "$candidate" ] && realpath "$candidate" done | awk '!x[$0]++' | # remove duplicates while read -r tags; do printf '!TAGROOT\t%s\n' "$(realpath "${tags%/*}")/" ${kak_opt_readtagscmd} -t "$tags" "$tagname" done | awk -F '\t|\n' ' /^!TAGROOT\t/ { tagroot=$2 } /[^\t]+\t[^\t]+\t\/\^.*\$?\// { line = $0; sub(".*\t/\\^", "", line); sub("\\$?/$", "", line); menu_info = line; gsub("!", "!!", menu_info); gsub(/^[\t+ ]+/, "", menu_info); gsub("{", "\\{", menu_info); gsub(/\t/, " ", menu_info); keys = line; gsub(/", keys); gsub(/\t/, "", keys); gsub("!", "!!", keys); gsub("&", "&&", keys); gsub("#", "##", keys); gsub("\\|", "||", keys); gsub("\\\\/", "/", keys); menu_item = $2; gsub("!", "!!", menu_item); edit_path = path($2); gsub("&", "&&", edit_path); gsub("#", "##", edit_path); gsub("\\|", "||", edit_path); select = $1; gsub(/", select); gsub(/\t/, "", select); gsub("!", "!!", select); gsub("&", "&&", select); gsub("#", "##", select); gsub("\\|", "||", select); out = out "%!" menu_item ": {MenuInfo}" menu_info "! %!evaluate-commands %# try %& edit -existing %|" edit_path "|; execute-keys %|/\\Q" keys "vc| & catch %& echo -markup %|{Error}unable to find tag| &; try %& execute-keys %|s\\Q" select "| & # !" } /[^\t]+\t[^\t]+\t[0-9]+/ { menu_item = $2; gsub("!", "!!", menu_item); select = $1; gsub(/", select); gsub(/\t/, "", select); gsub("!", "!!", select); gsub("&", "&&", select); gsub("#", "##", select); gsub("\\|", "||", select); menu_info = $3; gsub("!", "!!", menu_info); gsub("{", "\\{", menu_info); edit_path = path($2); gsub("!", "!!", edit_path); gsub("#", "##", edit_path); gsub("&", "&&", edit_path); gsub("\\|", "||", edit_path); line_number = $3; out = out "%!" menu_item ": {MenuInfo}" menu_info "! %!evaluate-commands %# try %& edit -existing %|" edit_path "|; execute-keys %|" line_number "gx| & catch %& echo -markup %|{Error}unable to find tag| &; try %& execute-keys %|s\\Q" select "| & # !" } END { print ( length(out) == 0 ? "echo -markup %{{Error}no such tag " ENVIRON["tagname"] "}" : "menu -markup -auto-single " out ) } # Ensure x is an absolute file path, by prepending with tagroot function path(x) { return x ~/^\// ? x : tagroot x }' ]] define-command ctags-complete -docstring "Complete the current selection" %{ nop %sh{ ( header="${kak_cursor_line}.${kak_cursor_column}@${kak_timestamp}" compl=$( eval "set -- $kak_quoted_opt_ctagsfiles" for ctagsfile in "$@"; do ${kak_opt_readtagscmd} -p -t "$ctagsfile" ${kak_selection} done | awk '{ uniq[$1]++ } END { for (elem in uniq) printf " %1$s||%1$s", elem }' ) printf %s\\n "evaluate-commands -client ${kak_client} set-option buffer=${kak_bufname} ctags_completions ${header}${compl}" | \ kak -p ${kak_session} ) > /dev/null 2>&1 < /dev/null & } } define-command ctags-funcinfo -docstring "Display ctags information about a selected function" %{ evaluate-commands -draft %{ try %{ execute-keys '[(;B[a-zA-Z_]+\(' evaluate-commands %sh{ f=${kak_selection%?} sig='\tsignature:(.*)' csn='\t(class|struct|namespace):(\S+)' sigs=$(${kak_opt_readtagscmd} -e -Q '(eq? $kind "f")' "${f}" | sed -re "s/^.*${csn}.*${sig}$/\3 [\2::${f}]/ ;t ;s/^.*${sig}$/\1 [${f}]/") if [ -n "$sigs" ]; then printf %s\\n "evaluate-commands -client ${kak_client} %{info -anchor $kak_cursor_line.$kak_cursor_column -style above '$sigs'}" fi } } } } define-command ctags-enable-autoinfo -docstring "Automatically display ctags information about function" %{ hook window -group ctags-autoinfo NormalIdle .* ctags-funcinfo hook window -group ctags-autoinfo InsertIdle .* ctags-funcinfo } define-command ctags-disable-autoinfo -docstring "Disable automatic ctags information displaying" %{ remove-hooks window ctags-autoinfo } declare-option -docstring "shell command to run" \ str ctagscmd "ctags -R --fields=+S" declare-option -docstring "path to the directory in which the tags file will be generated" str ctagspaths "." define-command ctags-generate -docstring 'Generate tag file asynchronously' %{ echo -markup "{Information}launching tag generation in the background" nop %sh{ ( while ! mkdir .tags.kaklock 2>/dev/null; do sleep 1; done trap 'rmdir .tags.kaklock' EXIT if ${kak_opt_ctagscmd} -f .tags.kaktmp ${kak_opt_ctagspaths}; then mv .tags.kaktmp tags msg="tags generation complete" else msg="tags generation failed" fi printf %s\\n "evaluate-commands -client $kak_client echo -markup '{Information}${msg}'" | kak -p ${kak_session} ) > /dev/null 2>&1 < /dev/null & } } define-command ctags-update-tags -docstring 'Update tags for the given file' %{ nop %sh{ ( while ! mkdir .tags.kaklock 2>/dev/null; do sleep 1; done trap 'rmdir .tags.kaklock' EXIT if ${kak_opt_ctagscmd} -f .file_tags.kaktmp $kak_bufname; then export LC_COLLATE=C LC_ALL=C # ensure ASCII sorting order # merge the updated tags tags with the general tags (filtering out out of date tags from it) into the target file grep -Fv "$(printf '\t%s\t' "$kak_bufname")" tags | grep -v '^!' | sort --merge - .file_tags.kaktmp >> .tags.kaktmp rm .file_tags.kaktmp mv .tags.kaktmp tags msg="tags updated for $kak_bufname" else msg="tags update failed for $kak_bufname" fi printf %s\\n "evaluate-commands -client $kak_client echo -markup '{Information}${msg}'" | kak -p ${kak_session} ) > /dev/null 2>&1 < /dev/null & } } define-command ctags-enable-autocomplete -docstring "Enable automatic ctags completion" %{ set-option window completers "option=ctags_completions" %opt{completers} hook window -group ctags-autocomplete InsertIdle .* %{ try %{ evaluate-commands -draft %{ # select previous word >= ctags_min_chars execute-keys "b_.{%opt{ctags_min_chars},}" ctags-complete # run in draft context to preserve selection } } } } define-command ctags-disable-autocomplete -docstring "Disable automatic ctags completion" %{ evaluate-commands %sh{ printf "set-option window completers %s\n" $(printf %s "${kak_opt_completers}" | sed -e "s/'option=ctags_completions'//g") } remove-hooks window ctags-autocomplete } kakoune-2019.07.01/rc/tools/doc.kak000066400000000000000000000135531350637360100165640ustar00rootroot00000000000000declare-option -docstring "name of the client in which documentation is to be displayed" \ str docsclient declare-option -hidden range-specs doc_render_ranges declare-option -hidden range-specs doc_render_links declare-option -hidden range-specs doc_links declare-option -hidden range-specs doc_anchors define-command -hidden -params 4 doc-render-regex %{ evaluate-commands -draft %{ try %{ execute-keys \%s %arg{1} execute-keys -draft s %arg{2} d execute-keys "%arg{3}" evaluate-commands %sh{ face="$4" eval "set -- $kak_quoted_selections_desc" for desc in "$@"; do ranges="$ranges '$desc|$face'"; done echo "update-option buffer doc_render_ranges" echo "set-option -add buffer doc_render_ranges $ranges" } } } } define-command -hidden doc-parse-links %{ evaluate-commands -draft %{ try %{ execute-keys \%s (.*?),.*? execute-keys -draft s .*,| d execute-keys H set-option buffer doc_links %val{timestamp} set-option buffer doc_render_links %val{timestamp} evaluate-commands -itersel %{ set-option -add buffer doc_links "%val{selection_desc}|%reg{1}" set-option -add buffer doc_render_links "%val{selection_desc}|default+u" } } } } define-command -hidden doc-parse-anchors %{ evaluate-commands -draft %{ try %{ set-option buffer doc_anchors %val{timestamp} # Find sections as add them as imlicit anchors execute-keys \%s ^={2,}\h+([^\n]+)$ evaluate-commands -itersel %{ set-option -add buffer doc_anchors "%val{selection_desc}|%sh{printf '%s' ""$kak_main_reg_1"" | tr '[A-Z ]' '[a-z-]'}" } # Parse explicit anchors and remove their text execute-keys \%s \[\[(.*?)\]\]\s* evaluate-commands -itersel %{ set-option -add buffer doc_anchors "%val{selection_desc}|%reg{1}" } execute-keys d update-option buffer doc_anchors } } } define-command doc-jump-to-anchor -params 1 %{ update-option buffer doc_anchors evaluate-commands %sh{ anchor="$1" eval "set -- $kak_quoted_opt_doc_anchors" shift for range in "$@"; do if [ "${range#*|}" = "$anchor" ]; then printf '%s\n' "select '${range%|*}'; execute-keys vv" exit fi done printf "echo -markup {Error}No such anchor '%s'" "${anchor}" } } define-command doc-follow-link %{ update-option buffer doc_links evaluate-commands %sh{ eval "set -- $kak_quoted_opt_doc_links" for link in "$@"; do printf '%s\n' "$link" done | awk -v FS='[.,|#]' ' BEGIN { l=ENVIRON["kak_cursor_line"]; c=ENVIRON["kak_cursor_column"]; } l >= $1 && c >= $2 && l <= $3 && c <= $4 { if (NF == 6) { print "doc " $5 if ($6 != "") { print "doc-jump-to-anchor %{" $6 "}" } } else { print "doc-jump-to-anchor %{" $5 "}" } exit } ' } } define-command -params 1 -hidden doc-render %{ edit! -scratch "*doc-%sh{basename $1 .asciidoc}*" execute-keys "!cat %arg{1}gg" doc-parse-anchors # Join paragraphs together try %{ execute-keys -draft '%S\n{2,}|(?<=\+)\n|^[^\n]+::\n|^\h*[*-]\h+' \ ^\h*-{2,}(\n|\z) S\n\z \n } # Remove some line end markers try %{ execute-keys -draft \%s \h*(\+|:{2,})$ d } # Setup the doc_render_ranges option set-option buffer doc_render_ranges %val{timestamp} doc-render-regex \B(? d } set-option buffer readonly true add-highlighter buffer/ ranges doc_render_ranges add-highlighter buffer/ ranges doc_render_links add-highlighter buffer/ wrap -word -indent map buffer normal ': doc-follow-link' } define-command -params 1..2 \ -shell-script-candidates %{ if [ "$kak_token_to_complete" -eq 0 ]; then find "${kak_runtime}/doc/" -type f -name "*.asciidoc" | sed 's,.*/,,; s/\.[^/]*$//' elif [ "$kak_token_to_complete" -eq 1 ]; then readonly page="${kak_runtime}/doc/${1}.asciidoc" if [ -f "${page}" ]; then awk ' /^==+ +/ { sub(/^==+ +/, ""); print } /^\[\[[^\]]+\]\]/ { sub(/^\[\[/, ""); sub(/\]\].*/, ""); print } ' < $page | tr '[A-Z ]' '[a-z-]' fi fi } \ doc -docstring %{doc []: open a buffer containing documentation about a given topic An optional keyword argument can be passed to the function, which will be automatically selected in the documentation} %{ evaluate-commands %sh{ readonly page="${kak_runtime}/doc/${1}.asciidoc" if [ -f "${page}" ]; then if [ $# -eq 2 ]; then jump_cmd="doc-jump-to-anchor '$2'" fi printf %s\\n "evaluate-commands -try-client %opt{docsclient} %{ doc-render ${page}; ${jump_cmd} }" else printf %s\\n "echo -markup '{Error}No such doc file: ${page}'" fi } } alias global help doc kakoune-2019.07.01/rc/tools/formatter.kak000066400000000000000000000026041350637360100200150ustar00rootroot00000000000000declare-option -docstring "shell command to which the contents of the current buffer is piped" \ str formatcmd define-command format -docstring "Format the contents of the current buffer" %{ evaluate-commands -draft -no-hooks %{ evaluate-commands %sh{ if [ -n "${kak_opt_formatcmd}" ]; then path_file_tmp=$(mktemp "${TMPDIR:-/tmp}"/kak-formatter-XXXXXX) printf %s\\n " write -sync \"${path_file_tmp}\" evaluate-commands %sh{ readonly path_file_out=\$(mktemp \"${TMPDIR:-/tmp}\"/kak-formatter-XXXXXX) if cat \"${path_file_tmp}\" | eval \"${kak_opt_formatcmd}\" > \"\${path_file_out}\"; then printf '%s\\n' \"execute-keys \\%|cat'\${path_file_out}'\" printf '%s\\n' \"nop %sh{ rm -f '\${path_file_out}' }\" else printf '%s\\n' \" evaluate-commands -client '${kak_client}' echo -markup '{Error}formatter returned an error (\$?)' \" rm -f \"\${path_file_out}\" fi rm -f \"${path_file_tmp}\" } " else printf '%s\n' "evaluate-commands -client '${kak_client}' echo -markup '{Error}formatcmd option not specified'" fi } } } kakoune-2019.07.01/rc/tools/git.kak000066400000000000000000000217071350637360100166020ustar00rootroot00000000000000declare-option -docstring "name of the client in which documentation is to be displayed" \ str docsclient hook -group git-log-highlight global WinSetOption filetype=git-log %{ add-highlighter window/git-log group add-highlighter window/git-log/ regex '^(commit) ([0-9a-f]+)( [^\n]+)?$' 1:keyword 2:meta 3:comment add-highlighter window/git-log/ regex '^([a-zA-Z_-]+:) (.*?)$' 1:variable 2:value add-highlighter window/git-log/ ref diff # highlight potential diffs from the -p option hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/git-log } } hook -group git-status-highlight global WinSetOption filetype=git-status %{ add-highlighter window/git-status group add-highlighter window/git-status/ regex '^\h+(?:((?:both )?modified:)|(added:|new file:)|(deleted(?: by \w+)?:)|(renamed:)|(copied:))(?:.*?)$' 1:yellow 2:green 3:red 4:cyan 5:blue 6:magenta hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/git-status } } declare-option -hidden line-specs git_blame_flags declare-option -hidden line-specs git_diff_flags define-command -params 1.. \ -docstring %sh{printf 'git []: git wrapping helper All the optional arguments are forwarded to the git utility Available commands:\n add\n rm\n blame\n commit\n checkout\n diff\n hide-blame\n hide-diff\n init\n log\n show\n show-diff\n status\n update-diff'} \ -shell-script-candidates %{ if [ $kak_token_to_complete -eq 0 ]; then printf "add\nrm\nblame\ncommit\ncheckout\ndiff\nhide-blame\nhide-diff\nlog\nshow\nshow-diff\ninit\nstatus\nupdate-diff\n" else case "$1" in commit) printf -- "--amend\n--no-edit\n--all\n--reset-author\n--fixup\n--squash\n"; git ls-files -m ;; add) git ls-files -dmo --exclude-standard ;; rm) git ls-files -c ;; esac fi } \ git %{ evaluate-commands %sh{ show_git_cmd_output() { local filetype case "$1" in show|diff) filetype=diff ;; log) filetype=git-log ;; status) filetype=git-status ;; esac output=$(mktemp -d "${TMPDIR:-/tmp}"/kak-git.XXXXXXXX)/fifo mkfifo ${output} ( git "$@" > ${output} 2>&1 ) > /dev/null 2>&1 < /dev/null & printf %s "evaluate-commands -try-client '$kak_opt_docsclient' %{ edit! -fifo ${output} *git* set-option buffer filetype '${filetype}' hook -always -once buffer BufCloseFifo .* %{ nop %sh{ rm -r $(dirname ${output}) } } }" } run_git_blame() { ( printf %s "evaluate-commands -client '$kak_client' %{ try %{ add-highlighter window/git-blame flag-lines Information git_blame_flags } set-option buffer=$kak_bufname git_blame_flags '$kak_timestamp' }" | kak -p ${kak_session} git blame "$@" --incremental ${kak_buffile} | awk ' function send_flags(text, flag, i) { if (line == "") { return; } text=substr(sha,1,8) " " dates[sha] " " authors[sha] # gsub("|", "\\|", text) gsub("~", "~~", text) flag="%~" line "|" text "~" for ( i=1; i < count; i++ ) { flag=flag " %~" line+i "|" text "~" } cmd = "kak -p " ENVIRON["kak_session"] print "set-option -add buffer=" ENVIRON["kak_bufname"] " git_blame_flags " flag | cmd close(cmd) } /^([0-9a-f]+) ([0-9]+) ([0-9]+) ([0-9]+)/ { send_flags() sha=$1 line=$3 count=$4 } /^author / { authors[sha]=substr($0,8) } /^author-time ([0-9]*)/ { cmd = "date -d @" $2 " +\"%F %T\"" cmd | getline dates[sha] close(cmd) } END { send_flags(); }' ) > /dev/null 2>&1 < /dev/null & } update_diff() { git --no-pager diff -U0 "$kak_buffile" | perl -e ' $flags = $ENV{"kak_timestamp"}; foreach $line () { if ($line =~ /@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))?/) { $from_line = $1; $from_count = ($2 eq "" ? 1 : $2); $to_line = $3; $to_count = ($4 eq "" ? 1 : $4); if ($from_count == 0 and $to_count > 0) { for $i (0..$to_count - 1) { $line = $to_line + $i; $flags .= " $line|\{green\}+"; } } elsif ($from_count > 0 and $to_count == 0) { if ($to_line == 0) { $flags .= " 1|\{red\}‾"; } else { $flags .= " $to_line|\{red\}_"; } } elsif ($from_count > 0 and $from_count == $to_count) { for $i (0..$to_count - 1) { $line = $to_line + $i; $flags .= " $line|\{blue\}~"; } } elsif ($from_count > 0 and $from_count < $to_count) { for $i (0..$from_count - 1) { $line = $to_line + $i; $flags .= " $line|\{blue\}~"; } for $i ($from_count..$to_count - 1) { $line = $to_line + $i; $flags .= " $line|\{green\}+"; } } elsif ($to_count > 0 and $from_count > $to_count) { for $i (0..$to_count - 2) { $line = $to_line + $i; $flags .= " $line|\{blue\}~"; } $last = $to_line + $to_count - 1; $flags .= " $last|\{blue+u\}~"; } } } print "set-option buffer git_diff_flags $flags" ' } commit() { # Handle case where message needs not to be edited if grep -E -q -e "-m|-F|-C|--message=.*|--file=.*|--reuse-message=.*|--no-edit|--fixup.*|--squash.*"; then if git commit "$@" > /dev/null 2>&1; then echo 'echo -markup "{Information}Commit succeeded"' else echo 'echo -markup "{Error}Commit failed"' fi exit fi <<-EOF $@ EOF # fails, and generate COMMIT_EDITMSG GIT_EDITOR='' EDITOR='' git commit "$@" > /dev/null 2>&1 msgfile="$(git rev-parse --git-dir)/COMMIT_EDITMSG" printf %s "edit '$msgfile' hook buffer BufWritePost '.*\Q$msgfile\E' %{ evaluate-commands %sh{ if git commit -F '$msgfile' --cleanup=strip $* > /dev/null; then printf %s 'evaluate-commands -client $kak_client echo -markup %{{Information}Commit succeeded}; delete-buffer' else printf %s 'evaluate-commands -client $kak_client echo -markup %{{Error}Commit failed}' fi } }" } case "$1" in show|log|diff|status) show_git_cmd_output "$@" ;; blame) shift; run_git_blame "$@" ;; hide-blame) printf %s "try %{ set-option buffer=$kak_bufname git_blame_flags $kak_timestamp remove-highlighter window/git-blame }" ;; show-diff) echo 'try %{ add-highlighter window/git-diff flag-lines Default git_diff_flags }' update_diff ;; hide-diff) echo 'try %{ remove-highlighter window/git-diff }' ;; update-diff) update_diff ;; commit) shift; commit "$@" ;; init) shift; git init "$@" > /dev/null 2>&1 ;; checkout) name="${2:-${kak_buffile}}" git checkout "${name}" > /dev/null 2>&1 ;; add) name="${2:-${kak_buffile}}" if git add -- "${name}" > /dev/null 2>&1; then printf %s "echo -markup '{Information}git: added ${name}'" else printf %s "echo -markup '{Error}git: unable to add ${name}'" fi ;; rm) name="${2:-${kak_buffile}}" if git rm -- "${name}" > /dev/null 2>&1; then printf %s "echo -markup '{Information}git: removed ${name}'" else printf %s "echo -markup '{Error}git: unable to remove ${name}'" fi ;; *) printf %s "echo -markup %{{Error}unknown git command '$1'}"; exit ;; esac }} kakoune-2019.07.01/rc/tools/go/000077500000000000000000000000001350637360100157255ustar00rootroot00000000000000kakoune-2019.07.01/rc/tools/go/go-tools.kak000066400000000000000000000161741350637360100201710ustar00rootroot00000000000000# Provides integration of the following tools: # - gocode for code completion (github.com/nsf/gocode) # - goimports for code formatting on save # - gogetdoc for documentation display and source jump (needs jq) (github.com/zmb3/gogetdoc) # Needs the following tools in the path: # - jq for json deserializaton hook -once global BufSetOption filetype=go %{ require-module go-tools } provide-module go-tools %{ evaluate-commands %sh{ for dep in gocode goimports gogetdoc jq; do if ! command -v $dep > /dev/null 2>&1; then echo "echo -debug %{Dependency unmet: $dep, please install it to use go-tools}" fi done } # Auto-completion # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ declare-option -hidden str go_complete_tmp_dir declare-option -hidden completions gocode_completions define-command go-complete -docstring "Complete the current selection with gocode" %{ evaluate-commands %sh{ dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-go.XXXXXXXX) printf %s\\n "set-option buffer go_complete_tmp_dir ${dir}" printf %s\\n "evaluate-commands -no-hooks write ${dir}/buf" } nop %sh{ dir=${kak_opt_go_complete_tmp_dir} ( gocode_data=$(gocode -f=godit --in=${dir}/buf autocomplete ${kak_cursor_byte_offset}) rm -r ${dir} column_offset=$(printf %s "${gocode_data}" | head -n1 | cut -d, -f1) header="${kak_cursor_line}.$((${kak_cursor_column} - $column_offset))@${kak_timestamp}" compl=$(echo "${gocode_data}" | sed 1d | awk -F ",," '{ gsub(/~/, "~~", $1) gsub(/~/, "~~", $2) print "%~" $2 "||" $1 "~" }' | paste -s -) printf %s\\n "evaluate-commands -client '${kak_client}' %{ set-option 'buffer=${kak_bufname}' gocode_completions ${header} ${compl} }" | kak -p ${kak_session} ) > /dev/null 2>&1 < /dev/null & } } define-command go-enable-autocomplete -docstring "Add gocode completion candidates to the completer" %{ set-option window completers "option=gocode_completions" %opt{completers} hook window -group go-autocomplete InsertIdle .* %{ try %{ execute-keys -draft [\w\.].\z go-complete } } alias window complete go-complete } define-command go-disable-autocomplete -docstring "Disable gocode completion" %{ set-option window completers %sh{ printf %s\\n "${kak_opt_completers}" | sed "s/'option=gocode_completions'//g" } remove-hooks window go-autocomplete unalias window complete go-complete } # Auto-format # ‾‾‾‾‾‾‾‾‾‾‾ declare-option -hidden str go_format_tmp_dir define-command -params ..1 go-format \ -docstring "go-format [-use-goimports]: custom formatter for go files" %{ evaluate-commands %sh{ dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-go.XXXXXXXX) printf %s\\n "set-option buffer go_format_tmp_dir ${dir}" printf %s\\n "evaluate-commands -no-hooks write ${dir}/buf" } evaluate-commands %sh{ dir=${kak_opt_go_format_tmp_dir} if [ "$1" = "-use-goimports" ]; then fmt_cmd="goimports -srcdir '${kak_buffile}'" else fmt_cmd="gofmt -s" fi eval "${fmt_cmd} -e -w ${dir}/buf 2> ${dir}/stderr" if [ $? ]; then cp ${dir}/buf "${kak_buffile}" else # we should report error if linting isn't active printf %s\\n "echo -debug '$(cat ${dir}/stderr)'" fi rm -r ${dir} } edit! } # Documentation # ‾‾‾‾‾‾‾‾‾‾‾‾‾ declare-option -hidden str go_doc_tmp_dir # FIXME text escaping define-command -hidden -params 1..2 gogetdoc-cmd %{ evaluate-commands %sh{ dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-go.XXXXXXXX) printf %s\\n "set-option buffer go_doc_tmp_dir ${dir}" printf %s\\n "evaluate-commands -no-hooks write ${dir}/buf" } evaluate-commands %sh{ dir=${kak_opt_go_doc_tmp_dir} ( printf %s\\n "${kak_buffile}" > ${dir}/modified cat ${dir}/buf | wc -c >> ${dir}/modified cat ${dir}/buf >> ${dir}/modified if [ "$2" = "1" ]; then args="-json" fi output=$(cat ${dir}/modified \ | gogetdoc $args -pos "${kak_buffile}:#${kak_cursor_byte_offset}" -modified \ | sed 's/%/%%/g') rm -r ${dir} printf %s "${output}" | grep -v -q "^gogetdoc: " status=$? case "$1" in "info") if [ ${status} -eq 0 ]; then printf %s\\n "evaluate-commands -client '${kak_client}' %{ info -anchor ${kak_cursor_line}.${kak_cursor_column} %@${output}@ }" | kak -p ${kak_session} else msg=$(printf %s "${output}" | cut -d' ' -f2-) printf %s\\n "evaluate-commands -client '${kak_client}' %{ echo '${msg}' }" | kak -p ${kak_session} fi ;; "echo") if [ ${status} -eq 0 ]; then signature=$(printf %s "${output}" | sed -n 3p) printf %s\\n "evaluate-commands -client '${kak_client}' %{ echo '${signature}' }" | kak -p ${kak_session} fi ;; "jump") if [ ${status} -eq 0 ]; then pos=$(printf %s "${output}" | jq -r .pos) file=$(printf %s "${pos}" | cut -d: -f1) line=$(printf %s "${pos}" | cut -d: -f2) col=$(printf %s "${pos}" | cut -d: -f3) printf %s\\n "evaluate-commands -client '${kak_client}' %{ evaluate-commands -try-client '${kak_opt_jumpclient}' edit -existing ${file} ${line} ${col} try %{ focus '${kak_opt_jumpclient}' } }" | kak -p ${kak_session} fi ;; *) printf %s\\n "evaluate-commands -client '${kak_client}' %{ echo -error %{unkown command '$1'} }" | kak -p ${kak_session} ;; esac ) > /dev/null 2>&1 < /dev/null & } } define-command go-doc-info -docstring "Show the documention of the symbol under the cursor" %{ gogetdoc-cmd "info" } define-command go-print-signature -docstring "Print the signature of the symbol under the cursor" %{ gogetdoc-cmd "echo" } define-command go-jump -docstring "Jump to the symbol definition" %{ gogetdoc-cmd "jump" 1 } define-command go-share-selection -docstring "Share the selection using the Go Playground" %{ evaluate-commands %sh{ snippet_id=$(printf %s\\n "${kak_selection}" | curl -s https://play.golang.org/share --data-binary @-) printf "echo https://play.golang.org/p/%s" ${snippet_id} } } } kakoune-2019.07.01/rc/tools/grep.kak000066400000000000000000000062101350637360100167440ustar00rootroot00000000000000declare-option -docstring "shell command run to search for subtext in a file/directory" \ str grepcmd 'grep -RHn' declare-option -docstring "name of the client in which utilities display information" \ str toolsclient declare-option -hidden int grep_current_line 0 define-command -params .. -file-completion \ -docstring %{grep []: grep utility wrapper All the optional arguments are forwarded to the grep utility} \ grep %{ evaluate-commands %sh{ output=$(mktemp -d "${TMPDIR:-/tmp}"/kak-grep.XXXXXXXX)/fifo mkfifo ${output} if [ $# -gt 0 ]; then ( ${kak_opt_grepcmd} "$@" | tr -d '\r' > ${output} 2>&1 ) > /dev/null 2>&1 < /dev/null & else ( ${kak_opt_grepcmd} "${kak_selection}" | tr -d '\r' > ${output} 2>&1 ) > /dev/null 2>&1 < /dev/null & fi printf %s\\n "evaluate-commands -try-client '$kak_opt_toolsclient' %{ edit! -fifo ${output} -scroll *grep* set-option buffer filetype grep set-option buffer grep_current_line 0 hook -always -once buffer BufCloseFifo .* %{ nop %sh{ rm -r $(dirname ${output}) } } }" }} hook -group grep-highlight global WinSetOption filetype=grep %{ add-highlighter window/grep group add-highlighter window/grep/ regex "^((?:\w:)?[^:\n]+):(\d+):(\d+)?" 1:cyan 2:green 3:green add-highlighter window/grep/ line %{%opt{grep_current_line}} default+b hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/grep } } hook global WinSetOption filetype=grep %{ hook buffer -group grep-hooks NormalKey grep-jump hook -once -always window WinSetOption filetype=.* %{ remove-hooks buffer grep-hooks } } declare-option -docstring "name of the client in which all source code jumps will be executed" \ str jumpclient define-command -hidden grep-jump %{ evaluate-commands %{ # use evaluate-commands to ensure jumps are collapsed try %{ execute-keys 's^((?:\w:)?[^:]+):(\d+):(\d+)?' set-option buffer grep_current_line %val{cursor_line} evaluate-commands -try-client %opt{jumpclient} edit -existing %reg{1} %reg{2} %reg{3} try %{ focus %opt{jumpclient} } } } } define-command grep-next-match -docstring 'Jump to the next grep match' %{ evaluate-commands -try-client %opt{jumpclient} %{ buffer '*grep*' # First jump to enf of buffer so that if grep_current_line == 0 # 0g will be a no-op and we'll jump to the first result. # Yeah, thats ugly... execute-keys "ge %opt{grep_current_line}g /^[^:]+:\d+:" grep-jump } try %{ evaluate-commands -client %opt{toolsclient} %{ execute-keys gg %opt{grep_current_line}g } } } define-command grep-previous-match -docstring 'Jump to the previous grep match' %{ evaluate-commands -try-client %opt{jumpclient} %{ buffer '*grep*' # See comment in grep-next-match execute-keys "ge %opt{grep_current_line}g ^[^:]+:\d+:" grep-jump } try %{ evaluate-commands -client %opt{toolsclient} %{ execute-keys gg %opt{grep_current_line}g } } } kakoune-2019.07.01/rc/tools/lint.kak000066400000000000000000000137351350637360100167670ustar00rootroot00000000000000declare-option -docstring %{shell command to which the path of a copy of the current buffer will be passed The output returned by this command is expected to comply with the following format: {filename}:{line}:{column}: {kind}: {message}} \ str lintcmd declare-option -hidden line-specs lint_flags declare-option -hidden range-specs lint_errors declare-option -hidden int lint_error_count declare-option -hidden int lint_warning_count define-command lint -docstring 'Parse the current buffer with a linter' %{ evaluate-commands %sh{ if [ -z "${kak_opt_lintcmd}" ]; then printf %s\\n 'echo -markup {Error}The `lintcmd` option is not set' exit 1 fi filename="${kak_buffile##*/}" dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-lint.XXXXXXXX) mkfifo "$dir"/fifo printf '%s\n' "evaluate-commands -no-hooks write -sync $dir/${filename}" printf '%s\n' "evaluate-commands -draft %{ edit! -fifo $dir/fifo -debug *lint-output* set-option buffer filetype make set-option buffer make_current_error_line 0 hook -always -once buffer BufCloseFifo .* %{ nop %sh{ rm -r '$dir' } } }" { # do the parsing in the background and when ready send to the session eval "$kak_opt_lintcmd '$dir'/${filename}" | sort -t: -k2,2 -n > "$dir"/stderr # Flags for the gutter: # stamp l3|{red}█ l11|{yellow}█ # Contextual error messages: # stamp 'l1.c1,l1.c1|kind:message' 'l2.c2,l2.c2|kind:message' awk -F: -v file="$kak_buffile" -v stamp="$kak_timestamp" -v client="$kak_client" ' BEGIN { error_count = 0 warning_count = 0 } /:[1-9][0-9]*:[1-9][0-9]*: ([Ff]atal )?[Ee]rror/ { flags = flags " " $2 "|{red}█" error_count++ } /:[1-9][0-9]*:[1-9][0-9]*:/ { if ($4 !~ /[Ee]rror/) { flags = flags " " $2 "|{yellow}█" warning_count++ } } /:[1-9][0-9]*:[1-9][0-9]*:/ { kind = substr($4, 2) error = $2 "." $3 "," $2 "." $3 "|" kind msg = "" # fix case where $5 is not the last field because of extra colons in the message for (i=5; i<=NF; i++) msg = msg ":" $i gsub(/\|/, "\\|", msg) gsub("'\''", "'"''"'", msg) error = error msg " (col " $3 ")" errors = errors " '\''" error "'\''" } END { print "set-option \"buffer=" file "\" lint_flags " stamp flags gsub("~", "\\~", errors) print "set-option \"buffer=" file "\" lint_errors " stamp errors print "set-option \"buffer=" file "\" lint_error_count " error_count print "set-option \"buffer=" file "\" lint_warning_count " warning_count print "evaluate-commands -client " client " lint-show-counters" } ' "$dir"/stderr | kak -p "$kak_session" cut -d: -f2- "$dir"/stderr | awk -v bufname="${kak_bufname}" ' /^[1-9][0-9]*:[1-9][0-9]*:/ { print bufname ":" $0 } ' > "$dir"/fifo } >/dev/null 2>&1 ]: make utility wrapper All the optional arguments are forwarded to the make utility} \ make %{ evaluate-commands %sh{ output=$(mktemp -d "${TMPDIR:-/tmp}"/kak-make.XXXXXXXX)/fifo mkfifo ${output} ( eval ${kak_opt_makecmd} "$@" > ${output} 2>&1 ) > /dev/null 2>&1 < /dev/null & printf %s\\n "evaluate-commands -try-client '$kak_opt_toolsclient' %{ edit! -fifo ${output} -scroll *make* set-option buffer filetype make set-option buffer make_current_error_line 0 hook -always -once buffer BufCloseFifo .* %{ nop %sh{ rm -r $(dirname ${output}) } } }" }} add-highlighter shared/make group add-highlighter shared/make/ regex "^((?:\w:)?[^:\n]+):(\d+):(?:(\d+):)?\h+(?:((?:fatal )?error)|(warning)|(note)|(required from(?: here)?))?.*?$" 1:cyan 2:green 3:green 4:red 5:yellow 6:blue 7:yellow add-highlighter shared/make/ regex "^\h*(~*(?:(\^)~*)?)$" 1:green 2:cyan+b add-highlighter shared/make/ line '%opt{make_current_error_line}' default+b hook -group make-highlight global WinSetOption filetype=make %{ add-highlighter window/make ref make hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/make } } hook global WinSetOption filetype=make %{ hook buffer -group make-hooks NormalKey make-jump hook -once -always window WinSetOption filetype=.* %{ remove-hooks buffer make-hooks } } declare-option -docstring "name of the client in which all source code jumps will be executed" \ str jumpclient define-command -hidden make-open-error -params 4 %{ evaluate-commands -try-client %opt{jumpclient} %{ edit -existing "%arg{1}" %arg{2} %arg{3} echo -markup "{Information}%arg{4}" try %{ focus } } } define-command -hidden make-jump %{ evaluate-commands %{ try %{ execute-keys gl "Entering directory" # Try to parse the error into capture groups, failing on absolute paths execute-keys s "Entering directory [`']([^']+)'.*\n([^:/][^:]*):(\d+):(?:(\d+):)?([^\n]+)\z" l set-option buffer make_current_error_line %val{cursor_line} make-open-error "%reg{1}/%reg{2}" "%reg{3}" "%reg{4}" "%reg{5}" } catch %{ execute-keys s "((?:\w:)?[^:]+):(\d+):(?:(\d+):)?([^\n]+)\z" l set-option buffer make_current_error_line %val{cursor_line} make-open-error "%reg{1}" "%reg{2}" "%reg{3}" "%reg{4}" } } } define-command make-next-error -docstring 'Jump to the next make error' %{ evaluate-commands -try-client %opt{jumpclient} %{ buffer '*make*' execute-keys "%opt{make_current_error_line}ggl" "/^(?:\w:)?[^:\n]+:\d+:(?:\d+:)?%opt{make_error_pattern}" make-jump } try %{ evaluate-commands -client %opt{toolsclient} %{ execute-keys %opt{make_current_error_line}g } } } define-command make-previous-error -docstring 'Jump to the previous make error' %{ evaluate-commands -try-client %opt{jumpclient} %{ buffer '*make*' execute-keys "%opt{make_current_error_line}g" "^(?:\w:)?[^:\n]+:\d+:(?:\d+:)?%opt{make_error_pattern}" make-jump } try %{ evaluate-commands -client %opt{toolsclient} %{ execute-keys %opt{make_current_error_line}g } } } kakoune-2019.07.01/rc/tools/man.kak000066400000000000000000000050501350637360100165630ustar00rootroot00000000000000declare-option -docstring "name of the client in which documentation is to be displayed" \ str docsclient declare-option -hidden str manpage hook -group man-highlight global WinSetOption filetype=man %{ add-highlighter window/man-highlight group # Sections add-highlighter window/man-highlight/ regex ^\S.*?$ 0:title # Subsections add-highlighter window/man-highlight/ regex '^ {3}\S.*?$' 0:default+b # Command line options add-highlighter window/man-highlight/ regex '^ {7}-[^\s,]+(,\s+-[^\s,]+)*' 0:list # References to other manpages add-highlighter window/man-highlight/ regex [-a-zA-Z0-9_.]+\([a-z0-9]+\) 0:header hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/man-highlight } } hook global WinSetOption filetype=man %{ hook -group man-hooks window WinResize .* %{ man-impl %val{bufname} %opt{manpage} } hook -once -always window WinSetOption filetype=.* %{ remove-hooks window man-hooks } } define-command -hidden -params 2..3 man-impl %{ evaluate-commands %sh{ buffer_name="$1" shift manout=$(mktemp "${TMPDIR:-/tmp}"/kak-man-XXXXXX) colout=$(mktemp "${TMPDIR:-/tmp}"/kak-man-XXXXXX) MANWIDTH=${kak_window_width} man "$@" > $manout 2>/dev/null retval=$? col -b -x > ${colout} < ${manout} rm ${manout} if [ "${retval}" -eq 0 ]; then printf %s\\n " edit -scratch '$buffer_name' execute-keys '%|cat${colout}gk' nop %sh{rm ${colout}} set-option buffer filetype man set-option window manpage '$@' " else printf %s\\n "echo -markup %{{Error}man '$@' failed: see *debug* buffer for details}" rm ${colout} fi } } define-command -params ..1 \ -shell-script-candidates %{ find /usr/share/man/ -name '*.[1-8]*' | sed 's,^.*/\(.*\)\.\([1-8][a-zA-Z]*\).*$,\1(\2),' } \ -docstring %{man []: manpage viewer wrapper If no argument is passed to the command, the selection will be used as page The page can be a word, or a word directly followed by a section number between parenthesis, e.g. kak(1)} \ man %{ evaluate-commands %sh{ subject=${1-$kak_selection} ## The completion suggestions display the page number, strip them if present case "${subject}" in *\([1-8]*\)) pagenum="${subject##*\(}" pagenum="${pagenum%\)}" subject="${subject%%\(*}" ;; esac printf %s\\n "evaluate-commands -try-client %opt{docsclient} man-impl *man* $pagenum $subject" } } kakoune-2019.07.01/rc/tools/python/000077500000000000000000000000001350637360100166415ustar00rootroot00000000000000kakoune-2019.07.01/rc/tools/python/jedi.kak000066400000000000000000000045551350637360100202550ustar00rootroot00000000000000hook -once global BufSetOption filetype=python %{ require-module jedi } provide-module jedi %{ declare-option -hidden str jedi_tmp_dir declare-option -hidden completions jedi_completions declare-option -docstring "colon separated list of path added to `python`'s $PYTHONPATH environment variable" \ str jedi_python_path define-command jedi-complete -docstring "Complete the current selection" %{ evaluate-commands %sh{ dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-jedi.XXXXXXXX) mkfifo ${dir}/fifo printf %s\\n "set-option buffer jedi_tmp_dir ${dir}" printf %s\\n "evaluate-commands -no-hooks write -sync ${dir}/buf" } evaluate-commands %sh{ dir=${kak_opt_jedi_tmp_dir} printf %s\\n "evaluate-commands -draft %{ edit! -fifo ${dir}/fifo *jedi-output* }" ( cd $(dirname ${kak_buffile}) header="${kak_cursor_line}.${kak_cursor_column}@${kak_timestamp}" export PYTHONPATH="$kak_opt_jedi_python_path:$PYTHONPATH" compl=$(python 2> "${dir}/fifo" <<-END import jedi script=jedi.Script(open('$dir/buf', 'r').read(), $kak_cursor_line, $kak_cursor_column - 1, '$kak_buffile') print(' '.join(["'" + (str(c.name).replace("|", "\\|") + "|info -style menu %!" + str(c.docstring()).replace("|", "\\|").replace("!", "!!") + "!|" + str(c.name).replace("|", "\\|")).replace("~", "~~").replace("'", "''") + "'" for c in script.completions()])) END ) printf %s\\n "evaluate-commands -client ${kak_client} %~echo completed; set-option %{buffer=${kak_buffile}} jedi_completions ${header} ${compl}~" | kak -p ${kak_session} rm -r ${dir} ) > /dev/null 2>&1 < /dev/null & } } define-command jedi-enable-autocomplete -docstring "Add jedi completion candidates to the completer" %{ set-option window completers option=jedi_completions %opt{completers} hook window -group jedi-autocomplete InsertIdle .* %{ try %{ execute-keys -draft \..\z echo 'completing...' jedi-complete } } alias window complete jedi-complete } define-command jedi-disable-autocomplete -docstring "Disable jedi completion" %{ set-option window completers %sh{ printf %s\\n "'${kak_opt_completers}'" | sed -e 's/option=jedi_completions://g' } remove-hooks window jedi-autocomplete unalias window complete jedi-complete } } kakoune-2019.07.01/rc/tools/rust/000077500000000000000000000000001350637360100163155ustar00rootroot00000000000000kakoune-2019.07.01/rc/tools/rust/racer.kak000066400000000000000000000116471350637360100201120ustar00rootroot00000000000000hook -once global BufSetOption filetype=rust %{ require-module racer } provide-module racer %{ declare-option -hidden str racer_tmp_dir declare-option -hidden completions racer_completions define-command racer-complete -docstring "Complete the current selection with racer" %{ evaluate-commands %sh{ dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-racer.XXXXXXXX) printf %s\\n "set-option buffer racer_tmp_dir ${dir}" printf %s\\n "evaluate-commands -no-hooks %{ write ${dir}/buf }" } evaluate-commands %sh{ dir=${kak_opt_racer_tmp_dir} ( cursor="${kak_cursor_line} $((${kak_cursor_column} - 1))" racer_data=$(racer --interface tab-text complete-with-snippet ${cursor} ${kak_buffile} ${dir}/buf) compl=$(printf %s\\n "${racer_data}" | awk ' BEGIN { FS = "\t"; ORS = " " } /^PREFIX/ { column = ENVIRON["kak_cursor_column"] + $2 - $3 print ENVIRON["kak_cursor_line"] "." column "@@" ENVIRON["kak_timestamp"] } /^MATCH/ { word = $2 desc = substr($9, 2, length($9) - 2) gsub(/\|/, "\\|", desc) gsub(/\\n/, "\n", desc) gsub(/!/, "!!", desc) info = $8 gsub(/\|/, "\\|", info) candidate = word "|info -style menu %!" desc "!|" word " {MenuInfo}" info gsub(/@/, "@@", candidate) gsub(/~/, "~~", candidate) print "%~" candidate "~" }' ) printf %s\\n "evaluate-commands -client '${kak_client}' %@ set-option 'buffer=${kak_bufname}' racer_completions ${compl%?} @" | kak -p ${kak_session} rm -r ${dir} ) > /dev/null 2>&1 < /dev/null & } } define-command racer-enable-autocomplete -docstring "Add racer completion candidates to the completer" %{ set-option window completers option=racer_completions %opt{completers} hook window -group racer-autocomplete InsertIdle .* %{ try %{ execute-keys -draft ([\w\.]|::).\z racer-complete } } alias window complete racer-complete } define-command racer-disable-autocomplete -docstring "Disable racer completion" %{ evaluate-commands %sh{ printf "set-option window completers %s\n" $(printf %s "${kak_opt_completers}" | sed -e "s/'option=racer_completions'//g") } remove-hooks window racer-autocomplete unalias window complete racer-complete } define-command racer-go-definition -docstring "Jump to where the rust identifier below the cursor is defined" %{ evaluate-commands %sh{ dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-racer.XXXXXXXX) printf %s\\n "set-option buffer racer_tmp_dir ${dir}" printf %s\\n "evaluate-commands -no-hooks %{ write ${dir}/buf }" } evaluate-commands %sh{ dir=${kak_opt_racer_tmp_dir} cursor="${kak_cursor_line} $((${kak_cursor_column} - 1))" racer_data=$(racer --interface tab-text find-definition ${cursor} "${kak_buffile}" "${dir}/buf" | head -n 1) racer_match=$(printf %s\\n "$racer_data" | cut -f1 ) if [ "$racer_match" = "MATCH" ]; then racer_line=$(printf %s\\n "$racer_data" | cut -f3 ) racer_column=$(printf %s\\n "$racer_data" | cut -f4 ) racer_file=$(printf %s\\n "$racer_data" | cut -f5 ) printf %s\\n "edit -existing '$racer_file' $racer_line $racer_column" case ${racer_file} in "${RUST_SRC_PATH}"* | "${CARGO_HOME:-$HOME/.cargo}"/registry/src/*) printf %s\\n "set-option buffer readonly true";; esac else printf %s\\n "echo -debug 'racer could not find a definition'" fi } } define-command racer-show-doc -docstring "Show the documentation about the rust identifier below the cursor" %{ evaluate-commands %sh{ dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-racer.XXXXXXXX) printf %s\\n "set-option buffer racer_tmp_dir ${dir}" printf %s\\n "evaluate-commands -no-hooks %{ write ${dir}/buf }" } evaluate-commands %sh{ dir=${kak_opt_racer_tmp_dir} cursor="${kak_cursor_line} ${kak_cursor_column}" racer_data=$(racer --interface tab-text complete-with-snippet ${cursor} "${kak_buffile}" "${dir}/buf" | sed -n 2p ) racer_match=$(printf %s\\n "$racer_data" | cut -f1) if [ "$racer_match" = "MATCH" ]; then racer_doc=$( printf %s\\n "$racer_data" | cut -f9 | sed -e ' # Remove leading and trailing quotes s/^"\(.*\)"$/\1/g # Escape all @ so that it can be properly used in the string expansion s/@/\\@/g ') printf "info %%@$racer_doc@" else printf %s\\n "echo -debug 'racer could not find a definition'" fi } } } kakoune-2019.07.01/rc/tools/spell.kak000066400000000000000000000113021350637360100171240ustar00rootroot00000000000000declare-option -hidden range-specs spell_regions declare-option -hidden str spell_lang declare-option -hidden str spell_tmp_file define-command -params ..1 \ -docstring %{spell []: spell check the current buffer The first optional argument is the language against which the check will be performed Formats of language supported: - ISO language code, e.g. 'en' - language code above followed by a dash or underscore with an ISO country code, e.g. 'en-US'} \ spell %{ try %{ add-highlighter window/ ranges 'spell_regions' } evaluate-commands %sh{ file=$(mktemp -d "${TMPDIR:-/tmp}"/kak-spell.XXXXXXXX)/buffer printf 'eval -no-hooks write -sync %s\n' "${file}" printf 'set-option buffer spell_tmp_file %s\n' "${file}" } evaluate-commands %sh{ if [ $# -ge 1 ]; then if [ ${#1} -ne 2 ] && [ ${#1} -ne 5 ]; then echo "echo -markup '{Error}Invalid language code (examples of expected format: en, en_US, en-US)'" rm -rf "$(dirname "$kak_opt_spell_tmp_file")" exit 1 else options="-l '$1'" printf 'set-option buffer spell_lang %s\n' "$1" fi fi { sed 's/^/^/' "$kak_opt_spell_tmp_file" | eval "aspell --byte-offsets -a $options" 2>&1 | { line_num=1 regions=$kak_timestamp read line # drop the identification message while read -r line; do case "$line" in [\#\&]*) if expr "$line" : '^&' >/dev/null; then pos=$(printf %s\\n "$line" | cut -d ' ' -f 4 | sed 's/:$//') else pos=$(printf %s\\n "$line" | cut -d ' ' -f 3) fi word=$(printf %s\\n "$line" | cut -d ' ' -f 2) # trim whitespace to make `wc` output consistent across implementations len=$(($(printf %s "$word" | wc -c))) regions="$regions $line_num.$pos+${len}|Error" ;; '') line_num=$((line_num + 1));; \*) ;; *) printf 'echo -markup %%{{Error}%s}\n' "${line}" | kak -p "${kak_session}";; esac done printf 'set-option "buffer=%s" spell_regions %s' "${kak_bufname}" "${regions}" \ | kak -p "${kak_session}" } rm -rf $(dirname "$kak_opt_spell_tmp_file") } /dev/null 2>&1 & } } define-command spell-clear %{ unset-option buffer spell_regions } define-command spell-next %{ evaluate-commands %sh{ anchor_line="${kak_selection_desc%%.*}" anchor_col="${kak_selection_desc%%,*}" anchor_col="${anchor_col##*.}" start_first="${kak_opt_spell_regions#* }" start_first="${start_first%%|*}" start_first="${start_first#\'}" find_next_word_desc() { ## XXX: the `spell` command adds sorted selection descriptions to the range printf %s\\n "${1}" \ | sed -e "s/'//g" -e 's/^[0-9]* //' -e 's/|[^ ]*//g' \ | tr ' ' '\n' \ | while IFS=, read -r start end; do start_line="${start%.*}" start_col="${start#*.}" end_line="${end%.*}" end_col="${end#*.}" if [ "${start_line}" -lt "${anchor_line}" ]; then continue elif [ "${start_line}" -eq "${anchor_line}" ] \ && [ "${start_col}" -le "${anchor_col}" ]; then continue fi printf 'select %s,%s\n' "${start}" "${end}" break done } # no selection descriptions are in `spell_regions` if ! expr "${start_first}" : '[0-9][0-9]*\.[0-9][0-9]*,[0-9][0-9]*\.[0-9]' >/dev/null; then exit fi next_word_desc=$(find_next_word_desc "${kak_opt_spell_regions}") if [ -n "${next_word_desc}" ]; then printf %s\\n "${next_word_desc}" else printf 'select %s\n' "${start_first}" fi } } define-command spell-replace %{ evaluate-commands %sh{ if [ -n "$kak_opt_spell_lang" ]; then options="-l '$kak_opt_spell_lang'" fi suggestions=$(printf %s "$kak_selection" | eval "aspell -a $options" | grep '^&' | cut -d: -f2) menu=$(printf %s "${suggestions#?}" | awk -F', ' ' { for (i=1; i<=NF; i++) printf "%s", "%{"$i"}" "%{execute-keys -itersel %{c"$i"be}}" } ') printf 'try %%{ menu -auto-single %s }' "${menu}" } } kakoune-2019.07.01/rc/windowing/000077500000000000000000000000001350637360100161655ustar00rootroot00000000000000kakoune-2019.07.01/rc/windowing/iterm.kak000066400000000000000000000130121350637360100177720ustar00rootroot00000000000000# https://www.iterm2.com # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ ## The default behaviour for the `terminal` command is to open a vertical pane in ## an iTerm session if not in a tmux session. hook global KakBegin .* %sh{ if [ "$TERM_PROGRAM" = "iTerm.app" ] && [ -z "$TMUX" ]; then echo "require-module iterm" fi } provide-module iterm %{ define-command -hidden -params 2.. iterm-terminal-split-impl %{ nop %sh{ direction="$1" shift # join the arguments as one string for the shell execution (see x11.kak) args=$( for i in "$@"; do if [ "$i" = '' ]; then printf "'' " else printf %s "$i" | sed -e "s|'|'\\\\''|g; s|^|'|; s|$|' |" fi done ) # go through another round of escaping for osascript # \ -> \\ # " -> \" escaped=$(printf %s "$args" | sed -e 's|\\|\\\\|g; s|"|\\"|g') cmd="env PATH='${PATH}' TMPDIR='${TMPDIR}' $escaped" osascript \ -e "tell application \"iTerm\"" \ -e " tell current session of current window" \ -e " tell (split ${direction} with same profile command \"${cmd}\") to select" \ -e " end tell" \ -e "end tell" >/dev/null } } define-command iterm-terminal-vertical -params 1.. -shell-completion -docstring ' iterm-terminal-vertical []: create a new terminal as an iterm pane The current pane is split into two, left and right The program passed as argument will be executed in the new terminal'\ %{ iterm-terminal-split-impl 'vertically' %arg{@} } define-command iterm-terminal-horizontal -params 1.. -shell-completion -docstring ' iterm-terminal-horizontal []: create a new terminal as an iterm pane The current pane is split into two, top and bottom The program passed as argument will be executed in the new terminal'\ %{ iterm-terminal-split-impl 'horizontally' %arg{@} } define-command iterm-terminal-tab -params 1.. -shell-completion -docstring ' iterm-terminal-tab []: create a new terminal as an iterm tab The program passed as argument will be executed in the new terminal'\ %{ nop %sh{ # see above args=$( for i in "$@"; do if [ "$i" = '' ]; then printf "'' " else printf %s "$i" | sed -e "s|'|'\\\\''|g; s|^|'|; s|$|' |" fi done ) escaped=$(printf %s "$args" | sed -e 's|\\|\\\\|g; s|"|\\"|g') cmd="env PATH='${PATH}' TMPDIR='${TMPDIR}' $escaped" osascript \ -e "tell application \"iTerm\"" \ -e " tell current window" \ -e " create tab with default profile command \"${cmd}\"" \ -e " end tell" \ -e "end tell" >/dev/null } } define-command iterm-terminal-window -params 1.. -shell-completion -docstring ' iterm-terminal-window []: create a new terminal as an iterm window The program passed as argument will be executed in the new terminal'\ %{ nop %sh{ # see above args=$( for i in "$@"; do if [ "$i" = '' ]; then printf "'' " else printf %s "$i" | sed -e "s|'|'\\\\''|g; s|^|'|; s|$|' |" fi done ) escaped=$(printf %s "$args" | sed -e 's|\\|\\\\|g; s|"|\\"|g') cmd="env PATH='${PATH}' TMPDIR='${TMPDIR}' $escaped" osascript \ -e "tell application \"iTerm\"" \ -e " create window with default profile command \"${cmd}\"" \ -e "end tell" >/dev/null } } define-command iterm-focus -params ..1 -client-completion -docstring ' iterm-focus []: focus the given client If no client is passed then the current one is used' \ %{ evaluate-commands %sh{ if [ $# -eq 1 ]; then printf %s\\n "evaluate-commands -client '$1' focus" else session="${kak_client_env_ITERM_SESSION_ID#*:}" osascript \ -e "tell application \"iTerm\" to repeat with aWin in windows" \ -e " tell aWin to repeat with aTab in tabs" \ -e " tell aTab to repeat with aSession in sessions" \ -e " tell aSession" \ -e " if (unique id = \"${session}\") then" \ -e " select" \ -e " end if" \ -e " end tell" \ -e " end repeat" \ -e " end repeat" \ -e "end repeat" fi } } alias global focus iterm-focus alias global terminal iterm-terminal-vertical } kakoune-2019.07.01/rc/windowing/kitty.kak000066400000000000000000000044151350637360100200250ustar00rootroot00000000000000 hook -group kitty-hooks global KakBegin .* %sh{ if [ "$TERM" = "xterm-kitty" ] && [ -z "$TMUX" ]; then echo "require-module kitty" fi } provide-module kitty %{ declare-option -docstring %{window type that kitty creates on new and repl calls (kitty|os)} str kitty_window_type kitty define-command kitty-terminal -params 1.. -shell-completion -docstring ' kitty-terminal []: create a new terminal as a kitty window The program passed as argument will be executed in the new terminal' \ %{ nop %sh{ kitty @ new-window --no-response --window-type $kak_opt_kitty_window_type --cwd "$PWD" "$@" } } define-command kitty-terminal-tab -params 1.. -shell-completion -docstring ' kitty-terminal-tab []: create a new terminal as kitty tab The program passed as argument will be executed in the new terminal' \ %{ nop %sh{ kitty @ new-window --no-response --new-tab --cwd "$PWD" "$@" } } define-command kitty-focus -params ..1 -client-completion -docstring ' kitty-focus []: focus the given client If no client is passed then the current one is used' \ %{ evaluate-commands %sh{ if [ $# -eq 1 ]; then printf "evaluate-commands -client '%s' focus" "$1" else kitty @ focus-tab --no-response -m=id:$kak_client_env_KITTY_WINDOW_ID kitty @ focus-window --no-response -m=id:$kak_client_env_KITTY_WINDOW_ID fi } } define-command kitty-repl -params .. -shell-completion -docstring ' kitty-repl []: create a new window for repl interaction All optional parameters are forwarded to the new window' \ %{ nop %sh{ if [ $# -eq 0 ]; then cmd="${SHELL:-/bin/sh}" else cmd="$*" fi kitty @ new-window --no-response --window-type $kak_opt_kitty_window_type --title kak_repl_window --cwd "$PWD" $cmd < /dev/null > /dev/null 2>&1 & } } define-command kitty-send-text -docstring "send the selected text to the repl window" %{ nop %sh{ kitty @ send-text -m=title:kak_repl_window "${kak_selection}" } } alias global terminal kitty-terminal alias global terminal-tab kitty-terminal-tab alias global focus kitty-focus alias global repl kitty-repl alias global send-text kitty-send-text } kakoune-2019.07.01/rc/windowing/new-client.kak000066400000000000000000000006531350637360100207260ustar00rootroot00000000000000define-command new -params .. -command-completion -docstring ' new []: create a new kakoune client The ''terminal'' alias is being used to determine the user''s preferred terminal emulator The optional arguments are passed as commands to the new client' \ %{ try %{ terminal kak -c %val{session} -e "%arg{@}" } catch %{ fail "The 'terminal' alias must be defined to use this command" } } kakoune-2019.07.01/rc/windowing/repl/000077500000000000000000000000001350637360100171275ustar00rootroot00000000000000kakoune-2019.07.01/rc/windowing/repl/tmux.kak000066400000000000000000000045131350637360100206170ustar00rootroot00000000000000# http://tmux.github.io/ # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global ModuleLoaded tmux %{ require-module tmux-repl } provide-module tmux-repl %{ declare-option -docstring "tmux pane id in which the REPL is running" str tmux_repl_id define-command -hidden -params 1..2 tmux-repl-impl %{ evaluate-commands %sh{ if [ -z "$TMUX" ]; then echo "echo -markup '{Error}This command is only available in a tmux session'" exit fi tmux_args="$1" shift tmux_cmd="$@" tmux $tmux_args $tmux_cmd printf "set-option global tmux_repl_id '%s'" $(tmux display-message -p '#{session_id}:#{window_id}.#{pane_id}') } } define-command tmux-repl-vertical -params 0..1 -command-completion -docstring "Create a new vertical pane for repl interaction" %{ tmux-repl-impl 'split-window -v' %arg{@} } define-command tmux-repl-horizontal -params 0..1 -command-completion -docstring "Create a new horizontal pane for repl interaction" %{ tmux-repl-impl 'split-window -h' %arg{@} } define-command tmux-repl-window -params 0..1 -command-completion -docstring "Create a new window for repl interaction" %{ tmux-repl-impl 'new-window' %arg{@} } define-command -hidden tmux-send-text -params 0..1 -docstring "tmux-send-text [text]: Send text(append new line) to the REPL pane. If no text is passed, then the selection is used" %{ nop %sh{ if [ $# -eq 0 ]; then tmux set-buffer -b kak_selection "${kak_selection}" else tmux set-buffer -b kak_selection "$1" fi tmux paste-buffer -b kak_selection -t "$kak_opt_tmux_repl_id" } } define-command -hidden tmux-repl-disabled %{ evaluate-commands %sh{ VERSION_TMUX=$(tmux -V) printf %s "echo -markup %{{Error}The version of tmux is too old: got ${VERSION_TMUX}, expected >= 2.x}" } } evaluate-commands %sh{ VERSION_TMUX=$(tmux -V | cut -d' ' -f2) VERSION_TMUX=${VERSION_TMUX%%.*} if [ "${VERSION_TMUX}" = "master" ] \ || [ "${VERSION_TMUX}" -ge 2 ]; then echo " alias global repl tmux-repl-horizontal alias global send-text tmux-send-text " else echo " alias global repl tmux-repl-disabled alias global send-text tmux-repl-disabled " fi } } kakoune-2019.07.01/rc/windowing/repl/x11.kak000066400000000000000000000022541350637360100202330ustar00rootroot00000000000000hook global ModuleLoaded x11 %{ require-module x11-repl } provide-module x11-repl %{ # termcmd should already be set in x11.kak define-command -docstring %{x11-repl []: create a new window for repl interaction All optional parameters are forwarded to the new window} \ -params .. \ -shell-completion \ x11-repl %{ evaluate-commands %sh{ if [ -z "${kak_opt_termcmd}" ]; then echo "echo -markup '{Error}termcmd option is not set'" exit fi if [ $# -eq 0 ]; then cmd="${SHELL:-sh}"; else cmd="$@"; fi # The escape sequence in the printf command sets the terminal's title: setsid ${kak_opt_termcmd} "printf '\e]2;kak_repl_window\a' \ && ${cmd}" < /dev/null > /dev/null 2>&1 & }} define-command x11-send-text -docstring "send the selected text to the repl window" %{ nop %sh{ printf %s\\n "${kak_selection}" | xsel -i wid=$(xdotool getactivewindow) xdotool search --name kak_repl_window windowactivate xdotool key --clearmodifiers "Shift+Insert" xdotool windowactivate $wid } } alias global repl x11-repl alias global send-text x11-send-text } kakoune-2019.07.01/rc/windowing/screen.kak000066400000000000000000000047651350637360100201500ustar00rootroot00000000000000# http://gnu.org/software/screen/ # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook -group GNUscreen global KakBegin .* %sh{ [ -z "${STY}" ] && exit echo "require-module screen" } provide-module screen %{ define-command screen-terminal-impl -hidden -params 3.. %{ nop %sh{ tty="$(ps -o tty ${kak_client_pid} | tail -n 1)" screen -X eval "$1" "$2" shift 2 # see x11.kak for what this achieves args=$( for i in "$@"; do if [ "$i" = '' ]; then printf "'' " else printf %s "$i" | sed -e "s|'|'\\\\''|g; s|^|'|; s|$|' |" fi done ) screen -X screen sh -c "${args} ; screen -X remove" < "/dev/$tty" } } define-command screen-terminal-vertical -params 1.. -shell-completion -docstring ' screen-terminal-vertical [] []: create a new terminal as a screen pane The current pane is split into two, left and right The program passed as argument will be executed in the new terminal' \ %{ screen-terminal-impl 'split -v' 'focus right' %arg{@} } define-command screen-terminal-horizontal -params 1.. -shell-completion -docstring ' screen-terminal-horizontal []: create a new terminal as a screen pane The current pane is split into two, top and bottom The program passed as argument will be executed in the new terminal' \ %{ screen-terminal-impl 'split -h' 'focus down' %arg{@} } define-command screen-terminal-window -params 1.. -shell-completion -docstring ' screen-terminal-window []: create a new terminal as a screen window The program passed as argument will be executed in the new terminal' \ %{ nop %sh{ tty="$(ps -o tty ${kak_client_pid} | tail -n 1)" screen -X screen "$@" < "/dev/$tty" } } define-command screen-focus -params ..1 -client-completion -docstring ' screen-focus []: focus the given client If no client is passed then the current one is used' \ %{ evaluate-commands %sh{ if [ $# -eq 1 ]; then printf %s\\n " evaluate-commands -client '$1' focus " elif [ -n "${kak_client_env_STY}" ]; then tty="$(ps -o tty ${kak_client_pid} | tail -n 1)" screen -X select "${kak_client_env_WINDOW}" < "/dev/$tty" fi } } alias global focus screen-focus alias global terminal screen-terminal-vertical } kakoune-2019.07.01/rc/windowing/tmux.kak000066400000000000000000000045341350637360100176600ustar00rootroot00000000000000# http://tmux.github.io/ # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global KakBegin .* %sh{ if [ -n "$TMUX" ]; then echo "require-module tmux" fi } provide-module tmux %{ define-command -hidden -params 2.. tmux-terminal-impl %{ evaluate-commands %sh{ tmux=${kak_client_env_TMUX:-$TMUX} if [ -z "$tmux" ]; then echo "fail 'This command is only available in a tmux session'" exit fi tmux_args="$1" shift # ideally we should escape single ';' to stop tmux from interpreting it as a new command # but that's probably too rare to care TMUX=$tmux tmux $tmux_args env TMPDIR="$TMPDIR" "$@" < /dev/null > /dev/null 2>&1 & } } define-command tmux-terminal-vertical -params 1.. -shell-completion -docstring ' tmux-terminal-vertical []: create a new terminal as a tmux pane The current pane is split into two, top and bottom The program passed as argument will be executed in the new terminal' \ %{ tmux-terminal-impl 'split-window -v' %arg{@} } define-command tmux-terminal-horizontal -params 1.. -shell-completion -docstring ' tmux-terminal-horizontal []: create a new terminal as a tmux pane The current pane is split into two, left and right The program passed as argument will be executed in the new terminal' \ %{ tmux-terminal-impl 'split-window -h' %arg{@} } define-command tmux-terminal-window -params 1.. -shell-completion -docstring ' tmux-terminal-window [] []: create a new terminal as a tmux window The program passed as argument will be executed in the new terminal' \ %{ tmux-terminal-impl 'new-window' %arg{@} } define-command tmux-focus -params ..1 -client-completion -docstring ' tmux-focus []: focus the given client If no client is passed then the current one is used' \ %{ evaluate-commands %sh{ if [ $# -eq 1 ]; then printf "evaluate-commands -client '%s' focus" "$1" elif [ -n "${kak_client_env_TMUX}" ]; then TMUX="${kak_client_env_TMUX}" tmux select-pane -t "${kak_client_env_TMUX_PANE}" > /dev/null fi } } ## The default behaviour for the `new` command is to open an horizontal pane in a tmux session alias global focus tmux-focus alias global terminal tmux-terminal-horizontal } kakoune-2019.07.01/rc/windowing/x11.kak000066400000000000000000000055371350637360100173000ustar00rootroot00000000000000# x11 hook global KakBegin .* %sh{ if [ -n "$DISPLAY" ] && [ -z "$TMUX" ]; then echo "require-module x11" fi } provide-module x11 %{ # termcmd should be set such as the next argument is the whole # command line to execute declare-option -docstring %{shell command run to spawn a new terminal A shell command is appended to the one set in this option at runtime} \ str termcmd %sh{ for termcmd in 'alacritty -e sh -c' \ 'kitty sh -c' \ 'termite -e ' \ 'urxvt -e sh -c' \ 'rxvt -e sh -c' \ 'st -e sh -c' \ 'xterm -e sh -c' \ 'roxterm -e sh -c' \ 'mintty -e sh -c' \ 'sakura -x ' \ 'gnome-terminal -e ' \ 'xfce4-terminal -e ' \ 'konsole -e '; do terminal=${termcmd%% *} if command -v $terminal >/dev/null 2>&1; then printf %s\\n "$termcmd" exit fi done } define-command x11-terminal -params 1.. -shell-completion -docstring ' x11-terminal []: create a new terminal as an x11 window The program passed as argument will be executed in the new terminal' \ %{ evaluate-commands %sh{ if [ -z "${kak_opt_termcmd}" ]; then echo "fail 'termcmd option is not set'" exit fi # join arguments into a single string, in which they're delimited # by single quotes, and with single quotes inside transformed to '\'' # so that sh -c "$args" will re-split the arguments properly # example: # $1 = ab # $2 = foo bar # $3 = # $4 = foo'bar # $args = 'ab' 'foo bar' '' 'foo'\''bar' # would be nicer to do in a single sed/awk call but that's difficult args=$( for i in "$@"; do # special case to preserve empty variables as sed will not touch these if [ "$i" = '' ]; then printf "'' " else printf %s "$i" | sed -e "s|'|'\\\\''|g; s|^|'|; s|$|' |" fi done ) setsid ${kak_opt_termcmd} "$args" < /dev/null > /dev/null 2>&1 & } } define-command x11-focus -params ..1 -client-completion -docstring ' x11-focus []: focus a given client''s window If no client is passed, then the current client is used' \ %{ evaluate-commands %sh{ if [ $# -eq 1 ]; then printf "evaluate-commands -client '%s' focus" "$1" else xdotool windowactivate $kak_client_env_WINDOWID > /dev/null fi } } alias global focus x11-focus alias global terminal x11-terminal } kakoune-2019.07.01/share/000077500000000000000000000000001350637360100146565ustar00rootroot00000000000000kakoune-2019.07.01/share/kak/000077500000000000000000000000001350637360100154245ustar00rootroot00000000000000kakoune-2019.07.01/share/kak/autoload000077700000000000000000000000001350637360100201272../../rcustar00rootroot00000000000000kakoune-2019.07.01/share/kak/colors000077700000000000000000000000001350637360100205152../../colorsustar00rootroot00000000000000kakoune-2019.07.01/share/kak/doc000077700000000000000000000000001350637360100204032../../doc/pages/ustar00rootroot00000000000000kakoune-2019.07.01/share/kak/gdb000077700000000000000000000000001350637360100172622../../gdb/ustar00rootroot00000000000000kakoune-2019.07.01/share/kak/kakrc000066400000000000000000000027221350637360100164450ustar00rootroot00000000000000def -params 1 -docstring "colorscheme : enable named colorscheme" \ -shell-script-candidates %{ find -L "${kak_runtime}/colors" "${kak_config}/colors" -type f -name '*\.kak' \ | while read -r filename; do basename="${filename##*/}" printf %s\\n "${basename%.*}" done | sort -u } \ colorscheme %{ evaluate-commands %sh{ find_colorscheme() { find -L "${1}" -type f -name "${2}".kak | head -n 1 } if [ -d "${kak_config}/colors" ]; then filename=$(find_colorscheme "${kak_config}/colors" "${1}") fi if [ -z "${filename}" ]; then filename=$(find_colorscheme "${kak_runtime}/colors" "${1}") fi if [ -n "${filename}" ]; then printf 'source %%{%s}' "${filename}" else echo "echo -markup '{Error}No such colorscheme'" fi }} evaluate-commands %sh{ autoload_directory() { find -L "$1" -type f -name '*\.kak' \ | sed 's/.*/try %{ source "&" } catch %{ echo -debug Autoload: could not load "&" }/' } echo "colorscheme default" if [ -d "${kak_config}/autoload" ]; then autoload_directory ${kak_config}/autoload elif [ -d "${kak_runtime}/autoload" ]; then autoload_directory ${kak_runtime}/autoload fi if [ -f "${kak_runtime}/kakrc.local" ]; then echo "source '${kak_runtime}/kakrc.local'" fi if [ -f "${kak_config}/kakrc" ]; then echo "source '${kak_config}/kakrc'" fi } kakoune-2019.07.01/share/kak/rc000077700000000000000000000000001350637360100167232../../rcustar00rootroot00000000000000kakoune-2019.07.01/src/000077500000000000000000000000001350637360100143435ustar00rootroot00000000000000kakoune-2019.07.01/src/.gdbinit000066400000000000000000000000611350637360100157610ustar00rootroot00000000000000set print pretty break Kakoune::on_assert_failed kakoune-2019.07.01/src/Makefile000066400000000000000000000117461350637360100160140ustar00rootroot00000000000000debug ?= no static ?= no gzip_man ?= yes ifneq ($(gzip_man),yes) ifneq ($(gzip_man),no) $(error gzip_man should be either yes or no) endif endif ifeq ($(debug),yes) CPPFLAGS += -DKAK_DEBUG CXXFLAGS += -Og suffix := .debug else ifeq ($(debug),no) CXXFLAGS += -O3 suffix := .opt else $(error debug should be either yes or no) endif endif ifneq (,$(findstring address,$(sanitize))) CPPFLAGS += -fsanitize=address LDFLAGS += -lasan sanitize_suffix := $(sanitize_suffix)a endif ifneq (,$(findstring undefined,$(sanitize))) CPPFLAGS += -fsanitize=undefined LDFLAGS += -lubsan sanitize_suffix := $(sanitize_suffix)u endif ifneq (,$(sanitize_suffix)) suffix := $(suffix).san_$(sanitize_suffix) endif version ?= $(shell if [ -f .version ]; then cat .version; elif [ -d ../.git ]; then git describe --tags HEAD; else echo "unknown"; fi) sources := $(sort $(wildcard *.cc)) objects := $(addprefix ., $(sources:.cc=$(suffix).o)) deps := $(addprefix ., $(sources:.cc=$(suffix).d)) PKG_CONFIG ?= $(shell command -v pkg-config 2>/dev/null) ifeq ($(static),yes) PKG_CONFIG_FLAGS += --static LDFLAGS += -static -pthread endif PREFIX ?= /usr/local DESTDIR ?= # root dir bindir := $(DESTDIR)$(PREFIX)/bin sharedir := $(DESTDIR)$(PREFIX)/share/kak docdir := $(DESTDIR)$(PREFIX)/share/doc/kak mandir := $(DESTDIR)$(PREFIX)/share/man/man1 os := $(shell uname) ifeq ($(os),Darwin) LIBS += -lncurses NCURSES_CFLAGS += -I$(PREFIX)/opt/ncurses/include CPPFLAGS += -I/opt/local/include LDFLAGS += -L$(PREFIX)/opt/ncurses/lib -L/opt/local/lib else ifeq ($(os),FreeBSD) LIBS += -ltinfow -lncursesw CPPFLAGS += -I/usr/local/include LDFLAGS += -L/usr/local/lib else ifeq ($(os),Haiku) LIBS += -lncursesw -lnetwork -lbe else ifeq ($(os),OpenBSD) LIBS += -lncursesw CPPFLAGS += -D'KAK_BIN_PATH="$(bindir)/kak"' -I/usr/local/include LDFLAGS += -L/usr/local/lib mandir := $(DESTDIR)$(PREFIX)/man/man1 else ifneq (,$(findstring CYGWIN,$(os))) CPPFLAGS += -D_XOPEN_SOURCE=700 LIBS += -lncursesw -ldbghelp else ifeq ($(PKG_CONFIG),) $(error "pkg-config not found in PATH") endif LIBS += $(shell $(PKG_CONFIG) $(PKG_CONFIG_FLAGS) --libs ncursesw) NCURSES_CFLAGS += $(shell $(PKG_CONFIG) $(PKG_CONFIG_FLAGS) --cflags ncursesw) LDFLAGS += -rdynamic endif CXXFLAGS += -pedantic -std=c++17 -g -Wall -Wextra -Wno-unused-parameter -Wno-sign-compare -Wno-address all : kak kak : kak$(suffix) ln -sf $< $@ kak$(suffix) : $(objects) .version.o $(CXX) $(LDFLAGS) $(CXXFLAGS) $(objects) .version.o $(LIBS) -o $@ -include $(deps) .%$(suffix).o: %.cc $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MD -MP -MF $(addprefix ., $(<:.cc=$(suffix).d)) -c -o $@ $< .ncurses_ui$(suffix).o: CPPFLAGS += $(NCURSES_CFLAGS) .version.o: .version.cc $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $< .version.cc: FORCE @printf "%s" 'namespace Kakoune { const char* version = "$(version)"; }' > .version.cc.tmp @if cmp -s .version.cc.tmp .version.cc; then rm .version.cc.tmp; else mv .version.cc.tmp .version.cc; fi # Generate the man page ifeq ($(gzip_man),yes) ../doc/kak.1.gz: ../doc/kak.1 gzip -n -9 -f < $< > $@ man: ../doc/kak.1.gz else man: ../doc/kak.1 endif check: test test: kak cd ../test && ./run TAGS: tags tags: ctags -R clean: rm -f .*.o .*.d dist: @if ! [ -d ../.git ]; then echo "make dist can only run from a git repo"; false; fi @if git status -s | grep -qEv '^\?\?'; then echo "working tree is not clean"; false; fi cd ../; \ basename="kakoune-$$(echo "$(version)" | sed -e s/^v//)"; \ git archive --format=tar --prefix=$${basename}/ HEAD -o $${basename}.tar; \ echo "$(version)" > src/.version; \ tar --transform "s,^,$${basename}/," -rf $${basename}.tar src/.version; \ rm src/.version; \ bzip2 $${basename}.tar; distclean: clean rm -f kak kak$(suffix) find ../doc -type f \( -name \*\\.gz -o -name \*\\.1 \) -exec rm -f '{}' + installdirs: install -d $(bindir) \ $(sharedir)/rc \ $(sharedir)/colors \ $(sharedir)/doc \ $(docdir) \ $(mandir) install: kak man installdirs install -m 0755 kak $(bindir) install -m 0644 ../share/kak/kakrc $(sharedir) install -m 0644 ../doc/pages/*.asciidoc $(sharedir)/doc cp -r ../rc/* $(sharedir)/rc find $(sharedir)/rc -type f -exec chmod 0644 {} + [ -e $(sharedir)/autoload ] || ln -s rc $(sharedir)/autoload install -m 0644 ../colors/* $(sharedir)/colors install -m 0644 ../README.asciidoc $(docdir) ifeq ($(gzip_man),yes) install -m 0644 ../doc/kak.1.gz $(mandir) else install -m 0644 ../doc/kak.1 $(mandir) endif install-strip: install strip -s $(bindir)/kak uninstall: rm -rf $(bindir)/kak \ $(sharedir) \ $(docdir) \ $(mandir)/kak.1.gz \ $(mandir)/kak.1 .PHONY: check TAGS clean dist distclean installdirs install install-strip uninstall .PHONY: tags test man kak FORCE kakoune-2019.07.01/src/alias_registry.cc000066400000000000000000000021251350637360100176730ustar00rootroot00000000000000#include "alias_registry.hh" #include "command_manager.hh" #include "ranges.hh" namespace Kakoune { void AliasRegistry::add_alias(String alias, String command) { kak_assert(not alias.empty()); kak_assert(CommandManager::instance().command_defined(command)); auto it = m_aliases.find(alias); if (it == m_aliases.end()) m_aliases.insert({std::move(alias), std::move(command) }); else it->value = std::move(command); } void AliasRegistry::remove_alias(StringView alias) { m_aliases.remove(alias); } StringView AliasRegistry::operator[](StringView alias) const { auto it = m_aliases.find(alias); if (it != m_aliases.end()) return it->value; else if (m_parent) return (*m_parent)[alias]; else return StringView{}; } Vector AliasRegistry::aliases_for(StringView command) const { Vector res; if (m_parent) res = m_parent->aliases_for(command); for (auto& alias : m_aliases) { if (alias.value == command) res.emplace_back(alias.key); } return res; } } kakoune-2019.07.01/src/alias_registry.hh000066400000000000000000000024711350637360100177110ustar00rootroot00000000000000#ifndef alias_registry_hh_INCLUDED #define alias_registry_hh_INCLUDED #include "safe_ptr.hh" #include "string.hh" #include "hash_map.hh" namespace Kakoune { class AliasRegistry : public SafeCountable { public: AliasRegistry(AliasRegistry& parent) : SafeCountable{}, m_parent(&parent) {} void add_alias(String alias, String command); void remove_alias(StringView alias); StringView operator[](StringView alias) const; Vector aliases_for(StringView command) const; auto flatten_aliases() const { auto merge = [](auto&& first, const AliasMap& second) { return concatenated(std::forward(first) | filter([&second](auto& i) { return not second.contains(i.key); }), second); }; static const AliasMap empty; auto& parent = m_parent ? m_parent->m_aliases : empty; auto& grand_parent = (m_parent and m_parent->m_parent) ? m_parent->m_parent->m_aliases : empty; return merge(merge(grand_parent, parent), m_aliases); } private: friend class Scope; AliasRegistry() = default; SafePtr m_parent; using AliasMap = HashMap; AliasMap m_aliases; }; } #endif // alias_registry_hh_INCLUDED kakoune-2019.07.01/src/array_view.hh000066400000000000000000000051271350637360100170410ustar00rootroot00000000000000#ifndef array_view_hh_INCLUDED #define array_view_hh_INCLUDED #include #include namespace Kakoune { // An ArrayView provides a typed, non owning view of a memory // range with an interface similar to std::vector. template class ArrayView { public: using size_t = std::size_t; constexpr ArrayView() : m_pointer(nullptr), m_size(0) {} constexpr ArrayView(T& oneval) : m_pointer(&oneval), m_size(1) {} constexpr ArrayView(T* pointer, size_t size) : m_pointer(pointer), m_size(size) {} constexpr ArrayView(T* begin, T* end) : m_pointer(begin), m_size(end - begin) {} template constexpr ArrayView(T(&array)[N]) : m_pointer(array), m_size(N) {} template().data())) == sizeof(T)>> constexpr ArrayView(const Container& c) : m_pointer(c.data()), m_size(c.size()) {} constexpr ArrayView(const std::initializer_list& v) : m_pointer(v.begin()), m_size(v.size()) {} constexpr T* pointer() const { return m_pointer; } constexpr size_t size() const { return m_size; } [[gnu::always_inline]] constexpr T& operator[](size_t n) const { return *(m_pointer + n); } constexpr T* begin() const { return m_pointer; } constexpr T* end() const { return m_pointer+m_size; } using reverse_iterator = std::reverse_iterator; constexpr reverse_iterator rbegin() const { return reverse_iterator(m_pointer+m_size); } constexpr reverse_iterator rend() const { return reverse_iterator(m_pointer); } constexpr T& front() const { return *m_pointer; } constexpr T& back() const { return *(m_pointer + m_size - 1); } constexpr bool empty() const { return m_size == 0; } constexpr ArrayView subrange(size_t first, size_t count = -1) const { auto min = [](size_t a, size_t b) { return a < b ? a : b; }; return ArrayView(m_pointer + min(first, m_size), min(count, m_size - min(first, m_size))); } private: T* m_pointer; size_t m_size; }; template using ConstArrayView = ArrayView; template bool operator==(ArrayView lhs, ArrayView rhs) { if (lhs.size() != rhs.size()) return false; for (int i = 0; i < lhs.size(); ++i) { if (lhs[i] != rhs[i]) return false; } return true; } template bool operator!=(ArrayView lhs, ArrayView rhs) { return not (lhs == rhs); } } #endif // array_view_hh_INCLUDED kakoune-2019.07.01/src/assert.cc000066400000000000000000000023301350637360100161510ustar00rootroot00000000000000#include "assert.hh" #include "backtrace.hh" #include "buffer_utils.hh" #include "exception.hh" #if defined(__CYGWIN__) #include #endif #include #include #include namespace Kakoune { struct assert_failed : logic_error { assert_failed(String message) : m_message(std::move(message)) {} StringView what() const override { return m_message; } private: String m_message; }; bool notify_fatal_error(StringView msg) { #if defined(__CYGWIN__) return MessageBox(NULL, msg.zstr(), "Kakoune: fatal error", MB_OKCANCEL | MB_ICONERROR) == IDOK; #elif defined(__linux__) auto cmd = format("xmessage -buttons 'quit:0,ignore:1' '{}'", msg); int status = system(cmd.c_str()); return (WIFEXITED(status)) ? (WEXITSTATUS(status)) == 1 : false; #else return false; #endif } void on_assert_failed(const char* message) { String debug_info = format("pid: {}\ncallstack:\n{}", getpid(), Backtrace{}.desc()); write_to_debug_buffer(format("assert failed: '{}'\n{}", message, debug_info)); const auto msg = format("{}\n[Debug Infos]\n{}", message, debug_info); if (not notify_fatal_error(msg)) throw assert_failed(msg); } } kakoune-2019.07.01/src/assert.hh000066400000000000000000000020321350637360100161620ustar00rootroot00000000000000#ifndef assert_hh_INCLUDED #define assert_hh_INCLUDED namespace Kakoune { class StringView; // return true if user asked to ignore the error bool notify_fatal_error(StringView message); void on_assert_failed(const char* message); } #define STRINGIFY(X) #X #define TOSTRING(X) STRINGIFY(X) #ifdef KAK_DEBUG #define kak_assert(...) do { \ if (not (__VA_ARGS__)) \ on_assert_failed("assert failed \"" #__VA_ARGS__ \ "\" at " __FILE__ ":" TOSTRING(__LINE__)); \ } while (false) #define kak_expect_throw(exception_type, ...) try {\ __VA_ARGS__; \ on_assert_failed("expression \"" #__VA_ARGS__ \ "\" did not throw \"" #exception_type \ "\" at " __FILE__ ":" TOSTRING(__LINE__)); \ } catch (exception_type &err) {} #else #define kak_assert(...) do { (void)sizeof(__VA_ARGS__); } while(false) #define kak_expect_throw(_, ...) do { (void)sizeof(__VA_ARGS__); } while(false) #endif #endif // assert_hh_INCLUDED kakoune-2019.07.01/src/backtrace.cc000066400000000000000000000035001350637360100165670ustar00rootroot00000000000000#include "backtrace.hh" #include "string.hh" #if defined(__GLIBC__) || defined(__APPLE__) # include #elif defined(__CYGWIN__) # include # include # include #endif #if defined(__linux__) || defined(__APPLE__) # include #endif namespace Kakoune { Backtrace::Backtrace() { #if defined(__GLIBC__) || defined(__APPLE__) num_frames = backtrace(stackframes, max_frames); #elif defined(__CYGWIN__) num_frames = CaptureStackBackTrace(0, max_frames, stackframes, nullptr); #endif } String Backtrace::desc() const { #if defined(__GLIBC__) || defined(__APPLE__) char** symbols = backtrace_symbols(stackframes, num_frames); ByteCount size = 0; for (int i = 0; i < num_frames; ++i) size += strlen(symbols[i]) + 1; String res; res.reserve(size); for (int i = 0; i < num_frames; ++i) { res += symbols[i]; res += "\n"; } free(symbols); return res; #elif defined(__CYGWIN__) HANDLE process = GetCurrentProcess(); static bool symbols_initialized = false; if (not symbols_initialized) { SymInitialize(process, nullptr, true); symbols_initialized = true; } alignas(SYMBOL_INFO) char symbol_info_buffer[sizeof(SYMBOL_INFO) + 256]; SYMBOL_INFO* symbol_info = reinterpret_cast(symbol_info_buffer); symbol_info->MaxNameLen = 255; symbol_info->SizeOfStruct = sizeof(SYMBOL_INFO); String res; // res.reserve(num_frames * 276); for (int i = 0; i < num_frames; ++i) { SymFromAddr(process, (DWORD64)stackframes[i], 0, symbol_info); char desc[276]; snprintf(desc, 276, "0x%0llx (%s)\n", symbol_info->Address, symbol_info->Name); res += desc; } return res; #else return ""; #endif } } kakoune-2019.07.01/src/backtrace.hh000066400000000000000000000004541350637360100166060ustar00rootroot00000000000000#ifndef backtrace_hh_INCLUDED #define backtrace_hh_INCLUDED namespace Kakoune { class String; struct Backtrace { static constexpr int max_frames = 16; void* stackframes[max_frames]; int num_frames = 0; Backtrace(); String desc() const; }; } #endif // backtrace_hh_INCLUDED kakoune-2019.07.01/src/buffer.cc000066400000000000000000000643071350637360100161350ustar00rootroot00000000000000#include "buffer.hh" #include "assert.hh" #include "buffer_manager.hh" #include "buffer_utils.hh" #include "client.hh" #include "context.hh" #include "diff.hh" #include "file.hh" #include "flags.hh" #include "option_types.hh" #include "ranges.hh" #include "shared_string.hh" #include "unit_tests.hh" #include "utils.hh" #include "window.hh" #include namespace Kakoune { struct ParsedLines { BufferLines lines; ByteOrderMark bom = ByteOrderMark::None; EolFormat eolformat = EolFormat::Lf; }; static ParsedLines parse_lines(StringView data) { ParsedLines res; const char* pos = data.begin(); if (data.substr(0, 3_byte) == "\xEF\xBB\xBF") { res.bom = ByteOrderMark::Utf8; pos = data.begin() + 3; } bool has_crlf = false, has_lf = false; for (auto it = pos; it != data.end(); ++it) { if (*it == '\n') ((it != pos and *(it-1) == '\r') ? has_crlf : has_lf) = true; } const bool crlf = has_crlf and not has_lf; res.eolformat = crlf ? EolFormat::Crlf : EolFormat::Lf; while (pos < data.end()) { const char* eol = std::find(pos, data.end(), '\n'); res.lines.emplace_back(StringData::create({{pos, eol - (crlf and eol != data.end() ? 1 : 0)}, "\n"})); pos = eol + 1; } if (res.lines.empty()) res.lines.emplace_back(StringData::create({"\n"})); return res; } static void apply_options(OptionManager& options, const ParsedLines& parsed_lines) { options.get_local_option("eolformat").set(parsed_lines.eolformat); options.get_local_option("BOM").set(parsed_lines.bom); } Buffer::HistoryNode::HistoryNode(HistoryId parent) : parent{parent}, timepoint{Clock::now()} {} Buffer::Buffer(String name, Flags flags, StringView data, timespec fs_timestamp) : Scope{GlobalScope::instance()}, m_name{(flags & Flags::File) ? real_path(parse_filename(name)) : std::move(name)}, m_display_name{(flags & Flags::File) ? compact_path(m_name) : m_name}, m_flags{flags | Flags::NoUndo}, m_history{{HistoryId::Invalid}}, m_history_id{HistoryId::First}, m_last_save_history_id{HistoryId::First}, m_fs_timestamp{fs_timestamp.tv_sec, fs_timestamp.tv_nsec} { ParsedLines parsed_lines = parse_lines(data); #ifdef KAK_DEBUG for (auto& line : parsed_lines.lines) kak_assert(not (line->length == 0) and line->data()[line->length-1] == '\n'); #endif static_cast(m_lines) = std::move(parsed_lines.lines); m_changes.push_back({ Change::Insert, {0,0}, line_count() }); apply_options(options(), parsed_lines); // now we may begin to record undo data if (not (flags & Flags::NoUndo)) m_flags &= ~Flags::NoUndo; } void Buffer::on_registered() { // Ignore debug buffer, as it can be created in many // corner cases (including while destroying the BufferManager // if a BufClose hooks triggers writing to it). if (m_flags & Flags::Debug) return; options().register_watcher(*this); if (m_flags & Buffer::Flags::NoHooks) { on_option_changed(options()["readonly"]); return; } run_hook_in_own_context(Hook::BufCreate, m_name); if (m_flags & Flags::File) { if (m_flags & Buffer::Flags::New) run_hook_in_own_context(Hook::BufNewFile, m_name); else { kak_assert(m_fs_timestamp != InvalidTime); run_hook_in_own_context(Hook::BufOpenFile, m_name); } } for (auto& option : options().flatten_options() | transform(&std::unique_ptr

{}, strs[0]), option_from_strings(Meta::Type>{}, strs.subrange(1))}; } template inline bool option_add_from_strings(PrefixedList& opt, ConstArrayView str) { return option_add_from_strings(opt.list, str); } } #endif // option_types_hh_INCLUDED kakoune-2019.07.01/src/optional.hh000066400000000000000000000061211350637360100165110ustar00rootroot00000000000000#ifndef optional_hh_INCLUDED #define optional_hh_INCLUDED #include "assert.hh" #include namespace Kakoune { template struct Optional { public: constexpr Optional() : m_valid{false} {} Optional(const T& other) : m_valid{true} { new (&m_value) T(other); } Optional(T&& other) : m_valid{true} { new (&m_value) T(std::move(other)); } Optional(const Optional& other) : m_valid{other.m_valid} { if (m_valid) new (&m_value) T(other.m_value); } Optional(Optional&& other) noexcept(noexcept(new (nullptr) T(std::move(other.m_value)))) : m_valid{other.m_valid} { if (m_valid) new (&m_value) T(std::move(other.m_value)); } Optional& operator=(const Optional& other) { destruct_ifn(); if ((m_valid = other.m_valid)) new (&m_value) T(other.m_value); return *this; } Optional& operator=(Optional&& other) { destruct_ifn(); if ((m_valid = other.m_valid)) new (&m_value) T(std::move(other.m_value)); return *this; } ~Optional() { destruct_ifn(); } constexpr explicit operator bool() const noexcept { return m_valid; } bool operator==(const Optional& other) const { return m_valid == other.m_valid and (not m_valid or m_value == other.m_value); } bool operator!=(const Optional& other) const { return !(*this == other); } template void emplace(Args&&... args) { destruct_ifn(); new (&m_value) T{std::forward(args)...}; m_valid = true; } T& operator*() { kak_assert(m_valid); return m_value; } const T& operator*() const { return *const_cast(*this); } T* operator->() { kak_assert(m_valid); return &m_value; } const T* operator->() const { return const_cast(*this).operator->(); } template struct DecayOptionalImpl { using Type = U; }; template struct DecayOptionalImpl> { using Type = typename DecayOptionalImpl::Type; }; template using DecayOptional = typename DecayOptionalImpl::Type; template auto map(F f) -> Optional()))>> { if (not m_valid) return {}; return {f(m_value)}; } template auto cast() -> Optional { if (not m_valid) return {}; return {(U)m_value}; } template T value_or(U&& fallback) const { return m_valid ? m_value : T{std::forward(fallback)}; } template T value_or_compute(U&& compute_func) const { return m_valid ? m_value : compute_func(); } void reset() { destruct_ifn(); m_valid = false; } private: void destruct_ifn() { if (m_valid) m_value.~T(); } struct Empty {}; union { Empty m_empty; // disable default construction of value T m_value; }; bool m_valid; }; } #endif // optional_hh_INCLUDED kakoune-2019.07.01/src/parameters_parser.cc000066400000000000000000000056341350637360100204010ustar00rootroot00000000000000#include "parameters_parser.hh" #include "flags.hh" namespace Kakoune { String generate_switches_doc(const SwitchMap& switches) { String res; if (switches.empty()) return res; auto switch_len = [](auto& sw) { return sw.key.column_length() + (sw.value.takes_arg ? 5 : 0); }; auto switches_len = switches | transform(switch_len); const ColumnCount maxlen = *std::max_element(switches_len.begin(), switches_len.end()); for (auto& sw : switches) { res += format("-{} {}{}{}\n", sw.key, sw.value.takes_arg ? "" : "", String{' ', maxlen - switch_len(sw) + 1}, sw.value.description); } return res; } ParametersParser::ParametersParser(ParameterList params, const ParameterDesc& desc) : m_params(params) { const bool switches_only_at_start = desc.flags & ParameterDesc::Flags::SwitchesOnlyAtStart; const bool ignore_unknown_switches = desc.flags & ParameterDesc::Flags::IgnoreUnknownSwitches; bool only_pos = desc.flags & ParameterDesc::Flags::SwitchesAsPositional; Vector switch_seen(desc.switches.size(), false); for (size_t i = 0; i < params.size(); ++i) { if (not only_pos and not ignore_unknown_switches and params[i] == "--") only_pos = true; else if (not only_pos and not params[i].empty() and params[i][0_byte] == '-') { StringView switch_name = params[i].substr(1_byte); auto it = desc.switches.find(switch_name); if (it == desc.switches.end()) { if (ignore_unknown_switches) { m_positional_indices.push_back(i); if (switches_only_at_start) only_pos = true; continue; } throw unknown_option(params[i]); } auto switch_index = it - desc.switches.begin(); if (switch_seen[switch_index]) throw runtime_error{format("switch '-{}' specified more than once", it->key)}; switch_seen[switch_index] = true; if (it->value.takes_arg and ++i == params.size()) throw missing_option_value(it->key); m_switches[switch_name.str()] = it->value.takes_arg ? params[i] : StringView{}; } else // positional { if (switches_only_at_start) only_pos = true; m_positional_indices.push_back(i); } } size_t count = m_positional_indices.size(); if (count > desc.max_positionals or count < desc.min_positionals) throw wrong_argument_count(); } Optional ParametersParser::get_switch(StringView name) const { auto it = m_switches.find(name); return it == m_switches.end() ? Optional{} : Optional{it->value}; } } kakoune-2019.07.01/src/parameters_parser.hh000066400000000000000000000077521350637360100204160ustar00rootroot00000000000000#ifndef parameters_parser_hh_INCLUDED #define parameters_parser_hh_INCLUDED #include "exception.hh" #include "hash_map.hh" #include "meta.hh" #include "array_view.hh" #include "optional.hh" #include "flags.hh" #include "string.hh" #include "string_utils.hh" namespace Kakoune { using ParameterList = ConstArrayView; struct parameter_error : public runtime_error { using runtime_error::runtime_error; }; struct unknown_option : public parameter_error { unknown_option(StringView name) : parameter_error(format("unknown option '{}'", name)) {} }; struct missing_option_value: public parameter_error { missing_option_value(StringView name) : parameter_error(format("missing value for option '{}'", name)) {} }; struct wrong_argument_count : public parameter_error { wrong_argument_count() : parameter_error("wrong argument count") {} }; struct SwitchDesc { bool takes_arg; String description; }; using SwitchMap = HashMap; String generate_switches_doc(const SwitchMap& opts); struct ParameterDesc { enum class Flags { None = 0, SwitchesOnlyAtStart = 0b0001, SwitchesAsPositional = 0b0010, IgnoreUnknownSwitches = 0b0100 }; friend constexpr bool with_bit_ops(Meta::Type) { return true; } SwitchMap switches; Flags flags = Flags::None; size_t min_positionals = 0; size_t max_positionals = -1; }; // ParametersParser provides tools to parse command parameters. // There are 3 types of parameters: // * unnamed options, which are accessed by position (ignoring named ones) // * named boolean options, which are enabled using '-name' syntax // * named string options, which are defined using '-name value' syntax struct ParametersParser { // the options defines named options, if they map to true, then // they are understood as string options, else they are understood as // boolean option. ParametersParser(ParameterList params, const ParameterDesc& desc); // Return a valid optional if the switch was given, with // a non empty StringView value if the switch took an argument. Optional get_switch(StringView name) const; struct iterator : std::iterator { iterator(const ParametersParser& parser, size_t index) : m_parser(parser), m_index(index) {} const String& operator*() const { return m_parser[m_index]; } const String* operator->() const { return &m_parser[m_index]; } iterator& operator++() { ++m_index; return *this; } iterator operator++(int) { auto copy = *this; ++m_index; return copy; } bool operator==(const iterator& other) const { kak_assert(&m_parser == &other.m_parser); return m_index == other.m_index; } bool operator!=(const iterator& other) const { return not (*this == other); } private: const ParametersParser& m_parser; size_t m_index; }; // positional parameters count size_t positional_count() const { return m_positional_indices.size(); } // access positional parameter by index const String& operator[] (size_t index) const { kak_assert(index < positional_count()); return m_params[m_positional_indices[index]]; } ConstArrayView positionals_from(size_t first) const { // kak_assert(m_desc.flags & (ParameterDesc::Flags::SwitchesOnlyAtStart | ParameterDesc::Flags::SwitchesAsPositional)); return m_params.subrange(first < m_positional_indices.size() ? m_positional_indices[first] : -1); } iterator begin() const { return iterator(*this, 0); } iterator end() const { return iterator(*this, m_positional_indices.size()); } private: ParameterList m_params; Vector m_positional_indices; HashMap m_switches; }; } #endif // parameters_parser_hh_INCLUDED kakoune-2019.07.01/src/range.hh000066400000000000000000000010221350637360100157530ustar00rootroot00000000000000#ifndef range_hh_INCLUDED #define range_hh_INCLUDED namespace Kakoune { template struct Range { T begin; T end; friend bool operator==(const Range& lhs, const Range& rhs) { return lhs.begin == rhs.begin and lhs.end == rhs.end; } friend bool operator!=(const Range& lhs, const Range& rhs) { return not (lhs == rhs); } friend size_t hash_value(const Range& range) { return hash_values(range.begin, range.end); } }; } #endif // range_hh_INCLUDED kakoune-2019.07.01/src/ranges.cc000066400000000000000000000023711350637360100161340ustar00rootroot00000000000000#include "ranges.hh" #include "unit_tests.hh" #include "string.hh" #include "string_utils.hh" namespace Kakoune { UnitTest test_ranges{[] { auto check_equal = [](auto&& container, ConstArrayView expected) { kak_assert(std::equal(container.begin(), container.end(), expected.begin(), expected.end())); }; check_equal("a,b,c"_sv | split(','), {"a", "b", "c"}); check_equal(",b,c"_sv | split(','), {"", "b", "c"}); check_equal(",b,"_sv | split(','), {"", "b", ""}); check_equal(","_sv | split(','), {"", ""}); check_equal(""_sv | split(','), {}); check_equal("a,b,c,"_sv | split_after(','), {"a,", "b,", "c,"}); check_equal("a,b,c"_sv | split_after(','), {"a,", "b,", "c"}); check_equal(R"(a\,,\,b,\,)"_sv | split(',', '\\') | transform(unescape<',', '\\'>), {"a,", ",b", ","}); check_equal(R"(\,\,)"_sv | split(',', '\\') | transform(unescape<',', '\\'>), {",,"}); check_equal(R"(\\,\\,)"_sv | split(',', '\\') | transform(unescape<',', '\\'>), {R"(\)", R"(\)", ""}); }}; } kakoune-2019.07.01/src/ranges.hh000066400000000000000000000364441350637360100161560ustar00rootroot00000000000000#ifndef ranges_hh_INCLUDED #define ranges_hh_INCLUDED #include #include #include #include #include "constexpr_utils.hh" namespace Kakoune { template struct ViewFactory { Func func; }; template ViewFactory> make_view_factory(Func&& func) { return {std::forward(func)}; } template decltype(auto) operator| (Range&& range, ViewFactory factory) { return factory.func(std::forward(range)); } template struct decay_range_impl { using type = std::decay_t; }; template struct decay_range_impl { using type = Range&; }; template using decay_range = typename decay_range_impl::type; template struct ReverseView { decltype(auto) begin() { return m_range.rbegin(); } decltype(auto) end() { return m_range.rend(); } Range m_range; }; inline auto reverse() { return make_view_factory([](auto&& range) { using Range = decltype(range); return ReverseView>{std::forward(range)}; }); } template using IteratorOf = decltype(std::begin(std::declval())); template using ValueOf = decltype(*std::declval>()); template struct SkipView { auto begin() const { return std::next(std::begin(m_range), m_skip_count); } auto end() const { return std::end(m_range); } Range m_range; size_t m_skip_count; }; inline auto skip(size_t count) { return make_view_factory([count](auto&& range) { using Range = decltype(range); return SkipView>{std::forward(range), count}; }); } template struct FilterView { using RangeIt = IteratorOf; struct Iterator : std::iterator::value_type> { Iterator(Filter& filter, RangeIt it, RangeIt end) : m_it{std::move(it)}, m_end{std::move(end)}, m_filter{&filter} { do_filter(); } decltype(auto) operator*() { return *m_it; } Iterator& operator++() { ++m_it; do_filter(); return *this; } Iterator operator++(int) { auto copy = *this; ++(*this); return copy; } friend bool operator==(const Iterator& lhs, const Iterator& rhs) { return lhs.m_it == rhs.m_it; } friend bool operator!=(const Iterator& lhs, const Iterator& rhs) { return not (lhs == rhs); } const RangeIt& base() const { return m_it; } private: void do_filter() { while (m_it != m_end and not (*m_filter)(*m_it)) ++m_it; } RangeIt m_it; RangeIt m_end; Filter* m_filter; }; Iterator begin() const { return {m_filter, std::begin(m_range), std::end(m_range)}; } Iterator end() const { return {m_filter, std::end(m_range), std::end(m_range)}; } Range m_range; mutable Filter m_filter; }; template inline auto filter(Filter f) { return make_view_factory([f = std::move(f)](auto&& range) { using Range = decltype(range); return FilterView, Filter>{std::forward(range), std::move(f)}; }); } template struct TransformView { using RangeIt = IteratorOf; using ResType = decltype(std::declval()(*std::declval())); struct Iterator { using iterator_category = typename std::iterator_traits::iterator_category; using value_type = std::remove_reference_t; using difference_type = typename std::iterator_traits::difference_type; using pointer = value_type*; using reference = value_type&; Iterator(Transform& transform, RangeIt it) : m_it{std::move(it)}, m_transform{&transform} {} decltype(auto) operator*() { return (*m_transform)(*m_it); } decltype(auto) operator[](difference_type i) const { return (*m_transform)(m_it[i]); } Iterator& operator++() { ++m_it; return *this; } Iterator operator++(int) { auto copy = *this; ++m_it; return copy; } Iterator& operator--() { --m_it; return *this; } Iterator operator--(int) { auto copy = *this; --m_it; return copy; } Iterator& operator+=(difference_type diff) { m_it += diff; return *this; } Iterator& operator-=(difference_type diff) { m_it -= diff; return *this; } Iterator operator+(difference_type diff) { return {*m_transform, m_it + diff}; } Iterator operator-(difference_type diff) { return {*m_transform, m_it - diff}; } friend bool operator==(const Iterator& lhs, const Iterator& rhs) { return lhs.m_it == rhs.m_it; } friend bool operator!=(const Iterator& lhs, const Iterator& rhs) { return not (lhs == rhs); } friend difference_type operator-(const Iterator& lhs, const Iterator& rhs) { return lhs.m_it - rhs.m_it; } RangeIt base() const { return m_it; } private: RangeIt m_it; Transform* m_transform; }; Iterator begin() const { return {m_transform, std::begin(m_range)}; } Iterator end() const { return {m_transform, std::end(m_range)}; } Range m_range; mutable Transform m_transform; }; template inline auto transform(Transform t) { return make_view_factory([t = std::move(t)](auto&& range) { using Range = decltype(range); return TransformView, Transform>{std::forward(range), std::move(t)}; }); } template struct is_pointer_like : std::false_type {}; template struct is_pointer_like())>, std::decay_t>>> : std::true_type {}; template inline auto transform(M T::*member) { return transform([member](auto&& arg) -> decltype(auto) { using Arg = decltype(arg); using Member = decltype(member); auto get_object = [&] () mutable -> decltype(auto) { if constexpr (is_pointer_like::value) return *std::forward(arg); else return std::forward(arg); }; if constexpr (std::is_member_function_pointer_v) return (get_object().*member)(); else return get_object().*member; }); } template, typename ValueTypeParam = void> struct SplitView { using RangeIt = IteratorOf; using ValueType = std::conditional_t::value, std::pair, IteratorOf>, ValueTypeParam>; struct Iterator : std::iterator { Iterator(RangeIt pos, const RangeIt& end, Element separator, Element escaper) : done{pos == end}, pos{pos}, sep{pos}, end(end), separator{std::move(separator)}, escaper{std::move(escaper)} { bool escaped = false; while (sep != end and (escaped or *sep != separator)) { escaped = escape and not escaped and *sep == escaper; ++sep; } } Iterator& operator++() { advance(); return *this; } Iterator operator++(int) { auto copy = *this; advance(); return copy; } bool operator==(const Iterator& other) const { return pos == other.pos and done == other.done; } bool operator!=(const Iterator& other) const { return pos != other.pos or done != other.done; } ValueType operator*() { return {pos, (not include_separator or sep == end) ? sep : sep + 1}; } private: void advance() { if (sep == end) { pos = end; done = true; return; } pos = sep+1; if (include_separator and pos == end) { done = true; return; } bool escaped = escape and *sep == escaper; for (sep = pos; sep != end; ++sep) { if (not escaped and *sep == separator) break; escaped = escape and not escaped and *sep == escaper; } } bool done; RangeIt pos; RangeIt sep; RangeIt end; Element separator; Element escaper; }; Iterator begin() const { return {std::begin(m_range), std::end(m_range), m_separator, m_escaper}; } Iterator end() const { return {std::end(m_range), std::end(m_range), m_separator, m_escaper}; } Range m_range; Element m_separator; Element m_escaper; }; template auto split(Element separator) { return make_view_factory([s = std::move(separator)](auto&& range) { using Range = decltype(range); return SplitView, false, false, Element, ValueType>{std::forward(range), std::move(s), {}}; }); } template auto split_after(Element separator) { return make_view_factory([s = std::move(separator)](auto&& range) { using Range = decltype(range); return SplitView, false, true, Element, ValueType>{std::forward(range), std::move(s), {}}; }); } template auto split(Element separator, Element escaper) { return make_view_factory([s = std::move(separator), e = std::move(escaper)](auto&& range) { using Range = decltype(range); return SplitView, true, false, Element, ValueType>{std::forward(range), std::move(s), std::move(e)}; }); } template struct ConcatView { using RangeIt1 = decltype(std::declval().begin()); using RangeIt2 = decltype(std::declval().begin()); using ValueType = typename std::common_type_t::value_type, typename std::iterator_traits::value_type>; struct Iterator : std::iterator { static_assert(std::is_convertible::value_type, ValueType>::value, ""); static_assert(std::is_convertible::value_type, ValueType>::value, ""); Iterator(RangeIt1 it1, RangeIt1 end1, RangeIt2 it2) : m_it1(std::move(it1)), m_end1(std::move(end1)), m_it2(std::move(it2)) {} decltype(auto) operator*() { return is2() ? *m_it2 : *m_it1; } Iterator& operator++() { if (is2()) ++m_it2; else ++m_it1; return *this; } Iterator operator++(int) { auto copy = *this; ++*this; return copy; } friend bool operator==(const Iterator& lhs, const Iterator& rhs) { return lhs.m_it1 == rhs.m_it1 and lhs.m_end1 == rhs.m_end1 and lhs.m_it2 == rhs.m_it2; } friend bool operator!=(const Iterator& lhs, const Iterator& rhs) { return not (lhs == rhs); } private: bool is2() const { return m_it1 == m_end1; } RangeIt1 m_it1; RangeIt1 m_end1; RangeIt2 m_it2; }; ConcatView(Range1& range1, Range2& range2) : m_range1(range1), m_range2(range2) {} Iterator begin() const { return {m_range1.begin(), m_range1.end(), m_range2.begin()}; } Iterator end() const { return {m_range1.end(), m_range1.end(), m_range2.end()}; } private: Range1 m_range1; Range2 m_range2; }; template ConcatView, decay_range> concatenated(Range1&& range1, Range2&& range2) { return {range1, range2}; } template auto find(Range&& range, const T& value) { using std::begin; using std::end; return std::find(begin(range), end(range), value); } template auto find_if(Range&& range, T op) { using std::begin; using std::end; return std::find_if(begin(range), end(range), op); } template bool contains(Range&& range, const T& value) { using std::end; return find(range, value) != end(range); } template bool all_of(Range&& range, T op) { using std::begin; using std::end; return std::all_of(begin(range), end(range), op); } template bool any_of(Range&& range, T op) { using std::begin; using std::end; return std::any_of(begin(range), end(range), op); } template void unordered_erase(Range&& vec, U&& value) { auto it = find(vec, std::forward(value)); if (it != vec.end()) { using std::swap; swap(vec.back(), *it); vec.pop_back(); } } template Init accumulate(Range&& c, Init&& init, BinOp&& op) { using std::begin; using std::end; return std::accumulate(begin(c), end(c), init, op); } template void for_n_best(Range&& c, size_t count, Compare&& compare, Func&& func) { using std::begin; using std::end; auto b = begin(c), e = end(c); std::make_heap(b, e, compare); while (count > 0 and b != e) { if (func(*b)) --count; std::pop_heap(b, e--, compare); } } template auto gather() { return make_view_factory([](auto&& range) { using std::begin; using std::end; return Container(begin(range), end(range)); }); } template