{"id":20951361,"url":"https://github.com/lgug2z/komokana","last_synced_at":"2026-04-01T22:44:14.439Z","repository":{"id":49717214,"uuid":"517825422","full_name":"LGUG2Z/komokana","owner":"LGUG2Z","description":"Automatic application-aware keyboard layer switching for Windows","archived":false,"fork":false,"pushed_at":"2026-03-22T02:00:08.000Z","size":272,"stargazers_count":202,"open_issues_count":0,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2026-03-22T17:19:47.667Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LGUG2Z.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"LGUG2Z","ko_fi":"lgug2z"}},"created_at":"2022-07-25T21:26:38.000Z","updated_at":"2026-03-22T01:59:42.000Z","dependencies_parsed_at":"2024-02-18T05:23:45.330Z","dependency_job_id":"94985df8-a49f-4b38-a50e-49778a7463f6","html_url":"https://github.com/LGUG2Z/komokana","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/LGUG2Z/komokana","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LGUG2Z%2Fkomokana","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LGUG2Z%2Fkomokana/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LGUG2Z%2Fkomokana/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LGUG2Z%2Fkomokana/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LGUG2Z","download_url":"https://codeload.github.com/LGUG2Z/komokana/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LGUG2Z%2Fkomokana/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31292692,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T21:15:39.731Z","status":"ssl_error","status_checked_at":"2026-04-01T21:15:34.046Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-19T00:58:31.254Z","updated_at":"2026-04-01T22:44:14.425Z","avatar_url":"https://github.com/LGUG2Z.png","language":"Rust","funding_links":["https://github.com/sponsors/LGUG2Z","https://ko-fi.com/lgug2z"],"categories":[],"sub_categories":[],"readme":"# komokana\n\nAutomatic application-aware keyboard layer switching for Windows\n\n# About\n\n`komokana` is a daemon that listens to events emitted by [`komorebi`](https://github.com/LGUG2Z/komorebi) and communicates\nwith [`kanata`](https://github.com/jtroo/kanata) to switch keyboard layers based on a set of user defined rules.\n\n`komokana` allows you associate different `kanata` keyboard layers with specific applications, and automatically switch\nto that keyboard layer when the windows of those applications are focused in the foreground.\n\nYou may join the `komorebi` [Discord server](https://discord.gg/mGkn66PHkx) for any `komokana`-related discussion, help,\ntroubleshooting, etc. If you have any specific feature requests or bugs to report, please create an issue in this repository.\n\nArticles, blog posts, demos and videos about `komokana` can be added to this section of the readme by PR.\n\n# Description\n\n`komokana` communicates with `komorebi`\nusing [Named Pipes](https://docs.microsoft.com/en-us/windows/win32/ipc/named-pipes),\nand with `kanata` via a [TCP server](https://en.wikipedia.org/wiki/Transmission_Control_Protocol) that can be optionally\nstarted by passing the `--port` flag when launching the `kanata` process.\n\nIf either the `komorebi` or `kanata` processes are stopped or killed, `komokana` will attempt to reconnect to them\nindefinitely. However, `komokana` will not launch successfully if either one of those processes is not running.\n\n# Getting Started\n\n## Prerequisites\n\n- The latest version of `komorebi` from either scoop or WinGet\n  - `scoop install komorebi` (from the `extras` bucket)\n  - `winget install LGUG2Z.komokana`\n- The latest version of `kanata`\n  - `cargo install kanata`\n\n## GitHub Releases\n\nPrebuilt binaries of tagged releases are available on the [releases page](https://github.com/LGUG2Z/komokana/releases)\nin a `zip` archive.\n\nOnce downloaded, you will need to move the `komokana.exe` binary to a directory in your `Path` (\nyou can see these directories by running `$Env:Path.split(\";\")` at a PowerShell prompt).\n\nAlternatively, you may add a new directory to your `Path`\nusing [`setx`](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/setx) or the Environment\nVariables pop up in System Properties Advanced (which can be launched with `SystemPropertiesAdvanced.exe` at a\nPowerShell prompt), and then move the binaries to that directory.\n\n## Scoop\n\nIf you use the [Scoop](https://scoop.sh/) command line installer, you can run\nthe following commands to install the binaries from the latest GitHub Release:\n\n```powershell\nscoop bucket add extras\nscoop install komokana\n```\n\nIf you install _komokana_ using Scoop, the binary will automatically be added\nto your `Path`.\n\n## Building from Source\n\nIf you prefer to compile _komokana_ from source, you will need\na [working Rust development environment on Windows 10](https://rustup.rs/). The `x86_64-pc-windows-msvc` toolchain is\nrequired, so make sure you have also installed\nthe [Build Tools for Visual Studio 2019](https://stackoverflow.com/a/55603112).\n\nYou can then clone this repo and compile the source code to install the binary for `komokana`:\n\n```powershell\ncargo install --path . --locked\n```\n\n## Configuring\n\n`komokana` is configured using a YAML file that can be specified using the `-c` flag.\n\nConsider the following `kanata.kbd` file which defines our keyboard layers:\n\n```clojure\n(defalias\n  ;; these are some convenient aliases to send the letter on tap, or toggle the\n  ;; \"firefox\" layout on hold\n  ft   (tap-hold 50 200 f (layer-toggle firefox))\n  jt   (tap-hold 50 200 j (layer-toggle firefox))\n\n  ;; these are some convenient aliases for us to switch layers\n  qwr  (layer-switch qwerty)\n  ff   (layer-switch firefox)\n)\n\n;; imagine this is our default layer, passed as \"-d qwerty\" when launching komokana\n;; the only two keys overriden here are f and j, which when held, will toggle\n;; our \"firefox\" layer\n(deflayer qwerty\n  _    _    _    _    _    _    _    _    _    _    _    _    _          _    _    _\n  _    _    _    _    _    _    _    _    _    _    _    _    _    _     _    _    _\n  _    _    _    _    _    _    _    _    _    _    _    _    _    _     _    _    _\n  _    _    _    _    @ft  _    _    @jt  _    _    _    _    _\n  _    _    _    _    _    _    _    _    _    _    _    _    _               _\n  _    _    _              _                   _    _         _          _    _    _\n)\n\n;; this is our firefox layer which lets us navigate webpages using hjkl\n(deflayer firefox\n  _    _    _    _    _    _    _    _    _    _    _    _    _          _    _    _\n  _    _    _    _    _    _    _    _    _    _    _    _    _    _     _    _    _\n  _    _    _    _    _    _    _    _    _    _    _    _    _    _     _    _    _\n  _    _    _    _    _    _    left down up   rght _    _    _\n  _    _    _    _    _    _    _    _     _    _   _    _    _               _\n  _    _    _              _                    _   _         _          _    _    _\n)\n\n;; this is our editor layer for use in windows where the vim editor or vim extensions\n;; in a text editor are running. the only thing we do here is ensure that the tap-hold\n;; not present on j, so that when we hold down j we can zoom all the way down the file\n;; that we are editing\n(deflayer editor\n  _    _    _    _    _    _    _    _    _    _    _    _    _          _    _    _\n  _    _    _    _    _    _    _    _    _    _    _    _    _    _     _    _    _\n  _    _    _    _    _    _    _    _    _    _    _    _    _    _     _    _    _\n  _    _    _    _    @ft  _    _    _    _    _    _    _    _\n  _    _    _    _    _    _    _    _    _    _    _    _    _               _\n  _    _    _              _                   _    _         _          _    _    _\n)\n```\n\nBased on the `kanata` layers defined above, we can have a `komokana.yaml` configuration file that looks like this:\n\n```yaml\n- exe: \"firefox.exe\" # when a window with this exe is active\n  target_layer: \"firefox\" # switch to this layer, a vim-like layer just for browsing!\n  title_overrides: # unless...\n    - title: \"Slack |\" # the window title matches this\n      # valid matching strategies are: starts_with, ends_with, contains and equals\n      strategy: \"starts_with\" # matching with this matching strategy\n      target_layer: \"qwerty\" # if it does, then switch to this layer for chatting\n    - title: \"Mozilla Firefox\" # new firefox tab, we'll probably want to switch to qwerty mode to type a url!\n      strategy: \"equals\"\n      target_layer: \"qwerty\"\n  virtual_key_overrides: # unless...\n    # list of key codes and their decimal values here: https://cherrytree.at/misc/vk.htm\n    - virtual_key_code: 18 # this key is held down (alt in this case) when the window becomes active\n      targer_layer: \"qwerty\" # if it is, then switch to this layer, so that we can continue switching window focus with alt+hjkl\n  virtual_key_ignores: # alternatively\n    - 18 # if this key is held down (alt in this case), then don't make any layer switches\n\n# your normal layer might have a tap-hold on j since it's a such convenient and ergonomic key\n# but it sucks to be in vim, holding down j to move down and have nothing happen because of the hold...\n# no worries! let's just switch to a layer which removes the tap-hold on the j when we are in windows\n# where we use vim or vim editing extensions!\n- exe: \"WindowsTerminal.exe\"\n  target_layer: \"editor\"\n- exe: \"idea64.exe\"\n  target_layer: \"editor\"\n```\n\n## Running\n\nOnce you have either the prebuilt binaries in your `Path`, or have compiled the binaries from source (these will already\nbe in your `Path` if you installed Rust with [rustup](https://rustup.rs), which you absolutely should), you can\nrun `komokana -p [KANATA_PORT] -d [DEFAULT_LAYER] -c [PATH_TO_YOUR_CONFIG]` at a Powershell prompt, and you should start to see log output.\n\nRemember, both `komorebi` and `kanata` must be running before you try to start `komokana`, and `kanata` must be running\nwith the `--port` flag to enable the TCP server on the given port.\n\nThis means that `komokana` is now running and listening for notifications sent to it by `komorebi`.\n\n### `yasb` Widget\n\nWhen running `komokana` with the `-t` flag, a plaintext file will be updated whenever the layer changes at the following\nlocation: `~/AppData/Local/Temp/kanata_layer`\n\nYou may optionally use this file to construct a simple [`yasb`](https://github.com/denBot/yasb) widget which polls and\ndisplays the contents of that file to provide a visual indicator of the currently :\n\n```yaml\n# in ~/.yasb/config.yaml\nwidgets:\n  kanata:\n    type: \"yasb.custom.CustomWidget\"\n    options:\n      label: \"{data}\"\n      label_alt: \"{data}\"\n      class_name: \"kanata-widget\"\n      exec_options:\n        run_cmd: \"cat '%LOCALAPPDATA%\\\\Temp\\\\kanata_layer'\"\n        run_interval: 300\n        return_format: \"string\"\n```\n\n# Contribution Guidelines\n\nIf you would like to contribute to `komokana` please take the time to carefully read the guidelines below.\n\n## Commit hygiene\n\n- Flatten all `use` statements\n- Run `cargo +stable clippy` and ensure that all lints and suggestions have been addressed before committing\n- Run `cargo +nightly fmt --all` to ensure consistent formatting before committing\n- Use `git cz` with\n  the [Commitizen CLI](https://github.com/commitizen/cz-cli#conventional-commit-messages-as-a-global-utility) to prepare\n  commit messages\n- Provide **at least** one short sentence or paragraph in your commit message body to describe your thought process for the\n  changes being committed\n\n## License\n\n`komokana` is licensed under the [Komorebi 2.0.0 license](./LICENSE.md), which\nis a fork of the [PolyForm Strict 1.0.0\nlicense](https://polyformproject.org/licenses/strict/1.0.0). On a high level\nthis means that you are free to do whatever you want with `komokana` for\npersonal use other than redistribution, or distribution of new works (i.e.\nhard-forks) based on the software.\n\nAnyone is free to make their own fork of `komokana` with changes intended\neither for personal use or for integration back upstream via pull requests.\n\n_The [Komorebi 2.0.0 License](./LICENSE.md) does not permit any kind of\ncommercial use._\n\n### Contribution licensing\n\nContributions are accepted with the following understanding:\n\n- Contributed content is licensed under the terms of the 0-BSD license\n- Contributors accept the terms of the project license at the time of contribution\n\nBy making a contribution, you accept both the current project license terms, and that all contributions that you have\nmade are provided under the terms of the 0-BSD license.\n\n#### Zero-Clause BSD\n\n```\nPermission to use, copy, modify, and/or distribute this software for\nany purpose with or without fee is hereby granted.\n\nTHE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL\nWARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\nOF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE\nFOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY\nDAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN\nAN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT\nOF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flgug2z%2Fkomokana","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flgug2z%2Fkomokana","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flgug2z%2Fkomokana/lists"}