A practical introduction to SQLcl's KEYMAP command for inspecting, customizing, exporting, and importing editor key bindings.
Meet KEYMAP: A Better Way To Make SQLcl Feel Like Yours
Most of us have a tiny list of terminal habits that we repeat all day.
- Press a key to search backward in history
- Press a key to run the current buffer
- Press a key and expect the cursor to move, complete, delete, or jump
When those habits match your fingers, SQLcl feels fast.
When they do not, every session feels a little bit off.
That is where the new KEYMAP command comes in.
It gives you a clean way to inspect, customize, export, and import SQLcl key bindings without guessing, digging through internals, or restarting your workflow every five minutes.
Why This Command Is Useful
KEYMAP is for people who want SQLcl to behave more like their editor.
Maybe you:
- prefer vi-style editing
- want to bind a shortcut to run the buffer immediately
- need to see what a key is actually doing
- want to share a team keymap
- moved to a new machine and want your setup back in seconds
That is the practical goal of this command: make keyboard behavior visible and customizable.
The Core Commands
Here is the command surface:
KEYMAP list [emacs|vicmd|viins|visual] [-bound|-unbound]* [filter]
KEYMAP bind <mode> (<key>|-detect) <action-id>
KEYMAP unbind <mode> <key>
KEYMAP detect [<key>]
KEYMAP reset [emacs|vicmd|viins|visual|all]
KEYMAP keys <action-id> [mode]
KEYMAP export [<file>]
KEYMAP import <file>
That looks like a lot, but most people will use only a few of them regularly:
listbinddetectkeysexportimport
Start Here: See What SQLcl Is Doing Today
If you want to understand your current session, start with:
keymap list
If you are in vi mode, you can narrow it down:
keymap list viins
keymap list vicmd
This is useful immediately because it answers questions like:
- What does
^Rdo in this mode? - Is
^Oalready bound? - Which actions are available but currently unbound?
You can also search:
keymap list viins history
keymap list -unbound run
That turns the command into a quick discovery tool instead of a giant wall of bindings.
KEYMAP detect
If you have ever wondered:
"What sequence is this key actually sending?"
then this is your command:
keymap detect
SQLcl will prompt you:
Press key sequence to detect...
Then you press the key you care about, and SQLcl tells you what it saw and what that key is currently bound to in each mode.
Example:
Detected key: ^O
emacs: cl-run-immediately
viins: cl-run-immediately
This is especially handy with:
- control keys
- escape-based keys
- terminal arrows
- keys that behave differently than you expected
KEYMAP detect is the bridge between "what I pressed" and "what SQLcl thinks I
pressed."
Rebind Something Useful In Seconds
Let us say you want Ctrl+O to run the current buffer immediately while typing
in vi insert mode.
That is:
keymap bind viins ^O cl-run-immediately
Want to verify it?
keymap keys cl-run-immediately viins
Want to remove it later?
keymap unbind viins ^O
That makes experimentation cheap. You do not have to commit to a setup forever. You can try bindings, keep what works, and remove what does not.
Do Not Forget The Mode
This is the one thing worth remembering:
a binding only applies in the mode where you define it.
That means:
emacsbindings affect emacs editingviinsbindings affect vi insert modevicmdbindings affect vi command modevisualbindings affect visual mode
So if you bind something in emacs but you are actively editing in viins,
the command may succeed and still not affect what your fingers do in that
moment.
That is not a bug. It just means the binding belongs to a different editing mode.
This is why keymap list viins and keymap list vicmd are so helpful. They
show the exact mode you care about.
Team-Friendly Feature: Export And Import
Once you have a setup you like, save it:
keymap export
By default, SQLcl writes:
~/.dbtools/sqlcl/keymap.json
That default location matters for another reason: on startup, SQLcl checks for that file and applies those bindings after loading the built-in defaults. In practice, that means your saved keymap becomes your next-session keymap automatically.
You can also choose your own file:
keymap export ~/team-keymap.json
Later, on the same machine or another one:
keymap import ~/team-keymap.json
This is good for:
- personal backups
- onboarding a team
- trying a shared SQLcl setup
- moving to a new laptop without rebuilding habits from scratch
A Few Nice Everyday Workflows
Here are a few practical patterns.
1. Find What A Key Does
keymap detect
Press the key, then inspect the output.
2. Find Keys For An Action
keymap keys cl-run-immediately
This is great when you know the action name but not the current shortcut.
3. Look For Unused Space
keymap list viins -unbound
This helps you discover available actions that are not mapped yet.
4. Try A Binding Without Fear
keymap bind viins ^O cl-run-immediately
keymap keys cl-run-immediately viins
If you do not like it:
keymap unbind viins ^O
5. Start Over
keymap reset viins
Or reset everything:
keymap reset all
That makes customization safer because "undo the experiment" is built in.
What Makes This Command Nice
The best part of KEYMAP is not that it exists.
It is that it turns key behavior into something you can inspect and control without mystery.
Instead of thinking:
"SQLcl is doing something strange with this key."
you can now think:
"Let me detect it, list it, bind it, test it, and export it."
That is a better workflow.
A Good First Five Minutes
If you want to try the new command without going deep, do this:
keymap list viins
keymap detect
keymap keys cl-run-immediately
keymap bind viins ^O cl-run-immediately
keymap export
That short session will show you:
- what is already bound
- what one key sends
- how to inspect an action
- how to customize a binding
- how to save the result
And after that, SQLcl starts feeling less like a generic terminal tool and more like your terminal tool.
Final Thought
There is a special kind of productivity boost that comes from tools matching your hands.
Not your config file.
Not your memory.
Your hands.
KEYMAP is a small command, but it gives SQLcl one of the most valuable kinds
of customization: the kind you notice every few seconds, all day long.