Environment
| Field |
Value |
| Micro version |
2.0.16-dev.51 (CGO_ENABLED=1) |
| Distro |
CachyOS (Arch Linux) |
| Kernel |
7.0.9-1-cachyos |
| CPU |
Intel Core i5-1240P |
| GPU |
Intel Iris Xe Graphics [ADL GT2] |
| GPU Driver |
i915 |
| Mesa |
26.1.1 |
| Compositor |
labwc |
My settings.json
{
"*.bak": {
"filetype": "micro"
},
"*.conf": {
"filetype": "ini"
},
"*.txt": {
"filetype": "micro"
},
"autosu": true,
"clipboard": "external",
"colorscheme": "dukedark_mod-tc",
"diffgutter": true,
"ft:asciidoc": {
"tabsize": 2
},
"ft:asm": {
"tabstospaces": false
},
"ft:awk": {
"tabstospaces": false
},
"ft:c": {
"tabsize": 2
},
"ft:c++": {
"tabsize": 2
},
"ft:clojure": {
"tabsize": 2
},
"ft:cmake": {
"tabsize": 2
},
"ft:crystal": {
"tabsize": 2
},
"ft:css": {
"tabsize": 2
},
"ft:cuda": {
"tabstospaces": false
},
"ft:dart": {
"tabsize": 2
},
"ft:ebuild": {
"tabstospaces": false
},
"ft:elixir": {
"tabsize": 2
},
"ft:forth": {
"tabstospaces": false
},
"ft:gdscript": {
"tabstospaces": false
},
"ft:gleam": {
"tabsize": 2
},
"ft:go": {
"tabstospaces": false
},
"ft:gomod": {
"tabstospaces": false
},
"ft:graphql": {
"tabsize": 2
},
"ft:haskell": {
"tabsize": 2
},
"ft:html": {
"tabsize": 2
},
"ft:html5": {
"tabsize": 2
},
"ft:jinja2": {
"tabsize": 2
},
"ft:json": {
"tabsize": 2
},
"ft:jsonnet": {
"tabsize": 2
},
"ft:justfile": {
"tabstospaces": false
},
"ft:lisp": {
"tabsize": 2
},
"ft:lua": {
"tabsize": 2
},
"ft:makefile": {
"tabstospaces": false
},
"ft:markdown": {
"tabsize": 2
},
"ft:meson": {
"tabsize": 2
},
"ft:msbuild": {
"tabsize": 2
},
"ft:nim": {
"tabsize": 2
},
"ft:nix": {
"tabsize": 2
},
"ft:ocaml": {
"tabsize": 2
},
"ft:proto": {
"tabsize": 2
},
"ft:puppet": {
"tabsize": 2
},
"ft:r": {
"tabsize": 2
},
"ft:ruby": {
"tabsize": 2
},
"ft:scala": {
"tabsize": 2
},
"ft:shell": {
"tabsize": 4
},
"ft:svelte": {
"tabsize": 2
},
"ft:terraform": {
"tabsize": 2
},
"ft:tex": {
"tabsize": 2
},
"ft:typescript": {
"tabsize": 2
},
"ft:vue": {
"tabsize": 2
},
"ft:xml": {
"tabsize": 2
},
"ft:yaml": {
"tabsize": 2
},
"ft:zsh": {
"tabsize": 4
},
"helpsplit": "vsplit",
"hlsearch": true,
"matchbracestyle": "highlight",
"mkparents": true,
"parsecursor": true,
"paste": false,
"rmtrailingws": false,
"ruler": false,
"savecursor": false,
"saveundo": false,
"scrollbar": true,
"scrollbarchar": "│",
"scrollspeed": 3,
"smartpaste": true,
"softwrap": true,
"statusformatl": "$(filename) $(modified)$(overwrite) $(status.paste)| ft:$(opt:filetype) | $(opt:fileformat) | $(opt:encoding)",
"statusformatr": "$(line):$(col) | $(lines) ",
"tabhighlight": false,
"tabmovement": true,
"tabsize": 4,
"tabstospaces": true,
"truecolor": "on",
"useprimary": true,
"wordwrap": true,
"xterm": false
}
My bindings.json
{
"Alt-r": "command:toggle ruler",
"Alt-s": "command:setlocal showchars 'tab=›,space=·'",
"Alt-Ctrl-s": "command:reset showchars",
"Alt-t": "command:togglelocal hltaberrors|command:togglelocal hltrailingws",
"Alt-w": "command:toggle softwrap|command:toggle wordwrap",
"\u001bк": "command:toggle ruler",
"\u001bы": "command:setlocal showchars 'tab=›,space=·'",
"\u001b\u0013": "command:reset showchars",
"\u001bе": "command:togglelocal hltaberrors|command:togglelocal hltrailingws",
"\u001bц": "command:toggle softwrap|command:toggle wordwrap",
"Alt-Enter": "CommandMode",
"\u001b[27;5;13~": "CommandMode",
"\u001b[27;2;13~": "InsertNewline",
"F3": "FindNext",
"Shift-F3": "FindPrevious",
"Alt-Ctrl-Down": "FindNext",
"Alt-Ctrl-Up": "FindPrevious",
"command": {
"Alt-Enter": "AbortCommand",
"\u001b[27;5;13~": "AbortCommand",
"Ctrl-e": "AbortCommand"
}
}
Description
I've encountered two keybinding bugs while configuring Micro in Foot/Kitty with a Cyrillic keyboard layout. Both issues stem from how Micro parses key events internally versus what the terminal actually sends.
Bug 1: Raw escape sequences are ignored in the command pane
Terminals such as Foot or Kitty send specific raw escape sequences for modified keys. For example, Ctrl+Enter sends \x1b[27;5;13~ and Shift+Enter sends \x1b[27;2;13~.
Using the > raw command, I can see Micro receives these sequences correctly in the main buffer. I can bind them in bindings.json:
{
"Alt-Enter": "CommandMode",
"\u001b[27;5;13~": "CommandMode",
"\u001b[27;2;13~": "InsertNewline"
}
This works perfectly in the main buffer. However, to create a toggle for the command mode, I need to bind the same key to AbortCommand inside the "command" pane type:
{
"command": {
"Alt-Enter": "AbortCommand",
"\u001b[27;5;13~": "AbortCommand"
}
}
Expected behavior: Pressing Ctrl+Enter while the command bar is open should execute AbortCommand and close the command bar (just like Alt-Enter does when bound this way).
Actual behavior: The raw escape sequence binding is completely ignored in the command pane. Pressing the key does nothing. The command pane parser does not support matching raw escape sequences the way the main buffer does.
Bug 2: Alt + Non-Latin keys require manual raw Unicode mappings
When using a non-Latin (Cyrillic ru_RU) keyboard layout, pressing Alt + a key sends an escape sequence containing the Unicode character of the Cyrillic letter, not the physical Latin key.
For example, Alt+r on a Cyrillic layout sends \x1bк (because 'к' is on the same physical key as 'r'). Micro does not map this to the logical Alt-r binding. To make it work, I have to manually figure out the raw sequence and duplicate every Alt binding (as seen in my bindings.json above):
{
"Alt-r": "command:toggle ruler",
"\u001bк": "command:toggle ruler"
}
Expected behavior: Micro should ideally map keybindings based on the physical key position, or at least provide a mechanism to define layout-agnostic bindings so users don't have to duplicate all Alt bindings with raw Unicode codes.
Actual behavior: Users with non-Latin layouts must duplicate all Alt keybindings using raw \u001b<unicode_char> sequences, making the config bloated and hard to maintain.
And a few small requests ...
Feature Request 1: Native Shift-Enter support
Currently, to make Shift+Enter insert a newline, users of Foot/Kitty have to manually bind the raw escape sequence (\u001b[27;2;13~) to InsertNewline. It would be much more user-friendly if Micro natively supported the logical binding "Shift-Enter": "InsertNewline" out of the box, abstracting away the terminal-specific escape sequences.
Feature Request 2: Add a native CommandMode toggle
Currently, CommandMode only opens the command bar. To close it, you need a separate action (AbortCommand or Escape) in the "command" pane.
I heavily rely on the command bar for text manipulation using the manipulator-plugin. This plugin provides commands like > brace, > squote, > dquote, > upper, etc. My workflow constantly involves opening the command bar, typing a case conversion command, and executing it.
Having a single CommandMode toggle action (instead of separate open/close actions) would make this workflow significantly faster and more ergonomic.
Feature Request 3: Make Ctrl-e a toggle by default
Following up on the previous point, since working with plugins like manipulator requires frequent access to the command bar, it makes perfect sense for Ctrl-e to act as a toggle by default. Currently, if I press Ctrl-e to open the bar and change my mind, I have to reach for Esc to close it. If Ctrl-e were a toggle (mapped to a ToggleCommandMode action), the workflow would be seamless: press Ctrl-e, type snake, press Enter. Or press Ctrl-e again to cancel.
Summary of requested changes:
- Fix: Allow raw escape sequence bindings (like
\u001b[27;5;13~) to work inside the "command" pane type.
- Fix: Improve handling of
Alt modifiers for non-Latin keyboard layouts (physical key mapping).
- Feature: Add native support for
"Shift-Enter": "InsertNewline" without requiring raw escape hacks.
- Feature: Add a
ToggleCommandMode action.
- Feature: Change the default
Ctrl-e binding from CommandMode to ToggleCommandMode.
Thank you for your time and for maintaining the best editor
Environment
2.0.16-dev.51 (CGO_ENABLED=1)CachyOS (Arch Linux)7.0.9-1-cachyosIntel Core i5-1240PIntel Iris Xe Graphics [ADL GT2]i91526.1.1labwcMy settings.json
{ "*.bak": { "filetype": "micro" }, "*.conf": { "filetype": "ini" }, "*.txt": { "filetype": "micro" }, "autosu": true, "clipboard": "external", "colorscheme": "dukedark_mod-tc", "diffgutter": true, "ft:asciidoc": { "tabsize": 2 }, "ft:asm": { "tabstospaces": false }, "ft:awk": { "tabstospaces": false }, "ft:c": { "tabsize": 2 }, "ft:c++": { "tabsize": 2 }, "ft:clojure": { "tabsize": 2 }, "ft:cmake": { "tabsize": 2 }, "ft:crystal": { "tabsize": 2 }, "ft:css": { "tabsize": 2 }, "ft:cuda": { "tabstospaces": false }, "ft:dart": { "tabsize": 2 }, "ft:ebuild": { "tabstospaces": false }, "ft:elixir": { "tabsize": 2 }, "ft:forth": { "tabstospaces": false }, "ft:gdscript": { "tabstospaces": false }, "ft:gleam": { "tabsize": 2 }, "ft:go": { "tabstospaces": false }, "ft:gomod": { "tabstospaces": false }, "ft:graphql": { "tabsize": 2 }, "ft:haskell": { "tabsize": 2 }, "ft:html": { "tabsize": 2 }, "ft:html5": { "tabsize": 2 }, "ft:jinja2": { "tabsize": 2 }, "ft:json": { "tabsize": 2 }, "ft:jsonnet": { "tabsize": 2 }, "ft:justfile": { "tabstospaces": false }, "ft:lisp": { "tabsize": 2 }, "ft:lua": { "tabsize": 2 }, "ft:makefile": { "tabstospaces": false }, "ft:markdown": { "tabsize": 2 }, "ft:meson": { "tabsize": 2 }, "ft:msbuild": { "tabsize": 2 }, "ft:nim": { "tabsize": 2 }, "ft:nix": { "tabsize": 2 }, "ft:ocaml": { "tabsize": 2 }, "ft:proto": { "tabsize": 2 }, "ft:puppet": { "tabsize": 2 }, "ft:r": { "tabsize": 2 }, "ft:ruby": { "tabsize": 2 }, "ft:scala": { "tabsize": 2 }, "ft:shell": { "tabsize": 4 }, "ft:svelte": { "tabsize": 2 }, "ft:terraform": { "tabsize": 2 }, "ft:tex": { "tabsize": 2 }, "ft:typescript": { "tabsize": 2 }, "ft:vue": { "tabsize": 2 }, "ft:xml": { "tabsize": 2 }, "ft:yaml": { "tabsize": 2 }, "ft:zsh": { "tabsize": 4 }, "helpsplit": "vsplit", "hlsearch": true, "matchbracestyle": "highlight", "mkparents": true, "parsecursor": true, "paste": false, "rmtrailingws": false, "ruler": false, "savecursor": false, "saveundo": false, "scrollbar": true, "scrollbarchar": "│", "scrollspeed": 3, "smartpaste": true, "softwrap": true, "statusformatl": "$(filename) $(modified)$(overwrite) $(status.paste)| ft:$(opt:filetype) | $(opt:fileformat) | $(opt:encoding)", "statusformatr": "$(line):$(col) | $(lines) ", "tabhighlight": false, "tabmovement": true, "tabsize": 4, "tabstospaces": true, "truecolor": "on", "useprimary": true, "wordwrap": true, "xterm": false }My bindings.json
{ "Alt-r": "command:toggle ruler", "Alt-s": "command:setlocal showchars 'tab=›,space=·'", "Alt-Ctrl-s": "command:reset showchars", "Alt-t": "command:togglelocal hltaberrors|command:togglelocal hltrailingws", "Alt-w": "command:toggle softwrap|command:toggle wordwrap", "\u001bк": "command:toggle ruler", "\u001bы": "command:setlocal showchars 'tab=›,space=·'", "\u001b\u0013": "command:reset showchars", "\u001bе": "command:togglelocal hltaberrors|command:togglelocal hltrailingws", "\u001bц": "command:toggle softwrap|command:toggle wordwrap", "Alt-Enter": "CommandMode", "\u001b[27;5;13~": "CommandMode", "\u001b[27;2;13~": "InsertNewline", "F3": "FindNext", "Shift-F3": "FindPrevious", "Alt-Ctrl-Down": "FindNext", "Alt-Ctrl-Up": "FindPrevious", "command": { "Alt-Enter": "AbortCommand", "\u001b[27;5;13~": "AbortCommand", "Ctrl-e": "AbortCommand" } }Description
I've encountered two keybinding bugs while configuring Micro in Foot/Kitty with a Cyrillic keyboard layout. Both issues stem from how Micro parses key events internally versus what the terminal actually sends.
Bug 1: Raw escape sequences are ignored in the command pane
Terminals such as Foot or Kitty send specific raw escape sequences for modified keys. For example,
Ctrl+Entersends\x1b[27;5;13~andShift+Entersends\x1b[27;2;13~.Using the
> rawcommand, I can see Micro receives these sequences correctly in the main buffer. I can bind them inbindings.json:{ "Alt-Enter": "CommandMode", "\u001b[27;5;13~": "CommandMode", "\u001b[27;2;13~": "InsertNewline" }This works perfectly in the main buffer. However, to create a toggle for the command mode, I need to bind the same key to
AbortCommandinside the"command"pane type:{ "command": { "Alt-Enter": "AbortCommand", "\u001b[27;5;13~": "AbortCommand" } }Expected behavior: Pressing
Ctrl+Enterwhile the command bar is open should executeAbortCommandand close the command bar (just likeAlt-Enterdoes when bound this way).Actual behavior: The raw escape sequence binding is completely ignored in the command pane. Pressing the key does nothing. The command pane parser does not support matching raw escape sequences the way the main buffer does.
Bug 2: Alt + Non-Latin keys require manual raw Unicode mappings
When using a non-Latin (Cyrillic ru_RU) keyboard layout, pressing
Alt+ a key sends an escape sequence containing the Unicode character of the Cyrillic letter, not the physical Latin key.For example,
Alt+ron a Cyrillic layout sends\x1bк(because 'к' is on the same physical key as 'r'). Micro does not map this to the logicalAlt-rbinding. To make it work, I have to manually figure out the raw sequence and duplicate everyAltbinding (as seen in mybindings.jsonabove):{ "Alt-r": "command:toggle ruler", "\u001bк": "command:toggle ruler" }Expected behavior: Micro should ideally map keybindings based on the physical key position, or at least provide a mechanism to define layout-agnostic bindings so users don't have to duplicate all
Altbindings with raw Unicode codes.Actual behavior: Users with non-Latin layouts must duplicate all
Altkeybindings using raw\u001b<unicode_char>sequences, making the config bloated and hard to maintain.And a few small requests ...
Feature Request 1: Native
Shift-EntersupportCurrently, to make
Shift+Enterinsert a newline, users of Foot/Kitty have to manually bind the raw escape sequence (\u001b[27;2;13~) toInsertNewline. It would be much more user-friendly if Micro natively supported the logical binding"Shift-Enter": "InsertNewline"out of the box, abstracting away the terminal-specific escape sequences.Feature Request 2: Add a native
CommandModetoggleCurrently,
CommandModeonly opens the command bar. To close it, you need a separate action (AbortCommandorEscape) in the"command"pane.I heavily rely on the command bar for text manipulation using the manipulator-plugin. This plugin provides commands like
> brace,> squote,> dquote,> upper, etc. My workflow constantly involves opening the command bar, typing a case conversion command, and executing it.Having a single
CommandModetoggle action (instead of separate open/close actions) would make this workflow significantly faster and more ergonomic.Feature Request 3: Make
Ctrl-ea toggle by defaultFollowing up on the previous point, since working with plugins like
manipulatorrequires frequent access to the command bar, it makes perfect sense forCtrl-eto act as a toggle by default. Currently, if I pressCtrl-eto open the bar and change my mind, I have to reach forEscto close it. IfCtrl-ewere a toggle (mapped to aToggleCommandModeaction), the workflow would be seamless: pressCtrl-e, typesnake, pressEnter. Or pressCtrl-eagain to cancel.Summary of requested changes:
\u001b[27;5;13~) to work inside the"command"pane type.Altmodifiers for non-Latin keyboard layouts (physical key mapping)."Shift-Enter": "InsertNewline"without requiring raw escape hacks.ToggleCommandModeaction.Ctrl-ebinding fromCommandModetoToggleCommandMode.Thank you for your time and for maintaining the best editor