[
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2018 Andrey Orst\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# Project status\n\nBecause I have stopped using Kakoune, this project will not receive active maintenance. The issues section has been closed, as I do not plan to address any issues myself. However, I welcome pull requests from anyone who encounters problems with this plugin and knows how to resolve them.\n\n# plug.kak\n[![GitHub issues][1]][2] ![license][3]\n\n![plug.kak][4]\n\n**plug.kak** is a plugin manager for Kakoune, which was inspired by [vim-plug][5] and [use-package][6].\nIt can install and update plugins, run post-update actions, and help to encapsulate the configuration within itself.\n\n\n## Installation\n\n**plug.kak** can be installed anywhere in your system, but to update itself, it is required to install **plug.kak** in the plugin installation directory.\nBy default, **plug.kak** installs plugins to the `%val{config}/plugins`, which is usually at `$HOME/.config/kak/plugins`:\n\n``` sh\nmkdir -p $HOME/.config/kak/plugins\ngit clone https://github.com/andreyorst/plug.kak.git $HOME/.config/kak/plugins/plug.kak\n```\n\nNow, when **plug.kak** is installed, we need to tell Kakoune about it.\nAdd this to the `kakrc` file:\n\n``` kak\nsource \"%val{config}/plugins/plug.kak/rc/plug.kak\"\nplug \"andreyorst/plug.kak\" noload\n```\n\nAlternatively, this process can be automated by adding the following snippet to the `kakrc`:\n\n``` sh\nevaluate-commands %sh{\n    plugins=\"$kak_config/plugins\"\n    mkdir -p \"$plugins\"\n    [ ! -e \"$plugins/plug.kak\" ] && \\\n        git clone -q https://github.com/andreyorst/plug.kak.git \"$plugins/plug.kak\"\n    printf \"%s\\n\" \"source '$plugins/plug.kak/rc/plug.kak'\"\n}\nplug \"andreyorst/plug.kak\" noload\n```\n\nThis will create all needed directories on Kakoune launch, and download **plug.kak** if it is not installed already.\n\n**Note**: `plug \"andreyorst/plug.kak\" noload` is needed to register **plug.kak** as a manually loaded plugin, so `plug-clean` will not delete **plug.kak**.\n\n\n## Usage\n\nAll plugins are installed and loaded with the `plug` command.\nThis command accepts one or more arguments, which are keywords and attributes, that change how **plug.kak** behaves.\n\nThe first strict rule of the `plug` command is that the first argument is always the plugin name formatted as in GitHub URL: `\"author/repository\"`.\n\n``` kak\nplug \"author/repository\"\n```\n\nBy default **plug.kak** will look for the plugin at GitHub.com and download it.\nWhen the plugin is hosted on a different service, a URL can be used as the first argument.\nSo, in most cases, it is enough to add this to the `kakrc` to use a plugin:\n\n```kak\nplug \"delapouite/kakoune-text-objects\"\n```\n\nOr with URL:\n\n```kak\nplug \"https://gitlab.com/Screwtapello/kakoune-inc-dec\"\n```\n\nAfter adding this, `kakrc` needs to be re-sourced to let **plug.kak** know that the configuration was changed.\nAlternatively, Kakoune can be restarted.\nAfter that, newly added plugins can be installed with the `plug-install` command.\nMore information about other commands available in the [Commands](#Commands) section.\n\n\n### Keywords and attributes\n\nThe `plug` command accepts optional attributes that change how **plug.kak** works, or add additional steps for `plug` to perform.\n\nThese keywords are supported:\n\n- [branch, tag, commit](#branch-tag-or-commit)\n- [load-path](#loading-plugin-from-a-different-path)\n- [noload](#skipping-loading-of-a-plugin)\n- [do](#automatically-do-certain-tasks-on-install-or-update)\n- [theme](#installing-color-schemes)\n- [config](#handling-user-configurations)\n- [defer](#deferring-plugin-configuration)\n- [demand](#demanding-plugin-module-configuration)\n- [ensure](#ensuring-that-plugins-are-installed)\n\n\n#### Branch, Tag, or Commit\n\n`plug` can checkout a plugin to the desired branch, commit, or tag before loading it.\nIt can be done by adding the following keywords with parameters: `branch \"branch_name\"`, `tag \"tag_name\"` or `commit \"commit_hash\"`.\n\n\n#### Loading plugin from a different path\n\nPlugins can be loaded from an arbitrary path by specifying the `load-path` keyword and providing the path as an argument:\n\n``` kak\nplug \"plugin_name\" load-path \"~/Development/plugin_dir\"\n```\n\nHowever, all `plug` related commands, like `plug-update` or `plug-clean`, will not work for plugins that aren't installed to `plug_install_dir`.\n\n\n#### Skipping loading of a plugin\n\nIf a plugin needs to be loaded manually, the `noload` keyword can be used.\nThis can also be used to avoid loading the plugin a second time, like in the example with **plug.kak** from the [installation](#installation) section:\n\n```kak\nsource \"%val{config}/plugins/plug.kak/rc/plug.kak\"\nplug \"andreyorst/plug.kak\" noload\n```\n\nNote that plugins with the `noload` keyword are still configured and managed.\nSee [handling-user-configuration](#handling-user-configurations) for more details.\n\n\n#### Automatically do certain tasks on install or update\n\nWhen the plugin requires some additional steps to perform after installation or update, the `do` keyword can be used.\nThis keyword expects the body, which will be executed in the shell. \nThus, it can only contain shell commands, not Kakoune commands.\n\n```kak\nplug \"ul/kak-lsp\" do %{\n    cargo build --release --locked\n    cargo install --force --path .\n}\n```\n\nIn the example above **plug.kak** will run these `cargo` commands after `kak-lsp` was installed or updated.\n\n**Note** that even though this is technically a shell expansion, the `%sh{}` expansion can't be used with `do`, as it will be evaluated immediately each time `kakrc` is loaded.\nUse `%{}` instead.\n\n\n#### Installing color schemes\n\nTo register the plugin as a color scheme, use `theme` keyword.\nSuch plugins will be copied to the `%val{config}/colors` directory.\n\n```kak\nplug \"andreyorst/base16-gruvbox.kak\" theme config %{\n    colorscheme base16-gruvbox-dark-soft\n}\n```\n\n\n#### Ensuring that plugins are installed\n\n`plug` command can be explicitly told to install the plugin automatically with the `ensure` keyword.\nThe `plug_always_ensure` option can be set to `true` to perform this for each and every plugin specified in the `kakrc`.\n\nNote that `ensure` plugins are installed (if missing) in a background job; they are then only loaded when the install finishes.\nThus, subsequent `kakrc` commands should not depend on functionality provided by such plugins.\nOnly use `ensure` with non-essential plugins, which are not required for `kakrc` to complete loading.\n\n\n#### Handling user configurations\n\nThe configuration of the plugin is performed only when the plugin is installed.\nThere's a second strict rule of `plug` command: every parameter that doesn't have a keyword before it, is treated as plugin configuration.\nFor example:\n\n```kak\nplug \"andreyorst/fzf.kak\" config %{\n    map -docstring 'fzf mode' global normal '<c-p>' ': fzf-mode<ret>'\n}\n```\n\nHere, `plug` will map <kbd>Ctrl</kbd>+<kbd>p</kbd> key only if the plugin is installed.\nEverything within the `config %{}` block is an ordinary kakscript.\n\nThe `config` keyword is optional, and can be skipped.\nMultiple `config` blocks are also supported.\n\n\n#### Commenting out `plug` options\n\nIt may be tricky to \"toggle\" `plug` options, for debugging or testing purposes, because it is impossible to continue a command past a `#...` comment (also, `config` blocks usually span multiple lines).\nTo solve this, `plug` supports a `comment` keyword that ignores its next argument.\nFor example, to toggle a `load-path` option, wrap it in `comment %{}`; then remove the \"wrapper\" to turn it back on (without having to re-type the full path):\n```kak\nplug \"andreyorst/fzf.kak\" comment %{load-path /usr/local/src/fzf} config %{\n    # ...\n}\n```\n\n\n### Deferring plugin configuration\n\nWith the introduction of the module system, some configurations have to be preformed after loading the module.\nThe `defer` keyword is a shorthand to register a `ModuleLoaded` hook for given `module`.\nYou need to **`require` the module explicitly** elsewhere.\n\nBelow is the configuration of [fzf.kak](https://github.com/andreyorst/fzf.kak) plugin, which provides the `fzf` module:\n\n```kak\nplug \"andreyorst/fzf.kak\" config %{\n    map -docstring 'fzf mode' global normal '<c-p>' ': fzf-mode<ret>'\n} defer fzf %{\n    set-option global fzf_preview_width '65%'\n    set-option global fzf_project_use_tilda true\n}\n```\n\n**Note**: the `ModuleLoaded` hook is defined as early as possible - before sourcing any of plugin files.\n\n### Demanding plugin module configuration\n\nWorks the same as `defer` except requires the module immediately:\n\n```kak\nplug \"andreyorst/fzf.kak\" config %{\n    # config1 (evaluated before demanding the module)\n} demand fzf %{\n    # demand block (will generate `require-modlue fzf` call, and a respective hook)\n    set-option global fzf_project_use_tilda true\n} config %{\n    # config2 (evaluated after demanding the module)\n}\n```\n\nThe above snippet is a shorthand for this code:\n\n``` kak\nplug \"andreyorst/fzf.kak\" defer fzf %{\n    # the body of demand block\n    set-option global fzf_project_use_tilda true # demand block\n} config %{\n    # config1 (evaluated before demanding the module)\n    require-module fzf # the demand hook\n    # config2 (evaluated after demanding the module)\n}\n```\n\n**Note**: the `ModuleLoaded` hook is defined as early as possible - before sourcing any of plugin files.\nThe place where `require-module` call will be placed depends on the order of config blocks in the `plug` command.\nAs soon as the module is required, the `ModuleLoaded` hook will execute.\n\n\n## **plug.kak** Configuration\n\nSeveral configuration options are available:\n\n- Changing the [plugin installation directory](#plugin-installation-directory),\n- Limiting the [maximum amount of active downloads](#maximum-downloads),\n- Specifying the [default git domain](#default-git-domain),\n- And [ensuring that plugins are installed](#ensuring-that-plugins-are-installed).\n\nProper way to configure **plug.kak** is to load it with the `plug` command, and providing both `noload` and `config` blocks:\nThis should be done before loading other plugins.\n\n```kak\nplug \"andreyorst/plug.kak\" noload config %{\n    # configure plug.kak here\n}\n```\n\n\n### Plugin installation directory\n\nBy default **plug.kak** automatically detects its installation path and installs plugins to the same directory.\nTo change this, use the `plug_install_dir` option:\n\n```kak\nplug \"andreyorst/plug.kak\" noload config %{\n    set-option global plug_install_dir %sh{ echo $HOME/.cache/kakoune_plugins }\n}\n```\n\n\n### Maximum downloads\n\n**plug.kak** downloads plugins from github.com asynchronously via `git`.\nBy default it allows only `10` simultaneously active `git` processes.\nTo change this, use the `plug_max_simultaneous_downloads` option.\n\n\n### Default git domain\n\nIf majority of plugins is installed from the service other than GitHub, default git domain can be changed to avoid specifying the `domain` keyword for each plugin, or using URLs.\n\n\n### Notify on configuration error\n\nBy default, **plug.kak** will display an `info` box when any plugin's `config` block has errors while being evaluated.\nTo change this, use the `plug_report_conf_errors` option:\n\n```kak\nset-option global plug_report_conf_errors false\n```\n\n\n## Commands\n\n**plug.kak** adds five new commands to Kakoune.\n\n\n### `plug-install`\n\nThis command installs all plugins that were specified in any of the configuration files sourced after Kakoune launch.\nIt accepts optional argument, which can be the plugin name or the URL, so it could be used to install a plugin from command prompt without restarting Kakoune.\nThis plugin will be enabled automatically, but you still need to add `plug` command to your configuration files in order to use that plugin after the restart.\n\n\n### `plug-list`\n\nDisplay the buffer with all installed plugins, and check for updates.\nThe <kbd>Enter</kbd> key is remapped to execute `plug-update` or `plug-install` command for selected plugin, depending on its state.\nThis command accepts an optional argument `noupdate`, and if it is specified, check for updates will not be performed.\n\n\n### `plug-update`\n\nThis command updates all installed plugins.\nIt accepts one optional argument, which is a plugin name, so it could be used to update single plugin.\nWhen called from prompt, it shows all installed plugins in the completion menu.\n\n\n### `plug-clean`\n\nRemove plugins, that are installed, but disabled or missing in configuration files.\nThis command also accepts optional argument, which is a plugin name, and can be used to remove any installed plugin.\n\n\n### `plug`\n\nLoad plugin from plugin installation directory by its name.\n\n\n### `plug-chain`\n\nThis command can collapse separate `plug` invocations and thus saves startup time by reducing multiple shell calls; it may come in handy if you're invoking `kak` frequently (e.g. as the `$EDITOR`). Replace the first `plug` command in your `kakrc` with `plug-chain`, then append subsequent `plug` calls and their parameters, as in the following:\n```\nplug-chain https://github.com/Delapouite/kakoune-select-view config %{\n  map global view s '<esc>: select-view<ret>' -docstring 'select view'\n} plug https://github.com/occivink/kakoune-vertical-selection %{\n} plug https://github.com/jbomanson/search-doc.kak demand search-doc %{\n  alias global doc-search search-doc\n}\n```\n\nBackslashes can also be used to separate individual `plug` \"clauses\" (which avoids the \"visual hack\" of empty config blocks, as above, serving as newlines).\nAn initial `plug` redundant argument is also supported for symmetry.\nEither way, `plug-chain` simply figures out the parameters intended for each individual `plug` clause (using \"`plug`\" as a delimiter), and executes all implied `plug`s in a single shell call.\nAll regular `plug` features are supported.\nMix and match `plug` / `plug-chain` invocations in any order, any number of times.\n\nNote, that if plug.kak own variables are altered in the `plug-chain` body, the chained `plug` commands won't get updated values.\nThis happens because Kakoune reads its variables only once per shell invocation, and calling `set-option` won't update the value of a variable for current shell.\n\n\n### Alternative plugin managers\n\nHere are some other plugin managers to consider as alternatives to plug.kak:\n\n- [kak-bundle][7]\n- [cork.kak][8]\n\n[1]: https://img.shields.io/github/issues/andreyorst/plug.kak.svg\n[2]: https://github.com/andreyorst/plug.kak/issues\n[3]: https://img.shields.io/github/license/andreyorst/plug.kak.svg\n[4]: https://user-images.githubusercontent.com/19470159/51197223-f2c26a80-1901-11e9-9494-b79ce823a364.png\n[5]: https://github.com/junegunn/vim-plug\n[6]: https://github.com/jwiegley/use-package\n[7]: https://github.com/jdugan6240/kak-bundle\n[8]: https://github.com/topisani/cork.kak\n\n<!--  LocalWords:  kak Kakoune Kakoune's GitLab Gitea noload config\n      LocalWords:  kakscript kbd Ctrl github fzf\n -->\n"
  },
  {
    "path": "rc/plug.kak",
    "content": "# Author: Andrey Listopadov\n# plug.kak is a plugin manager for Kakoune. It can install plugins, keep them updated, configure and build dependencies\n# https://github.com/andreyorst/plug.kak\n\n# Public options\ndeclare-option -docstring \\\n\"Path where plugins should be installed.\n\n    Defaults to the plug.kak installation directory\" \\\nstr plug_install_dir %sh{ echo \"${kak_source%%/rc*}/../\" }\n\ndeclare-option -docstring \\\n\"Default domain to access git repositories. Can be changed to any preferred domain, like gitlab, bitbucket, gitea, etc.\n\n    Default value: 'https://github.com'\" \\\nstr plug_git_domain 'https://github.com'\n\ndeclare-option -docstring \\\n\"Profile plugin loading.\" \\\nbool plug_profile false\n\ndeclare-option -docstring \\\n\"Maximum amount of simultaneously active downloads when installing or updating all plugins\n    Default value: 10\n\" \\\nint plug_max_active_downloads 10\n\ndeclare-option -docstring \\\n\"Always ensure that all plugins are installed. If this option specified, all uninstalled plugins are being installed when Kakoune starts.\" \\\nbool plug_always_ensure false\n\ndeclare-option -docstring \"name of the client in which utilities display information\" \\\nstr toolsclient\n\ndeclare-option -docstring \\\n\"Block UI until operation completes.\" \\\nbool plug_block_ui false\n\n# Private options\ndeclare-option -hidden -docstring \\\n\"Path to plug.sh script.\" \\\nstr plug_sh_source %sh{ echo \"${kak_source%%.kak}.sh\" }\n\ndeclare-option -hidden -docstring \\\n\"Array of all plugins, mentioned in any configuration file.\nEmpty by default, and erased on reload of main Kakoune configuration, to track if some plugins were disabled\nShould not be modified by user.\" \\\nstr plug_plugins \"\"\n\ndeclare-option -hidden -docstring \\\n\"List of loaded plugins. Has no default value.\nShould not be cleared during update of configuration files. Should not be modified by user.\" \\\nstr plug_loaded_plugins \"\"\n\ndeclare-option -docstring \\\n\"Whether or not to report errors in config blocks. Defaults to true.\" \\\nbool plug_report_conf_errors true\n\ndeclare-option -hidden -docstring \\\n\"This will be set if there are any errors with a plugin's config block. Has no default value.\nShould not be cleared during update of configuration files. Should not be modified by user.\" \\\nstr plug_conf_errors \"\"\n\n# since we want to add highlighters to kak filetype we need to require kak module\n# using `try' here since kakrc module may not be available in rare cases\ntry %@\n    require-module kak\n\n    try %$\n        add-highlighter shared/kakrc/code/plug_keywords   regex '\\b(plug|plug-chain|do|config|domain|defer|demand|load-path|branch|tag|commit|comment)(?=[ \\t])' 0:keyword\n        add-highlighter shared/kakrc/code/plug_attributes regex '(?<=[ \\t])(noload|ensure|theme)\\b' 0:attribute\n        add-highlighter shared/kakrc/plug_post_hooks1     region -recurse '\\{' '\\bdo\\K\\h+%\\{' '\\}' ref sh\n        add-highlighter shared/kakrc/plug_post_hooks2     region -recurse '\\[' '\\bdo\\K\\h+%\\[' '\\]' ref sh\n        add-highlighter shared/kakrc/plug_post_hooks3     region -recurse '\\(' '\\bdo\\K\\h+%\\(' '\\)' ref sh\n        add-highlighter shared/kakrc/plug_post_hooks4     region -recurse '<'  '\\bdo\\K\\h+%<'  '>'  ref sh\n    $ catch %$\n        echo -debug \"Error: plug.kak: can't declare highlighters for 'kak' filetype: %val{error}\"\n    $\n@ catch %{\n    echo -debug \"Error: plug.kak: can't require 'kak' module to declare highlighters for plug.kak. Check if kakrc.kak is available in your autoload.\"\n}\n\n# *plug* highlighters\ntry %{\n    add-highlighter shared/plug_buffer group\n    add-highlighter shared/plug_buffer/done          regex [^:]+:\\h+(Up\\h+to\\h+date|Done|Installed)$                    1:string\n    add-highlighter shared/plug_buffer/update        regex [^:]+:\\h+(Update\\h+available|Deleted)$                       1:keyword\n    add-highlighter shared/plug_buffer/not_installed regex [^:]+:\\h+(Not\\h+(installed|loaded)|(\\w+\\h+)?Error([^\\n]+)?)$ 1:red+b\n    add-highlighter shared/plug_buffer/updating      regex [^:]+:\\h+(Installing|Updating|Local\\h+changes)$              1:type\n    add-highlighter shared/plug_buffer/working       regex [^:]+:\\h+(Running\\h+post-update\\h+hooks|Waiting[^\\n]+)$      1:attribute\n} catch %{\n    echo -debug \"Error: plug.kak: Can't declare highlighters for *plug* buffer: %val{error}\"\n}\n\nhook -group plug-syntax global WinSetOption filetype=plug %{\n    add-highlighter buffer/plug_buffer ref plug_buffer\n    hook -always -once window WinSetOption filetype=.* %{\n        remove-highlighter buffer/plug_buffer\n    }\n}\n\ndefine-command -override -docstring \\\n\"plug <plugin> [<switches>]: manage <plugin> from \"\"%opt{plug_install_dir}\"\"\nSwitches:\n    branch (tag, commit) <str>      checkout to <str> before loading plugin\n    noload                          do not source plugin files\n    subset <subset>                 source only <subset> of plugin files\n    load-path <path>                path for loading plugin from foreign location\n    defer <module> <configurations> load plugin <configurations> only when <module> is loaded\n    config <configurations>         plugin <configurations>\" \\\nplug -params 1.. -shell-script-candidates %{ ls -1 ${kak_opt_plug_install_dir} } %{ try %{\n    evaluate-commands %sh{\n        # $kak_client\n        # $kak_config\n        # $kak_opt_plug_always_ensure\n        # $kak_opt_plug_git_domain\n        # $kak_opt_plug_install_dir\n        # $kak_opt_plug_loaded_plugins\n        # $kak_opt_plug_max_active_downloads\n        # $kak_opt_plug_plugin\n        # $kak_opt_plug_plugins\n        # $kak_opt_plug_profile\n        # $kak_opt_plug_block_ui\n        # $kak_opt_plug_report_conf_errors\n        # $kak_opt_plug_conf_errors\n        # $kak_session\n\n        . \"${kak_opt_plug_sh_source}\"\n        plug \"$@\"\n    }\n}}\n\ndefine-command -override plug-chain -params 0.. -docstring %{\n  Chain plug commands (see docs, saves startup time by reducing sh calls)\n} %{ try %{\n    evaluate-commands %sh{\n        # $kak_client\n        # $kak_config\n        # $kak_opt_plug_always_ensure\n        # $kak_opt_plug_git_domain\n        # $kak_opt_plug_install_dir\n        # $kak_opt_plug_loaded_plugins\n        # $kak_opt_plug_max_active_downloads\n        # $kak_opt_plug_plugin\n        # $kak_opt_plug_plugins\n        # $kak_opt_plug_profile\n        # $kak_opt_plug_block_ui\n        # $kak_opt_plug_report_conf_errors\n        # $kak_opt_plug_conf_errors\n        # $kak_session\n\n        set -u\n        . \"${kak_opt_plug_sh_source}\"\n        plug1() {\n          for _plug_param; do\n            # reset \"$@\" on 1st iteration; args still in 'for'\n            [ \"$_plug_processed_args\" != 0 ] || set --\n            _plug_processed_args=$((_plug_processed_args + 1))\n            [ plug != \"$_plug_param\" ] || break\n            set -- \"$@\" \"$_plug_param\"\n          done\n          [ $# = 0 ] || plug \"$@\"  # subshell would be safer, but slower\n        }\n        while [ \"$#\" != 0 ]; do\n          _plug_processed_args=0\n          plug1 \"$@\"\n          shift \"$_plug_processed_args\"\n        done\n    }\n}}\n\ndefine-command -override -docstring \\\n\"plug-install [<plugin>] [<noload>]: install <plugin>.\nIf <plugin> omitted installs all plugins mentioned in configuration\nfiles.  If <noload> is supplied skip loading the plugin.\" \\\nplug-install -params ..2 %{ nop %sh{\n    # $kak_client\n    # $kak_config\n    # $kak_opt_plug_always_ensure\n    # $kak_opt_plug_git_domain\n    # $kak_opt_plug_install_dir\n    # $kak_opt_plug_loaded_plugins\n    # $kak_opt_plug_max_active_downloads\n    # $kak_opt_plug_plugin\n    # $kak_opt_plug_plugins\n    # $kak_opt_plug_profile\n    # $kak_opt_plug_block_ui\n    # $kak_opt_plug_report_conf_errors\n    # $kak_opt_plug_conf_errors\n    # $kak_session\n\n    . \"${kak_opt_plug_sh_source}\"\n    plug_install \"$@\"\n}}\n\ndefine-command -override -docstring \\\n\"plug-update [<plugin>]: Update plugin.\nIf <plugin> omitted all installed plugins are updated\" \\\nplug-update -params ..1 -shell-script-candidates %{ printf \"%s\\n\" ${kak_opt_plug_plugins} | tr ' ' '\\n' } %{\n    evaluate-commands %sh{\n        # $kak_client\n        # $kak_config\n        # $kak_opt_plug_always_ensure\n        # $kak_opt_plug_git_domain\n        # $kak_opt_plug_install_dir\n        # $kak_opt_plug_loaded_plugins\n        # $kak_opt_plug_max_active_downloads\n        # $kak_opt_plug_plugin\n        # $kak_opt_plug_plugins\n        # $kak_opt_plug_profile\n        # $kak_opt_plug_block_ui\n        # $kak_opt_plug_report_conf_errors\n        # $kak_opt_plug_conf_errors\n        # $kak_session\n\n        . \"${kak_opt_plug_sh_source}\"\n        plug_update \"$@\"\n}}\n\ndefine-command -override -docstring \\\n\"plug-clean [<plugin>]: delete <plugin>.\nIf <plugin> omitted deletes all plugins that are installed but not presented in configuration files\" \\\nplug-clean -params ..1 -shell-script-candidates %{ ls -1 ${kak_opt_plug_install_dir} } %{ nop %sh{\n    # $kak_client\n    # $kak_config\n    # $kak_opt_plug_always_ensure\n    # $kak_opt_plug_git_domain\n    # $kak_opt_plug_install_dir\n    # $kak_opt_plug_loaded_plugins\n    # $kak_opt_plug_max_active_downloads\n    # $kak_opt_plug_plugin\n    # $kak_opt_plug_plugins\n    # $kak_opt_plug_profile\n    # $kak_opt_plug_block_ui\n    # $kak_opt_plug_report_conf_errors\n    # $kak_opt_plug_conf_errors\n    # $kak_session\n\n    . \"${kak_opt_plug_sh_source}\"\n    plug_clean \"$@\"\n}}\n\ndefine-command -override -hidden \\\n-docstring \"plug-eval-hooks: wrapper for post update/install hooks\" \\\nplug-eval-hooks -params 1 %{ nop %sh{\n    # $kak_client\n    # $kak_config\n    # $kak_opt_plug_always_ensure\n    # $kak_opt_plug_git_domain\n    # $kak_opt_plug_install_dir\n    # $kak_opt_plug_loaded_plugins\n    # $kak_opt_plug_max_active_downloads\n    # $kak_opt_plug_plugin\n    # $kak_opt_plug_plugins\n    # $kak_opt_plug_profile\n    # $kak_opt_plug_block_ui\n    # $kak_opt_plug_report_conf_errors\n    # $kak_opt_plug_conf_errors\n    # $kak_session\n\n    . \"${kak_opt_plug_sh_source}\"\n    plug_eval_hooks \"$@\"\n}}\n\ndefine-command -override \\\n-docstring \"plug-list [<noupdate>]: list all installed plugins in *plug* buffer. Checks updates by default unless <noupdate> is specified.\" \\\nplug-list -params ..1 %{ evaluate-commands -try-client %opt{toolsclient} %sh{\n    # $kak_client\n    # $kak_config\n    # $kak_opt_plug_always_ensure\n    # $kak_opt_plug_git_domain\n    # $kak_opt_plug_install_dir\n    # $kak_opt_plug_loaded_plugins\n    # $kak_opt_plug_max_active_downloads\n    # $kak_opt_plug_plugin\n    # $kak_opt_plug_plugins\n    # $kak_opt_plug_profile\n    # $kak_opt_plug_block_ui\n    # $kak_opt_plug_report_conf_errors\n    # $kak_opt_plug_conf_errors\n    # $kak_session\n\n    . \"${kak_opt_plug_sh_source}\"\n    plug_list \"$@\"\n}}\n\ndefine-command -hidden -override \\\n-docstring \"operate on *plug* buffer contents based on current cursor position\" \\\nplug-fifo-operate -params 1 %{ evaluate-commands -save-regs t %{\n    execute-keys -save-regs '' \"<a-h><a-l>\"\n    set-register t %val{selection}\n    evaluate-commands %sh{\n    # $kak_reg_t\n    # $kak_client\n    # $kak_config\n    # $kak_opt_plug_always_ensure\n    # $kak_opt_plug_git_domain\n    # $kak_opt_plug_install_dir\n    # $kak_opt_plug_loaded_plugins\n    # $kak_opt_plug_max_active_downloads\n    # $kak_opt_plug_plugin\n    # $kak_opt_plug_plugins\n    # $kak_opt_plug_profile\n    # $kak_opt_plug_block_ui\n    # $kak_opt_plug_report_conf_errors\n    # $kak_opt_plug_conf_errors\n    # $kak_session\n\n    . \"${kak_opt_plug_sh_source}\"\n    plug_fifo_operate \"$@\"\n}}}\n\ndefine-command -hidden -override \\\nplug-display-log -params 1 %{ evaluate-commands %sh{\n    plugin_log=\"${TMPDIR:-/tmp}/${1##*/}-log\"\n    [ -s \"${plugin_log}\" ] && printf \"%s\\n\" \"edit! -existing -debug -readonly -scroll %{${plugin_log}}\"\n}}\n\ndefine-command -override \\\n-docstring \"displays help message\" \\\nplug-show-help %{\n    info -title \"plug.kak Help\" \"h,j,k,l: Move\n<ret>:   Update or Install plugin\nI:       Install plugin\nU:       Update plugin\nD:       clean (Delete) plugin\nL:       show Log, if any\nR:       Run post-update hooks manually\nH        show Help message\"\n}\n"
  },
  {
    "path": "rc/plug.sh",
    "content": "#!/usr/bin/env sh\n\n# Author: Andrey Listopadov\n# https://github.com/andreyorst/plug.kak\n#\n# plug.kak is a plugin manager for Kakoune. It can install plugins,\n# keep them updated, configure and build dependencies.\n#\n# plug.sh contains a set of functions plug.kak calls via shell\n# expansions.\n\nplug_code_append () {\n    eval \"$1=\\\"\\$$1\n\\$2\\\"\"\n}\n\nplug () {\n    [ \"${kak_opt_plug_profile:-}\" = \"true\" ] && plug_save_timestamp profile_start\n    plugin_arg=$1\n    plugin=\"${1%%.git}\"; plugin=${plugin%%/}\n    shift\n    plugin_name=\"${plugin##*/}\"\n    path_to_plugin=\"${kak_opt_plug_install_dir:?}/$plugin_name\"\n    build_dir=\"${kak_opt_plug_install_dir:?}/.build/$plugin_name\"\n    conf_file=\"$build_dir/config\"\n    hook_file=\"$build_dir/hooks\"\n    domain_file=\"$build_dir/domain\"\n\n    configurations= hooks= domain= checkout= checkout_type= noload= ensure=\n\n    case \"${kak_opt_plug_loaded_plugins:-}\" in\n      (*\"$plugin\"*)\n        printf \"%s\\n\" \"echo -markup %{{Information}$plugin_name already loaded}\"\n        exit\n        ;;\n      (*)\n        printf \"%s\\n\" \"set-option -add global plug_plugins %{$plugin }\"\n        ;;\n    esac\n\n    while [ $# -gt 0 ]; do\n        case $1 in\n            (branch|tag|commit) checkout_type=$1; shift; checkout=${1?} ;;\n            (noload) noload=1 ;;\n            (load-path) shift; eval \"path_to_plugin=${1?}\" ;;\n            (comment) shift ;;\n            (defer|demand)\n                demand=$1\n                shift; module=${1?}\n                if [ $# -ge 2 ]; then\n                    case \"$2\" in\n                        (branch|tag|commit|noload|load-path|ensure|theme|domain|depth-sort|subset|no-depth-sort|config|defer|demand|comment)\n                        ;;\n                        (*)\n                            shift\n                            deferred=$1\n                            case \"$deferred\" in (*[![:space:]]*)\n                                case \"$deferred\" in (*'@'*)\n                                    deferred=$(printf \"%s\\n\" \"$deferred\" | sed \"s/@/@@/g\") ;;\n                                esac\n                                printf \"%s\\n\" \"hook global ModuleLoaded '$module' %@ $deferred @\"\n                            esac\n                            [ \"$demand\" = demand ] && plug_code_append configurations \"require-module $module\" ;;\n                    esac\n                fi\n                ;;\n            ('do') shift; plug_code_append hooks \"set -e\n${1?}\" ;;\n            (ensure) ensure=1 ;;\n            (theme)\n                noload=1\n                plug_code_append hooks \"[ -d \\\"${kak_config:?}/colors\\\" ] || mkdir -p \\\"${kak_config}/colors\\\"; ln -sf \\\"\\$PWD\\\" \\\"$kak_config/colors\\\"\"\n            ;;\n            (domain) shift; domain=${1?} ;;\n            (depth-sort|subset)\n                printf \"%s\\n\" \"echo -debug %{Error: plug.kak: '$plugin_name': keyword '$1' is no longer supported. Use the module system instead}\"\n                exit 1 ;;\n            (no-depth-sort) printf \"%s\\n\" \"echo -debug %{Warning: plug.kak: '$plugin_name': use of deprecated '$1' keyword which has no effect}\" ;;\n            (config) shift; plug_code_append configurations \"${1?}\" ;;\n            (*) plug_code_append configurations \"$1\" ;;\n        esac\n        shift\n    done\n\n    [ -d \"$build_dir\" ] || mkdir -p \"$build_dir\"\n    rm -rf \"$build_dir\"/* \"$build_dir\"/.[!.]* \"$build_dir\"/..?*\n    [ -n \"$hooks\" ] && printf \"%s\" \"$hooks\" > \"$hook_file\"\n    [ -n \"$domain\" ] && printf \"%s\" \"$domain\" > \"$domain_file\"\n\n    if [ -n \"$configurations\" ]; then\n        if [ \"${kak_opt_plug_report_conf_errors:-}\" = \"true\" ]; then\n            cat > \"$conf_file\" <<ERRHANDLE\ntry %{ $configurations } catch %{\n    echo -debug \"Error while evaluating '$plugin_name' configuration: %val{error}\"\n\n    set-option -add current plug_conf_errors \"Error while evaluating '$plugin_name' configuration:\"\n    set-option -add current plug_conf_errors %sh{ printf \"\\n    \" }\n    set-option -add current plug_conf_errors %val{error}\n    set-option -add current plug_conf_errors %sh{ printf \"\\n\\n\" }\n\n    hook -once -group plug-conf-err global WinDisplay .* %{\n        info -style modal -title \"plug.kak error\" \"%opt{plug_conf_errors}\"\n        on-key %{\n            info -style modal\n            execute-keys -with-maps -with-hooks %val{key}\n        }\n    }\n}\nERRHANDLE\n        else\n          printf \"%s\" \"$configurations\" > \"$conf_file\"\n        fi\n    fi\n\n    if [ -d \"$path_to_plugin\" ]; then\n        if [ -n \"$checkout\" ]; then\n            (\n                cd \"$path_to_plugin\" || exit\n                # shellcheck disable=SC2030,SC2031\n                [ -z \"${GIT_TERMINAL_PROMPT:-}\" ] && export GIT_TERMINAL_PROMPT=0\n                if [ \"$checkout_type\" = \"branch\" ]; then\n                    [ \"$(git branch --show-current)\" != \"$checkout\" ] && git fetch >/dev/null 2>&1\n                fi\n                git checkout \"$checkout\" >/dev/null 2>&1\n            )\n        fi\n        plug_load \"$plugin\" \"$path_to_plugin\" \"$noload\"\n        if  [ \"$kak_opt_plug_profile\" = \"true\" ]; then\n            plug_save_timestamp profile_end\n            profile_time=$(echo \"scale=3; x=($profile_end-$profile_start)/1000; if(x<1) print 0; x\" | bc -l)\n            printf \"%s\\n\" \"echo -debug %{'$plugin_name' loaded in $profile_time sec}\"\n        fi\n    else\n        if [ -n \"$ensure\" ] || [ \"${kak_opt_plug_always_ensure:-}\" = \"true\" ]; then\n            (\n                plug_install \"$plugin_arg\" \"$noload\"\n                wait\n                if  [ \"$kak_opt_plug_profile\" = \"true\" ]; then\n                    plug_save_timestamp profile_end\n                    profile_time=$(echo \"scale=3; x=($profile_end-$profile_start)/1000; if(x<1) print 0; x\" | bc -l)\n                    printf \"%s\\n\" \"echo -debug %{'$plugin_name' loaded in $profile_time sec}\" | kak -p \"${kak_session:?}\"\n                fi\n            ) > /dev/null 2>&1 < /dev/null &\n        fi\n    fi\n}\n\nplug_install () {\n    (\n        plugin=\"${1%%.git}\"; plugin=${plugin%%/}\n        noload=$2\n        plugin_name=\"${plugin##*/}\"\n        build_dir=\"${kak_opt_plug_install_dir:?}/.build/$plugin_name\"\n        domain_file=\"$build_dir/domain\"\n\n        # shellcheck disable=SC2030,SC2031\n        [ -z \"${GIT_TERMINAL_PROMPT:-}\" ] && export GIT_TERMINAL_PROMPT=0\n\n        if [ ! -d \"${kak_opt_plug_install_dir}\" ]; then\n            if ! mkdir -p \"${kak_opt_plug_install_dir}\" >/dev/null 2>&1; then\n                printf \"%s\\n\" \"evaluate-commands -client ${kak_client:-client0} echo -debug 'Error: plug.kak: unable to create directory for plugins'\" | kak -p \"${kak_session:?}\"\n                exit\n            fi\n        fi\n\n        printf \"%s\\n\" \"evaluate-commands -client ${kak_client:-client0} %{ try %{ buffer *plug* } catch %{ plug-list noupdate } }\" | kak -p \"${kak_session}\"\n        sleep 0.3\n\n        lockfile=\"${kak_opt_plug_install_dir}/.${plugin_name:-global}.plug.kak.lock\"\n        if [ -d \"${lockfile}\" ]; then\n            plug_fifo_update \"${plugin_name}\" \"Waiting for .plug.kak.lock\"\n        fi\n\n        # this creates the lock file for a plugin, if specified to\n        # prevent several processes of installation of the same\n        # plugin, but will allow install different plugins without\n        # waiting for each other.  Should be fine, since different\n        # plugins doesn't interfere with each other.\n        while ! mkdir \"${lockfile}\" 2>/dev/null; do sleep 1; done\n        # shellcheck disable=SC2064\n        trap \"rmdir '${lockfile}'\" EXIT\n\n        # if plugin specified as an argument add it to the *plug*\n        # buffer, if it isn't there already otherwise update all\n        # plugins\n        if [ -n \"${plugin}\" ]; then\n            plugin_list=${plugin}\n            printf \"%s\\n\" \"\n                evaluate-commands -buffer *plug* %{ try %{\n                    execute-keys /${plugin}<ret>\n                } catch %{\n                    execute-keys gjO${plugin}:<space>Not<space>installed<esc>\n                }}\" | kak -p \"${kak_session}\"\n            sleep 0.2\n        else\n            plugin_list=${kak_opt_plug_plugins}\n        fi\n\n        for plugin in ${plugin_list}; do\n            plugin_name=\"${plugin##*/}\"\n            [ -e \"$domain_file\" ] && git_domain=\"https://$(cat \"$domain_file\")\" || git_domain=${kak_opt_plug_git_domain:?}\n            if [ ! -d \"${kak_opt_plug_install_dir}/${plugin_name}\" ]; then\n                (\n                    plugin_log=\"${TMPDIR:-/tmp}/${plugin_name}-log\"\n                    printf \"%s\\n\" \"hook global -always KakEnd .* %{ nop %sh{rm -rf \\\"$plugin_log\\\"}} \" | kak -p \"${kak_session}\"\n                    plug_fifo_update \"${plugin_name}\" \"Installing\"\n                    cd \"${kak_opt_plug_install_dir}\" || exit\n                    case ${plugin} in\n                        (https://*|http://*|*@*|file://*|ext::*)\n                            git clone --recurse-submodules \"${plugin}\" \"$plugin_name\" >> \"$plugin_log\" 2>&1 ;;\n                        (*)\n                            git clone --recurse-submodules \"$git_domain/$plugin\" \"$plugin_name\" >> \"$plugin_log\" 2>&1 ;;\n                    esac\n                    status=$?\n                    if [ ${status} -ne 0 ]; then\n                        plug_fifo_update \"$plugin_name\" \"Download Error ($status)\"\n                    else\n                        plug_eval_hooks \"$plugin_name\"\n                        wait\n                        plug_load \"$plugin\" \"${kak_opt_plug_install_dir:?}/$plugin_name\" \"$noload\" | kak -p \"${kak_session:?}\"\n                    fi\n                ) > /dev/null 2>&1 < /dev/null &\n            fi\n            # this is a hacky way to measure amount of active\n            # processes. We need this because dash shell has this long\n            # term bug:\n            # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=482999\n            jobs=$(mktemp \"${TMPDIR:-/tmp}\"/plug.kak.jobs.XXXXXX)\n            jobs > \"${jobs}\"; active=$(wc -l < \"${jobs}\")\n            while [ \"${active}\" -ge \"${kak_opt_plug_max_active_downloads:?}\" ]; do\n                sleep 1\n                jobs > \"${jobs}\"; active=$(wc -l < \"${jobs}\")\n            done\n            rm -rf \"${jobs}\"\n        done\n        wait\n    ) > /dev/null 2>&1 < /dev/null &\n}\n\nplug_load() {\n    plugin=\"${1%%.git}\"\n    path_to_plugin=$2\n    noload=$3\n    plugin_name=\"${plugin##*/}\"\n    build_dir=\"${kak_opt_plug_install_dir:?}/.build/$plugin_name\"\n    conf_file=\"$build_dir/config\"\n\n    if [ -z \"${noload}\" ]; then\n        find -L \"${path_to_plugin}\" -path '*/.git' -prune -o -type f -name '*.kak' -exec printf 'source \"%s\"\\n' {} +\n    fi\n    [ -e \"$conf_file\" ] && printf \"%s\\n\" \"source $conf_file\"\n    printf \"%s\\n\" \"set-option -add global plug_loaded_plugins %{${plugin} }\"\n}\n\nplug_update () {\n    (\n        plugin=\"${1%%.git}\"\n        plugin_name=\"${plugin##*/}\"\n\n        # shellcheck disable=SC2030,SC2031\n        [ -z \"${GIT_TERMINAL_PROMPT:-}\" ] && export GIT_TERMINAL_PROMPT=0\n\n        printf \"%s\\n\" \"evaluate-commands -client ${kak_client:-client0} %{ try %{ buffer *plug* } catch %{ plug-list noupdate } }\" | kak -p \"${kak_session}\"\n\n        lockfile=\"${kak_opt_plug_install_dir}/.${plugin_name:-global}.plug.kak.lock\"\n        if [ -d \"${lockfile}\" ]; then\n            plug_fifo_update \"${plugin##*/}\" \"Waiting for .plug.kak.lock\"\n        fi\n\n        while ! mkdir \"${lockfile}\" 2>/dev/null; do sleep 1; done\n        # shellcheck disable=SC2064\n        trap \"rmdir '${lockfile}'\" EXIT\n\n        [ -n \"${plugin}\" ] && plugin_list=${plugin} || plugin_list=${kak_opt_plug_plugins}\n        for plugin in ${plugin_list}; do\n            plugin_name=\"${plugin##*/}\"\n            if [ -d \"${kak_opt_plug_install_dir}/${plugin_name}\" ]; then\n                (\n                    plugin_log=\"${TMPDIR:-/tmp}/${plugin_name}-log\"\n                    printf \"%s\\n\" \"hook global -always KakEnd .* %{ nop %sh{rm -rf ${plugin_log}}} \" | kak -p \"${kak_session}\"\n                    plug_fifo_update \"${plugin_name}\" \"Updating\"\n                    cd \"${kak_opt_plug_install_dir}/${plugin_name}\" && rev=$(git rev-parse HEAD) && git pull --recurse-submodules >> \"${plugin_log}\" 2>&1\n                    status=$?\n                    if [ ${status} -ne 0 ]; then\n                        plug_fifo_update \"${plugin_name}\" \"Update Error (${status})\"\n                    else\n                        if [ \"${rev}\" != \"$(git rev-parse HEAD)\" ]; then\n                            printf \"%s\\n\" \"evaluate-commands -client ${kak_client:-client0} plug-eval-hooks ${plugin_name}\" | kak -p \"${kak_session}\"\n                        else\n                            plug_fifo_update \"${plugin_name}\" \"Done\"\n                        fi\n                    fi\n                ) > /dev/null 2>&1 < /dev/null &\n            fi\n            jobs=$(mktemp \"${TMPDIR:-/tmp}\"/jobs.XXXXXX)\n            jobs > \"${jobs}\"; active=$(wc -l < \"${jobs}\")\n            # TODO: re-check this\n            # For some reason I need to multiply the amount of jobs by five here.\n            while [ \"${active}\" -ge $((kak_opt_plug_max_active_downloads * 5)) ]; do\n                sleep 1\n                jobs > \"${jobs}\"; active=$(wc -l < \"${jobs}\")\n            done\n            rm -rf \"${jobs}\"\n        done\n        wait\n    ) > /dev/null 2>&1 < /dev/null &\n\n    if [ \"${kak_opt_plug_block_ui:-}\" = \"true\" ]; then\n        wait\n    fi\n}\n\n\nplug_clean () {\n    (\n        plugin=\"${1%%.git}\"\n        plugin_name=\"${plugin##*/}\"\n\n        printf \"%s\\n\" \"evaluate-commands -client ${kak_client:-client0} %{ try %{ buffer *plug* } catch %{ plug-list noupdate } }\" | kak -p \"${kak_session}\"\n\n        lockfile=\"${kak_opt_plug_install_dir}/.${plugin_name:-global}.plug.kak.lock\"\n        if [ -d \"${lockfile}\" ]; then\n            plug_fifo_update \"${plugin_name}\" \"Waiting for .plug.kak.lock\"\n        fi\n\n        while ! mkdir \"${lockfile}\" 2>/dev/null; do sleep 1; done\n        # shellcheck disable=SC2064\n        trap \"rmdir '${lockfile}'\" EXIT\n\n        if [ -n \"${plugin}\" ]; then\n            if [ -d \"${kak_opt_plug_install_dir}/${plugin_name}\" ]; then\n                (\n                    cd \"${kak_opt_plug_install_dir}\" && rm -rf \"${plugin_name}\"\n                    plug_fifo_update \"${plugin_name}\" \"Deleted\"\n                )\n            else\n                printf \"%s\\n\" \"evaluate-commands -client ${kak_client:-client0} echo -markup %{{Error}No such plugin '${plugin}'}\" | kak -p \"${kak_session}\"\n                exit\n            fi\n        else\n            for installed_plugin in $(printf \"%s\\n\" \"${kak_opt_plug_install_dir}\"/*); do\n                skip=\n                for enabled_plugin in ${kak_opt_plug_plugins}; do\n                    [ \"${installed_plugin##*/}\" = \"${enabled_plugin##*/}\" ] && { skip=1; break; }\n                done\n                [ \"${skip}\" = \"1\" ] || plugins_to_remove=${plugins_to_remove}\" ${installed_plugin}\"\n            done\n            for plugin in ${plugins_to_remove}; do\n                plug_fifo_update \"${plugin##*/}\" \"Deleted\"\n                rm -rf \"${plugin}\"\n            done\n        fi\n    ) > /dev/null 2>&1 < /dev/null &\n\n    if [ \"$kak_opt_plug_block_ui\" = \"true\" ]; then\n        wait\n    fi\n}\n\nplug_eval_hooks () {\n    (\n        plugin=\"${1%%.git}\"\n        plugin_name=\"${plugin##*/}\"\n        path_to_plugin=\"${kak_opt_plug_install_dir:?}/$plugin_name\"\n        build_dir=\"${kak_opt_plug_install_dir:?}/.build/$plugin_name\"\n        hook_file=\"$build_dir/hooks\"\n\n        plugin_log=\"${TMPDIR:-/tmp}/${plugin_name}-log\"\n        cd \"$path_to_plugin\" || exit\n\n        printf \"%s\\n\" \"hook global -always KakEnd .* %{ nop %sh{rm -rf ${plugin_log}}}\" | kak -p \"${kak_session}\"\n        plug_fifo_update \"${plugin_name}\" \"Running post-update hooks\"\n\n        status=0\n        if [ -e \"$hook_file\" ]; then\n            # shellcheck disable=SC1090\n            (. \"$hook_file\" >> \"$plugin_log\" 2>&1)\n            status=$?\n        fi\n        [ ${status} -ne 0 ] && message=\"Error (${status})\" || message=\"Done\"\n\n        plug_fifo_update \"${plugin_name}\" \"${message}\"\n    ) > /dev/null 2>&1 < /dev/null &\n\n    if [ \"$kak_opt_plug_block_ui\" = \"true\" ]; then\n        wait\n    fi\n}\n\nplug_list () {\n    noupdate=$1\n    tmp=$(mktemp -d \"${TMPDIR:-/tmp}/plug-kak.XXXXXXXX\")\n    fifo=\"${tmp}/fifo\"\n    plug_buffer=\"${tmp}/plug-buffer\"\n    mkfifo \"${fifo}\"\n\n    printf \"%s\\n\" \"edit! -fifo ${fifo} *plug*\n                   set-option buffer filetype plug\n                   plug-show-help\n                   hook -always -once buffer BufCloseFifo .* %{ nop %sh{ rm -rf ${tmp} } }\n                   map buffer normal '<ret>' ':<space>plug-fifo-operate install-update<ret>'\n                   map buffer normal 'H' ':<space>plug-show-help<ret>'\n                   map buffer normal 'U' ':<space>plug-fifo-operate update<ret>'\n                   map buffer normal 'I' ':<space>plug-fifo-operate install<ret>'\n                   map buffer normal 'L' ':<space>plug-fifo-operate log<ret>'\n                   map buffer normal 'D' ':<space>plug-fifo-operate clean<ret>'\n                   map buffer normal 'R' ':<space>plug-fifo-operate hooks<ret>'\"\n\n    # get those plugins which were loaded by plug.kak\n    eval \"set -- ${kak_opt_plug_plugins}\"\n    while [ $# -gt 0 ]; do\n        if [ -d \"${kak_opt_plug_install_dir}/${1##*/}\" ]; then\n            printf \"%s: Installed\\n\" \"$1\" >> \"${plug_buffer}\"\n        else\n            printf \"%s: Not installed\\n\" \"$1\" >> \"${plug_buffer}\"\n        fi\n        shift\n    done\n\n    # get those plugins which have a directory at installation path,\n    # but wasn't mentioned in any config file\n    for existing_plugin in \"${kak_opt_plug_install_dir}\"/*; do\n        case \"${kak_opt_plug_plugins}\" in\n          (*\"${existing_plugin##*/}\"*) ;;\n          (*)\n            printf \"%s: Not loaded\\n\" \"${existing_plugin##*/}\" >> \"${plug_buffer}\"\n            ;;\n        esac\n    done\n\n    ( sort \"${plug_buffer}\" > \"${fifo}\" )  > /dev/null 2>&1 < /dev/null &\n\n    if [ -z \"${noupdate}\" ]; then\n        (\n            # shellcheck disable=SC2030,SC2031\n            [ -z \"${GIT_TERMINAL_PROMPT:-}\" ] && export GIT_TERMINAL_PROMPT=0\n            eval \"set -- ${kak_opt_plug_plugins}\"\n            while [ $# -gt 0 ]; do\n                plugin_dir=\"${1##*/}\"\n                if [ -d \"${kak_opt_plug_install_dir}/${plugin_dir}\" ]; then (\n                    cd \"${kak_opt_plug_install_dir}/${plugin_dir}\" || exit\n                    git fetch > /dev/null 2>&1\n                    status=$?\n                    if [ ${status} -eq 0 ]; then\n                        { IFS= read -r LOCAL; IFS= read -r REMOTE; IFS= read -r BASE; } <<EOF\n$(\n                        git rev-parse  @ '@{u}'  # prints 2 lines\n                        git merge-base @ '@{u}'\n)\nEOF\n\n                        if [ \"${LOCAL}\" = \"${REMOTE}\" ]; then\n                            message=\"Up to date\"\n                        elif [ \"${LOCAL}\" = \"${BASE}\" ]; then\n                            message=\"Update available\"\n                        elif [ \"${REMOTE}\" = \"${BASE}\" ]; then\n                            message=\"Local changes\"\n                        else\n                            message=\"Installed\"\n                        fi\n                    else\n                        message=\"Fetch Error (${status})\"\n                    fi\n                    plug_fifo_update \"$1\" \"${message}\"\n                ) > /dev/null 2>&1 < /dev/null & fi\n                shift\n            done\n        ) > /dev/null 2>&1 < /dev/null &\n    fi\n}\n\nplug_fifo_operate() {\n    plugin=\"${kak_reg_t%:*}\"\n    case $1 in\n        (install-update)\n            if [ -d \"${kak_opt_plug_install_dir}/${plugin##*/}\" ]; then\n                plug_update \"${plugin}\"\n            else\n                plug_install \"${plugin}\" true\n            fi ;;\n        (update)\n            if [ -d \"${kak_opt_plug_install_dir}/${plugin##*/}\" ]; then\n                plug_update \"${plugin}\"\n            else\n                printf \"%s\\n\" \"echo -markup %{{Information}'${plugin}' is not installed}\"\n            fi ;;\n        (install)\n            if [ ! -d \"${kak_opt_plug_install_dir}/${plugin##*/}\" ]; then\n                plug_install \"${plugin}\"\n            else\n                printf \"%s\\n\" \"echo -markup %{{Information}'${plugin}' already installed}\"\n            fi ;;\n        (clean) plug_clean \"${plugin}\" ;;\n        (log) printf \"%s\\n\" \"plug-display-log $plugin\" ;;\n        (hooks) plug_eval_hooks \"${plugin##*/}\" ;;\n        (*) ;;\n    esac\n}\n\nplug_fifo_update() {\n    printf \"%s\\n\" \"\n        evaluate-commands -draft -buffer *plug* -save-regs \\\"/\\\"\\\"\\\" %{ try %{\n            set-register / \\\"$1: \\\"\n            set-register dquote %{$2}\n            execute-keys -draft /<ret>lGlR\n        }}\" | kak -p \"$kak_session\"\n}\n\nplug_save_timestamp() {\n  plug_tstamp=${EPOCHREALTIME:-}\n  if [ -n \"$plug_tstamp\" ]; then\n    plug_tstamp_ms=${plug_tstamp#*.}\n    case \"$plug_tstamp_ms\" in\n      (????*) plug_tstamp_ms=${plug_tstamp_ms%\"${plug_tstamp_ms#???}\"} ;;\n      (???)   ;;\n      (*)     plug_tstamp= ;;  # redo with date\n    esac\n    if [ -n \"$plug_tstamp\" ]; then\n      plug_tstamp=${plug_tstamp%.*}${plug_tstamp_ms}\n    fi\n  fi\n  : \"${plug_tstamp:=$(date +%s%3N)}\"\n  if [ -n \"$1\" ]; then eval \"$1=\\$plug_tstamp\"; fi\n}\n\n#  Spell-checker local dictionary\n#  LocalWords:  Andrey Listopadov github kak usr config dir Kakoune\n#  LocalWords:  expr ModuleLoaded mkdir ln PWD conf shellcheck noload\n#  LocalWords:  TMPDIR tmp noupdate lockfile rmdir ret gjO esc KakEnd\n#  LocalWords:  nop rf hacky eval fifo filetype BufCloseFifo regs\n#  LocalWords:  dquote lGlR\n"
  }
]