{"id":13647176,"url":"https://github.com/zgqq/mah","last_synced_at":"2026-03-01T00:02:58.784Z","repository":{"id":106460082,"uuid":"79451571","full_name":"zgqq/mah","owner":"zgqq","description":"An alternative to alfred written in java","archived":false,"fork":false,"pushed_at":"2022-10-15T05:29:43.000Z","size":19212,"stargazers_count":69,"open_issues_count":2,"forks_count":6,"subscribers_count":4,"default_branch":"dev","last_synced_at":"2024-11-09T21:36:30.487Z","etag":null,"topics":["alfred","java","mah","productivity"],"latest_commit_sha":null,"homepage":"","language":"Java","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/zgqq.png","metadata":{"files":{"readme":"README.md","changelog":null,"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}},"created_at":"2017-01-19T12:34:39.000Z","updated_at":"2024-07-24T02:36:32.000Z","dependencies_parsed_at":"2024-01-14T10:18:09.430Z","dependency_job_id":null,"html_url":"https://github.com/zgqq/mah","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zgqq%2Fmah","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zgqq%2Fmah/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zgqq%2Fmah/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zgqq%2Fmah/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zgqq","download_url":"https://codeload.github.com/zgqq/mah/tar.gz/refs/heads/dev","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250163563,"owners_count":21385260,"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":["alfred","java","mah","productivity"],"created_at":"2024-08-02T01:03:22.809Z","updated_at":"2026-03-01T00:02:53.685Z","avatar_url":"https://github.com/zgqq.png","language":"Java","funding_links":[],"categories":["Java"],"sub_categories":[],"readme":"** No longer maintained(这个项目不再维护了) **\n# Mah\nMah is an alternative to alfred,written in java.The project is currently under development.\n\n# Plugins\n## Search \n\n    \u003cplugs\u003e\n            \u003cname\u003eSearch\u003c/name\u003e\n    \u003c/plugs\u003e\n    \u003cplug name=\"Search\"\u003e\n            \u003ccommand name=\"GoogleSearchCommand\"\u003e\n                \u003ctrigger key=\"g\" /\u003e\n            \u003c/command\u003e\n    \u003c/plug\u003e\n\n![suggestion](./screenshot/Search.gif \"Search\")\n## Auto suggestion\n\n    \u003cplugs\u003e\n            \u003cname\u003eAutoSuggestion\u003c/name\u003e\n    \u003c/plugs\u003e\n\n![suggestion](./screenshot/AutoSuggestion.gif \"suggestion\")\n\n## KeyRecorder plugin\nKeyRecorder will record all key strokes with modifier such as Control+c,helping you find out those key strokes pressed most.\n\n    \u003cplugs\u003e\n            \u003cname\u003eKeyRecorder\u003c/name\u003e\n    \u003c/plugs\u003e\n    \u003cplug name=\"KeyRecorder\"\u003e\n        \u003ccommand name=\"TopKeystroke\"\u003e\n            \u003ctrigger key=\"tk\" /\u003e\n        \u003c/command\u003e\n    \u003c/plug\u003e\n\n![github plugin](./screenshot/KeyRecorder.gif \"github\")\n\n\n## Translation plugin\nFirst,you need to apply api pair http://fanyi.youdao.com/openapi?path=data-mode\n\n    \u003cplugs\u003e\n            \u003cname\u003etranslation\u003c/name\u003e\n    \u003c/plugs\u003e\n    \u003cplug name=\"translation\"\u003e\n        \u003ccommand name=\"Translation\"\u003e\n            \u003ctrigger key=\"fy\" /\u003e\n            \u003cconfig\u003e\n                \u003ckeyfrom\u003e{keyfrom}\u003c/keyfrom\u003e\n                \u003capikey\u003e{apkey}\u003c/apikey\u003e\n            \u003c/config\u003e\n        \u003c/command\u003e\n    \u003c/plug\u003e\n\n\n![translation plugin](./screenshot/translation.gif \"translation\")\n\n## Weather plugin\n    \u003cplugs\u003e\n            \u003cname\u003eweather\u003c/name\u003e\n    \u003c/plugs\u003e\n    \u003cplug name=\"weather\"\u003e\n        \u003ccommand name=\"QueryWeather\"\u003e\n            \u003ctrigger key=\"we\" /\u003e\n            \u003cconfig\u003e\n                \u003cdefaultCity\u003ebeijing\u003c/defaultCity\u003e\n            \u003c/config\u003e\n        \u003c/command\u003e\n    \u003c/plug\u003e\n\n![weather plugin](./screenshot/weather.gif \"weather\")\n\n## github plugin\nFirst, go to https://github.com/settings/tokens to generate a token\n\n    \u003cplugs\u003e\n            \u003cname\u003egithub\u003c/name\u003e\n    \u003c/plugs\u003e\n    \u003cplug name=\"github\"\u003e\n        \u003cmode name=\"github_mode\" parent=\"item_mode\"\u003e\n            \u003ckeybind bind=\"M-i\" action=\"GoGithubIssues\" /\u003e\n            \u003ckeybind bind=\"M-c\" action=\"ClearCache\" /\u003e\n        \u003c/mode\u003e\n        \u003ccommand name=\"GithubStarredList\"\u003e\n            \u003ctrigger key=\"gs\" /\u003e\n            \u003cconfig\u003e\n                \u003cusername\u003e{your github usename}\u003c/username\u003e\n                \u003c!-- 2 minutes --\u003e\n                \u003cupdateRate\u003e2\u003c/updateRate\u003e\n                \u003ctoken\u003e{your token}\u003c/token\u003e\n                \u003cpostCommand\u003e\u003c/postCommand\u003e\n            \u003c/config\u003e\n        \u003c/command\u003e\n    \u003c/plug\u003e\n\n![github plugin](./screenshot/github.gif \"github\")\n\n## More plugins\nJava libraries are so powerful that it is easy to develop a plugin.\n\n# Features\n## Asynchronous\nFor example,it will take long time to synchronize github repositories you starred;\nyou can execute other actions like translation while synchronizing.\n## Better keybind\nYou can bind as many actions as you want.There are many useful actions in Mah.\nThe mode (input_mode) provides a action named ClearQueryText,which is used to clear\ntext prior to command.Try to imagine that you have translated a long sentence and want to translate another sentence or word,you need to clear input and input command again.Thanks to this action,you don't need to do so.\n## Configurable\nConfiguration is the one of important features,you can configure keybind,plugin,and so on.To configure keybind,you should know what is Mode.Mode is a collection of keybinds,allowing same keybind to execute different actions.For instance,TranslationCommand will trigger translation_mode,in which CopyWord and CopyExplains actions are defined;then you can press alt+w (i defined,you can configure it freely in conf.xml) to execute CopyWord\n action;as a result,translated word will be copied.\n## Plugin support\nMah is totally based on plugin.Thinks to java ecosystem,you can develop a plugin with powerful abilities.\n\n# Getting Started\n## Installation\nMah doesn't provide any binary package for user as there are some efforts to do this.So to use\nMah,you must compile it yourself;it is not a big deal,only tough thing is to install jdk8.Once installed,the rest is easy.\n\n    git clone https://github.com/zgqq/mah \u0026\u0026 cd mah \n    ./install\n\n## Configuration\n    Open /{home}/.config/mah/conf.xml with editor,you will see\n       \n         \u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n          \u003cconfig\u003e\n           \u003cglobal\u003e\n               \u003cglobalKeybind listen=\"M-space\" action=\"FocusWindow\" /\u003e\n           \u003c/global\u003e\n           \u003cmode name=\"system_mode\"\u003e\n               \u003ckeybind bind=\"C-x C-c\" action=\"ExitSystem\" /\u003e\n           \u003c/mode\u003e\n           \u003cmode name=\"window_mode\"\u003e\n               \u003ckeybind bind=\"C-g\" action=\"HideWindow\" /\u003e\n               \u003ckeybind bind=\"M-h\" action=\"MoveWindowToLeft\" /\u003e\n               \u003ckeybind bind=\"M-l\" action=\"MoveWindowToRight\" /\u003e\n               \u003ckeybind bind=\"M-c\" action=\"MoveWindowToCenter\" /\u003e\n           \u003c/mode\u003e\n           \u003cmode name=\"input_mode\"\u003e\n               \u003ckeybind bind=\"C-r\" action=\"Redo\" /\u003e\n               \u003ckeybind bind=\"C-/\" action=\"Undo\" /\u003e\n               \u003c!-- line --\u003e\n               \u003ckeybind bind=\"C-a\" action=\"BeginningOfLine\" /\u003e\n               \u003ckeybind bind=\"C-e\" action=\"EndOfLine\" /\u003e\n               \u003ckeybind bind=\"C-u\" action=\"KillWholeLine\" /\u003e\n               \u003ckeybind bind=\"C-k\" action=\"KillLine\" /\u003e\n               \u003c!-- char --\u003e\n               \u003ckeybind bind=\"backspace\" action=\"BackwardDeleteChar\" /\u003e\n               \u003ckeybind bind=\"C-h\" action=\"BackwardDeleteChar\" /\u003e\n               \u003ckeybind bind=\"C-d\" action=\"DeleteChar\" /\u003e\n               \u003ckeybind bind=\"C-f\" action=\"ForwardChar\" /\u003e\n               \u003ckeybind bind=\"C-b\" action=\"BackwardChar\" /\u003e\n               \u003c!-- word --\u003e\n               \u003ckeybind bind=\"C-backspace\" action=\"BackwardKillWord\" /\u003e\n               \u003ckeybind bind=\"M-f\" action=\"ForwardWord\" /\u003e\n               \u003ckeybind bind=\"M-b\" action=\"BackwardWord\" /\u003e\n               \u003ckeybind bind=\"M-d\" action=\"KillWord\" /\u003e\n           \u003c/mode\u003e\n           \u003cmode name=\"item_mode\"\u003e\n                   \u003c!-- item --\u003e\n                   \u003ckeybind bind=\"C-n\" action=\"NextItem\" /\u003e\n                   \u003ckeybind bind=\"C-p\" action=\"PreviousItem\" /\u003e\n                   \u003ckeybind bind=\"Enter\" action=\"DefaultSelectItem\" /\u003e\n                   \u003ckeybind bind=\"M-1\" action=\"SelectItem1\" /\u003e\n                   \u003ckeybind bind=\"M-2\" action=\"SelectItem2\" /\u003e\n                   \u003ckeybind bind=\"M-3\" action=\"SelectItem3\" /\u003e\n                   \u003ckeybind bind=\"M-4\" action=\"SelectItem4\" /\u003e\n                   \u003ckeybind bind=\"M-5\" action=\"SelectItem5\" /\u003e\n                   \u003ckeybind bind=\"M-6\" action=\"SelectItem6\" /\u003e\n                   \u003ckeybind bind=\"M-7\" action=\"SelectItem7\" /\u003e\n                   \u003ckeybind bind=\"M-8\" action=\"SelectItem8\" /\u003e\n                   \u003ckeybind bind=\"M-9\" action=\"SelectItem9\" /\u003e\n           \u003c/mode\u003e\n           \u003ctheme\u003edark\u003c/theme\u003e\n        \u003c/config\u003e\n\nAbove is most basic configuration,mah will generate it automatically,you can modify it freely.\nNote that you must tell mah if you change key location using tool like xmodmap \n\n    \u003cconfig\u003e\n        \u003cmodifier name=\"Caplock\" as=\"LControl\" /\u003e\n        \u003cmodifier name=\"LControl\" as=\"Caplock\" /\u003e\n    \u003c/config\u003e\n\n## Configuration example \n[conf.xml](https://github.com/zgqq/dotfiles/blob/master/mah/conf.xml)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzgqq%2Fmah","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzgqq%2Fmah","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzgqq%2Fmah/lists"}