{"id":509574,"date":"2024-09-12T16:46:07","date_gmt":"2024-09-12T15:46:07","guid":{"rendered":"https:\/\/blog.jetbrains.com\/?post_type=fleet&#038;p=509574"},"modified":"2024-10-15T19:19:24","modified_gmt":"2024-10-15T18:19:24","slug":"fleet-plugins-now-with-sustom-keymaps","status":"publish","type":"fleet","link":"https:\/\/blog.jetbrains.com\/en\/fleet\/2024\/09\/fleet-plugins-now-with-sustom-keymaps","title":{"rendered":"Fleet Plugins \u2013 Now With \u0421ustom Keymaps"},"content":{"rendered":"\n<p>About a month ago, we <a href=\"https:\/\/blog.jetbrains.com\/fleet\/2024\/08\/fleet-plugins-themes-first\/\">launched<\/a> a mechanism for publishing your color theme as a plugin. With the recent updates, we are extending Fleet plugin applicability even further by allowing you to publish your custom keymaps. You can now map Fleet actions to specific key combinations to streamline your development experience and share the resulting keymap with others.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Customizing keyboard shortcuts<\/h2>\n\n\n\n<p>Keyboard shortcuts can significantly boost your productivity as a software developer, but they can also slow you down if they&#8217;re not the shortcuts you&#8217;re used to. Unfortunately, there\u2019s no one-size-fits-all solution. We put much effort into creating <a href=\"https:\/\/blog.jetbrains.com\/fleet\/2024\/04\/10-fleet-shortcuts-to-boost-your-productivity\/\">Fleet&#8217;s default keymap<\/a> \u2013 we wanted it to respect the system defaults, have familiar shortcuts from other apps like <em>Cmd\/Ctrl+K<\/em>, and be as lightweight as possible to give users the freedom to add their own shortcuts without creating conflicts. However, we understand that it might not be to everyone\u2019s liking. So, we made several customization options available.<\/p>\n\n\n\n<p>First, we added several other keymap options that might work better for you. To switch between them, go to the customization menu by clicking the gear icon in the top-right corner of your Fleet window:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"1434\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/09\/image-10.png\" alt=\"\" class=\"wp-image-509575\"\/><\/figure>\n\n\n\n<p>The <em>Keymap<\/em> dialog allows you to select your preferred keymap:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"1151\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/09\/image-11.png\" alt=\"\" class=\"wp-image-509586\"\/><\/figure>\n\n\n\n<p>Second, we allow keymap customization in the <em>Keymap<\/em> view (it can be launched by the <em>Help | Keymap<\/em> menu item or the <em>Edit Keymap\u2026<\/em> action):<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"1434\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/09\/image-12.png\" alt=\"\" class=\"wp-image-509597\"\/><\/figure>\n\n\n\n<p>The idea behind keymap customization is as follows:&nbsp;<\/p>\n\n\n\n<ul>\n<li>There\u2019s a long list of actions available in Fleet.<\/li>\n\n\n\n<li>You can select any action and then replace the assigned shortcut, remove it, or add a new one.<\/li>\n\n\n\n<li>It\u2019s possible to restore the default shortcuts (those originally defined in your selected keymap).<\/li>\n<\/ul>\n\n\n\n<p>Fleet stores your customizations in the <kbd>user.json<\/kbd> file, for example:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"json\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">{\n  \"keymap\": [\n\t{\n\t\t\"key\": \"shift-cmd-s\",\n\t\t\"action\": \"show-file-symbols\"\n\t},\n\t{\n\t\t\"key\": \"shift-ctrl-a\",\n\t\t\"action\": \"toggle-distraction-free-mode\"\n\t},\n\t{\n\t\t\"key\": \"ctrl-o\",\n\t\t\"action\": \"-open-in\"\n\t}\n  ]\n}<\/pre>\n\n\n\n<p>The keymap array in this example lists all the assignments that differ from the keymap currently selected in Fleet. Let\u2019s call it a <em>delta keymap<\/em>. For every shortcut assignment, we specify a key and an action ID. Removing a default shortcut is expressed as an action ID with the leading \u2018-\u2019 symbol (for example, <code>-open-in<\/code>). Adding several shortcuts for a single action can be expressed by adding several key\/action pairs. Fleet supports viewing and editing this <em>delta<\/em> keymap JSON file directly via the <em>Edit Keymap in JSON File\u2026<\/em> action.<\/p>\n\n\n\n<p>If you\u2019ve heavily customized your keymap and think it makes you more productive, you might want to share it with others. Let\u2019s see how you can publish your keymap as a Fleet plugin.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Publishing custom keymap as a Fleet plugin<\/h2>\n\n\n\n<p>Like <a href=\"https:\/\/blog.jetbrains.com\/fleet\/2024\/08\/fleet-plugins-themes-first\/#step-2-packaging-your-theme-as-a-fleet-plugin\">theme plugins<\/a>, we start packaging a custom keymap by creating a new project from <a href=\"https:\/\/github.com\/JetBrains\/fleet-keymap-plugin-template\/\" target=\"_blank\" rel=\"noopener\">the dedicated keymap plugin template on GitHub<\/a>. Three things need to be adjusted in the project.<\/p>\n\n\n\n<p><strong>First<\/strong>, you must put a keymap JSON file with <strong>a complete list of assigned shortcuts<\/strong> in the <kbd>my-keymap-plugin\/frontendImpl\/src\/jvmMain\/resources\/<\/kbd> folder. The easiest way to build such a file is to manually merge the default Fleet keymap (<kbd>my-custom-keymap.json<\/kbd> in the template) with your customizations (the <em>delta<\/em> keymap) in <kbd>user.json<\/kbd>. There\u2019s one caveat, though. Delta keymap is used for the current operating system, but a complete keymap JSON file is supposed to be useful across different OSes. You can use the <kbd>\u201dwin\u201d<\/kbd>, <kbd>\u201cmac\u201d<\/kbd>, or <kbd>\u201clinux\u201d<\/kbd> key values to set shortcuts specific to the respective operating system. The value of the <kbd>\u201dkey\u201d<\/kbd> field serves as a fallback option. Use definitions in <kbd>my-custom-keymap.json<\/kbd> as an example.<\/p>\n\n\n\n<p>Let\u2019s call this new complete keymap file <kbd>super-productive.json<\/kbd>.<\/p>\n\n\n\n<p><strong>Second<\/strong>, you need to register your keymap as a contribution of your plugin in the <kbd>my-keymap-plugin\/frontendImpl\/src\/jvmMain\/kotlin\/fleet\/sample\/frontendImpl\/MyKeymapPlugin.kt<\/kbd> file:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"kotlin\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">package fleet.sample.frontendImpl\n\nimport fleet.frontend.keymap.KeymapId\nimport fleet.frontend.keymap.registerKeymap\nimport fleet.kernel.plugins.ContributionScope\nimport fleet.kernel.plugins.Plugin\nimport fleet.kernel.plugins.PluginScope\n\nclass MyKeymapPlugin : Plugin&lt;Unit> {\n\n    companion object : Plugin.Key&lt;Unit>\n\n    override val key: Plugin.Key&lt;Unit> = MyKeymapPlugin\n\n    override fun ContributionScope.load(pluginScope: PluginScope) {\n        registerKeymap(\n            id = KeymapId(\"super-productive\"), \n            presentableName = \"Fleet Super Productive\")\n    }\n}<\/pre>\n\n\n\n<p>The keymap ID must be the same as the name of the keymap JSON file (without an extension).<\/p>\n\n\n\n<p><strong>Third<\/strong>, we need to configure the plugin itself. The plugin should have a unique <kbd><code>id<\/code><\/kbd>, a readable name, and a description. The name and the description are visible both on Marketplace and in Fleet\u2019s <em>Plugins<\/em> view (use the <em>Plugins\u2026<\/em> action to open it). These parameters are set in the <kbd>my-keymap-plugin\/build.gradle.kts<\/kbd> file, for example:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">plugins {\n\tbase\n\talias(libs.plugins.fleet.plugin)\n}\n\nversion = \"0.1.0\"\n\nfleetPlugin {\n\tid = \"pro.bravit.super.keymap\"\n\tmetadata {\n\t\treadableName = \"Fleet Super Productive\"\n\t\tdescription = \"Super productive keymap for Fleet\"\n\t}\n\tfleetRuntime {\n\t\tversion = libs.versions.fleet.runtime\n\t}\n}<\/pre>\n\n\n\n<p>Once we are done editing the files, we can launch Fleet with the plugin in development by opening the <em>Run<\/em> dialog and choosing the <em>Run Fleet with local plugin<\/em> run configuration. The Fleet instance will be launched after a bit of compilation and will have our keymap available in the <em>Select Keymap\u2026<\/em> dialog:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"1102\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/09\/image-13.png\" alt=\"\" class=\"wp-image-509608\"\/><\/figure>\n\n\n\n<p>We can also check out the <em>Plugins<\/em> view to make sure that the plugin has been loaded:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"1102\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/09\/image-14.png\" alt=\"\" class=\"wp-image-509619\"\/><\/figure>\n\n\n\n<p>While experimenting with your new keymap, you can get your changes as a delta keymap (as described in the previous section) and then transfer them to the complete keymap JSON file. Note that any changes you make to your complete keymap JSON file now won\u2019t be immediately visible in the running Fleet instance. You need to restart Fleet with the <em>Run Fleet with local plugin<\/em> run configuration selected in order for your changes to take effect.<\/p>\n\n\n\n<p>Once you finish editing and testing your keymap, please follow the <a href=\"https:\/\/www.jetbrains.com\/help\/fleet\/building-custom-theme-plugins.html#publishing-your-plugin-at-jetbrains-marketplace\" target=\"_blank\" rel=\"noopener\">instructions from the documentation<\/a> to publish your new keymap plugin to <a href=\"https:\/\/plugins.jetbrains.com\/\" target=\"_blank\" rel=\"noopener\">JetBrains Marketplace<\/a>. The Marketplace team will check the uploaded plugin, and following their approval, it will become available for anyone to install from the <em>Plugins<\/em> view in Fleet:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"1072\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/09\/image-15.png\" alt=\"\" class=\"wp-image-509630\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>We now allow you to publish your custom color themes and keymaps as Fleet plugins. Some users <a href=\"https:\/\/plugins.jetbrains.com\/plugin\/25081-catppuccin-fleet-theme\" target=\"_blank\" rel=\"noopener\">have already done so<\/a>. But this is just the beginning. You can do much more to customize Fleet\u2019s behavior with plugins. The <a href=\"https:\/\/blog.jetbrains.com\/fleet\/2024\/08\/fleet-plugins-themes-first\/#fleet-plugins-roadmap\">road ahead<\/a> is long and full of possibilities.<\/p>\n\n\n\n<p>Stay with us on this journey!<\/p>\n","protected":false},"author":1335,"featured_media":509997,"comment_status":"closed","ping_status":"closed","template":"","categories":[6815,89,1065],"tags":[],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/fleet\/509574"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/fleet"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/types\/fleet"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/users\/1335"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/comments?post=509574"}],"version-history":[{"count":9,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/fleet\/509574\/revisions"}],"predecessor-version":[{"id":510020,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/fleet\/509574\/revisions\/510020"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/media\/509997"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/media?parent=509574"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/categories?post=509574"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/tags?post=509574"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/cross-post-tag?post=509574"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}