{"id":15674686,"url":"https://github.com/dynobo/keyhint","last_synced_at":"2026-02-26T03:36:22.581Z","repository":{"id":43181579,"uuid":"260449684","full_name":"dynobo/keyhint","owner":"dynobo","description":"Cheat-sheets for shortcuts \u0026 commands at your fingertips.","archived":false,"fork":false,"pushed_at":"2025-04-12T17:56:20.000Z","size":26337,"stargazers_count":16,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-12T18:28:17.248Z","etag":null,"topics":["keybindings","shortcuts","tool"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dynobo.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2020-05-01T12:05:51.000Z","updated_at":"2025-04-12T17:56:24.000Z","dependencies_parsed_at":"2023-01-25T13:46:05.555Z","dependency_job_id":"968657b3-d3c5-4a3b-8238-9dd244b3fa7f","html_url":"https://github.com/dynobo/keyhint","commit_stats":{"total_commits":176,"total_committers":2,"mean_commits":88.0,"dds":0.05681818181818177,"last_synced_commit":"5bb2c5e250f28de9e92cff0ea96d3ba491603626"},"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dynobo%2Fkeyhint","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dynobo%2Fkeyhint/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dynobo%2Fkeyhint/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dynobo%2Fkeyhint/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dynobo","download_url":"https://codeload.github.com/dynobo/keyhint/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249058372,"owners_count":21205910,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["keybindings","shortcuts","tool"],"created_at":"2024-10-03T15:49:18.754Z","updated_at":"2026-02-26T03:36:22.575Z","avatar_url":"https://github.com/dynobo.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# KeyHint\n\n**_Utility to display keyboard shortcuts or other hints based on the active window on\nLinux._**\n\n\u003cp align=\"center\"\u003e\u003cbr\u003e\n\u003cimg alt=\"Tests passing\" src=\"https://github.com/dynobo/keyhint/workflows/Test/badge.svg\"\u003e\n\u003ca href=\"https://github.com/dynobo/keyhint/blob/main/LICENSE\"\u003e\u003cimg alt=\"License: MIT\" src=\"https://img.shields.io/badge/License-MIT-blue.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/psf/black\"\u003e\u003cimg alt=\"Code style: black\" src=\"https://img.shields.io/badge/Code%20style-black-%23000000\"\u003e\u003c/a\u003e\n\u003ca href='https://coveralls.io/github/dynobo/keyhint'\u003e\u003cimg src='https://coveralls.io/repos/github/dynobo/keyhint/badge.svg' alt='Coverage Status' /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n![Keyhint Screenshot](https://raw.githubusercontent.com/dynobo/keyhint/main/keyhint/resources/keyhint.png)\n\n## Prerequisites\n\n- Python 3.11+\n- GTK 4.12+ (shipped since Ubuntu 23.10) + related dev packages:\n  ```sh\n  sudo apt-get install \\\n     libgirepository1.0-dev \\\n     libcairo2-dev \\\n     python3-gi \\\n     gobject-introspection \\\n     libgtk-4-dev\n  ```\n- Wayland \u0026 Gnome: The\n  [Gnome Extension \"Window-Calls\"](https://extensions.gnome.org/extension/4724/window-calls/)\n  is required to auto-select the cheatsheet based on the current active application.\n\n## Installation\n\n- `uv tool install keyhint` (recommended, requires [uv](https://docs.astral.sh/uv/))\n- `pipx install keyhint` (requires [pipx](https://pipx.pypa.io/))\n- _or_ `pip install keyhint`\n\n## Usage\n\n- Configure a **global hotkey** (e.g. `Ctrl + F1`) **via your system settings** to\n  launch `keyhint`.\n- If KeyHint is launched via hotkey, it detects the current active application and shows\n  the appropriate hints. (This feature won't work reliably when KeyHint ist started via\n  Menu or Launcher.)\n\n## CLI Options\n\n```\nApplication Options:\n  -c, --cheatsheet=SHEET-ID                 Show cheatsheet with this ID on startup\n  -v, --verbose                             Verbose log output for debugging\n```\n\n## Cheatsheet Configuration\n\nThe content which KeyHint displays is configured using [`toml`](https://toml.io/en/)\nconfiguration files.\n\nKeyHint reads those files from two locations:\n\n1. The [built-in directory](https://github.com/dynobo/keyhint/tree/main/keyhint/config)\n1. The user directory, usually located in `~/.config/keyhint`\n\n### How Keyhint selects the cheatsheet to show\n\n- The cheatsheet to be displayed on startup are selected by comparing the value of\n  `regex_wmclass` with the wm_class of the active window and the value of `regex_title`\n  with the title of the active window.\n- The potential cheatsheets are processed alphabetically by filename, the first file\n  that matches both wm_class and title are getting displayed.\n- Both of `regex_` values are interpreted as **case in-sensitive regular expressions**.\n- Check \"Debug Info\" in the application menu to get insights about the active window and\n  the selected cheatsheet file.\n\n### Customize or add cheatsheets\n\n- To **change built-in** cheatsheets, copy\n  [the corresponding .toml-file](https://github.com/dynobo/keyhint/tree/main/keyhint/config)\n  into the config directory. Make your changes in a text editor. As long as you don't\n  change the `id` it will overwrite the defaults.\n- To **create new** cheatsheets, I suggest you start with\n  [one of the existing .toml-file](https://github.com/dynobo/keyhint/tree/main/keyhint/config):\n  - Place it in the config directory and give it a good file name.\n  - Change the value `id` to something unique.\n  - Adjust `regex_wmclass` and `regex_title` so it will be selected based on the active\n    window. (See [Tips](#tips))\n  - Add the `shortcuts` \u0026 `label` to a `section`.\n  - If you think your cheatsheet might be useful for others, please consider opening a\n    pull request or an issue!\n- You can always **reset cheatsheets** to the shipped version by deleting the\n  corresponding `.toml` files from the config folder.\n- You can **include shortcuts from other cheatsheets** by adding\n  `include = [\"\u003cCheatsheet ID\u003e\"]`\n\n### Examples\n\n#### Hide existing cheatsheets\n\nTo hide a cheatsheet, e.g. the\n[built-in](https://github.com/dynobo/keyhint/blob/main/keyhint/config/tilix.toml) one\nwith the ID `tilix`, create a new file `~/.config/keyhint/tilix.toml` with the content:\n\n```toml\nid = \"tilix\"\nhidden = true\n```\n\n#### Extend existing cheatsheets\n\nTo add keybindings to an existing cheatsheet, e.g. the\n[built-in](https://github.com/dynobo/keyhint/blob/main/keyhint/config/firefox.toml) one\nwith the ID `firefox`, create a new file `~/.config/keyhint/firefox.toml` which only\ncontains the ID and the additional bindings:\n\n```toml\nid = \"firefox\"\n\n[section]\n[section.\"My Personal Favorites\"]  # New section\n\"Ctrl + Shift + Tab\" = \"Show all Tabs\"\n# ...\n```\n\n#### Add new cheatsheet which never gets auto-selected\n\nTo add a new cheatsheet, which never gets automatically selected and displayed by\nKeyHint, but remains accessible through KeyHint's cheatsheet dropdown, create a file\n`~/.config/keyhint/my-app.toml`:\n\n```toml\nid = \"my-app\"\nurl = \"url-to-my-apps-keybindings\"\n\n[match]\nregex_wmclass = \"a^\"  # Patter which never matches\nregex_title = \"a^\"\n\n[section]\n[section.General]\n\"Ctrl + C\" = \"Copy\"\n# ...\n\n```\n\n#### Different cheatsheets for different Websites\n\nFor showing different browser-cheatsheets depending on the current website, you might\nwant to use a browser extension like\n\"[Add URL To Window Title](https://addons.mozilla.org/en-US/firefox/addon/add-url-to-window-title/)\"\nand configure the `[match]` section to look for the url in the title. E.g.\n`~/.config/keyhint/github.toml`\n\n```toml\nid = \"github.com\"\n\n[match]\nregex_wmclass = \"Firefox\"\nregex_title = \".*github\\\\.com.*\"  # URL added by browser extensions to window title\n\n[section]\n[section.Repositories]\ngc = \"Goto code tab\"\n# ...\n```\n\n## Contribute\n\nI'm happy about any contribution! Especially I would appreciate submissions to improve\nthe\n[shipped cheatsheets](https://github.com/dynobo/keyhint/tree/main/keyhint/config).\n(The current set are the cheatsheets I personally use).\n\n## Design Principles\n\n- **Don't run as service**\u003cbr\u003eIt shouldn't consume resources in the background, even if\n  this leads to slightly slower start-up time.\n- **No network connection**\u003cbr\u003eEverything should run locally without any network\n  communication.\n- **Dependencies**\u003cbr\u003eThe fewer dependencies, the better.\n\n## Certification\n\n![WOMM](https://raw.githubusercontent.com/dynobo/lmdiag/master/badge.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdynobo%2Fkeyhint","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdynobo%2Fkeyhint","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdynobo%2Fkeyhint/lists"}