vim_ahk: Vim key handling in Windows apps that never expected it
Setting file to emulate vim with AutoHotkey
At a glance
- What is it?
- vim_ahk is an MIT licensed AutoHotkey v2 script that adds Vim style normal, insert and visual modes to ordinary Windows applications such as Notepad, Explorer and Word, with IME aware escape handling, a settings GUI and a standalone executable build. It suits a Windows user who wants Vim navigation everywhere without giving up their mouse, and it is a poor fit if you want a real modal editor with buffers, registers and macros.
- Who is it for?
- vim_ahk suits a Windows user who spends the day in Notepad, Explorer, Office and Visual Studio Code and wants h and j and :w without changing any of those applications, especially if you type in Japanese or Chinese where IME conversion complicates the escape key. It does not suit anyone who wants Vim itself, because there is no buffer, no register, no macro system and no command line, only key handling layered over whatever the application already does.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 9 days ago.
- What is it written in?
- Mainly AutoHotkey, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Key handling layered over apps that were not built for it
vim_ahk is a set of AutoHotkey scripts and executable builds for Vim emulation on Windows.
The mechanism is worth understanding before the feature list, because it explains both what the project does well and where its ceiling is. vim.ahk is the main script for AutoHotkey, and vim_ahk.exe is a standalone executable built from that script. The project does not replace your editor or convert the application into a modal one. It intercepts keys, tracks whether you are in normal, insert or visual mode, and translates movements into the keystrokes the target application understands.
That means the behaviour is bounded by what the application accepts. In a rich text control, h and j move the caret rather than select a block, and there is no :w, because the application already has its own save command. What you gain is navigation muscle memory applied consistently across a dozen programs, and what you give up is anything that requires Vim to be in control of the buffer.
The project also solves a problem specific to Windows and to people who type in Japanese or Chinese. The README topics list ime, and a large part of the options table is about how escape and Ctrl-[ behave while an input method editor is converting. On those systems the escape key is frequently consumed by the IME, so a naive key remap leaves you stuck in insert mode, and vim_ahk spends a lot of its option surface on exactly that.
The licence is MIT, the last push to the repository was on 2026-10-14, and the recent release tags are v0.17.2 on 2026-10-14, v0.17.1 on 2026-09-15 and v0.17.0 on 2026-08-25.
Attaching to a window is done by title, class or process
The list of applications vim mode is enabled for is called VimGroup, and by default it covers Notepad, WordPad, TeraPad, Windows Explorer, Thunderbird (only the sending window), PowerPoint, Word, Evernote, Visual Studio Code, TeXworks, TeXstudio, Q-dir, OneNote, and applications running under ahk_exe ApplicationFrameHost.exe.
You can change that list from the tray icon right-click menu, under VimMenu and Settings, or by launching the settings window with Ctrl-Alt-Shift-v.
If you would rather configure it in the script, you set VimGroup before Vim := VimAhk(A_LineFile) in vim.ahk, or before the #Include in your own script. Each entry is a matcher, and the example given is a comma separated list.
VimGroup := "ahk_exe chrome.exe,ahk_exe firefox.exe"Multiple applications are specified as a comma-separated list. One trap is documented explicitly: setting VimGroup this way replaces the default list. To add entries while keeping the defaults, append the default entries after your own, or use the GUI.
Matching is by window title, window class or process name, and the README gives concrete examples beyond the defaults, such as Chrome as ahk_exe chrome.exe, Firefox as ahk_exe firefox.exe, Excel as ahk_exe EXCEL.EXE, and LibreOffice as ahk_exe soffice.bin for all LibreOffice applications.
AutoHotkey Window Spy is the tool for working out which matcher to use, and it shows the window title, the class and the process. That is the answer to most problems with an application that vim_ahk does not attach to.
The title matching is configurable through VimSetTitleMatchMode, whose default is 2, Contain. If you set OneNote, all windows with a title containing OneNote are included, and mode 3 matches only the exact title.
Three ways to install it, and one of them is a warning
There are three installation routes, and the README is explicit about which one applies to which version.
The script route is the simplest. If AutoHotkey is already installed, open vim.ahk with AutoHotkey. This script is for AutoHotkey v2, and users on AutoHotkey v1 are pointed at release v0.13.2 or the ahk_v1 branch instead.
The include route is for people who already run their own AutoHotkey script. Copy vim.ahk and the lib directory under the same parent directory as your script, then add this line to the end of the auto-execute section.
#Include %A_LineFile%\..\vim.ahkThe location of that line matters. It has to come after your own auto-execute code, and the relative path means the lib directory has to sit alongside vim.ahk, since that is where the rest of the implementation lives.
The executable route needs no AutoHotkey at all. vim_ahk.exe runs standalone, and you download the latest zip from the Releases page, extract it, and run it.
There is one important note attached to the executable. The vim_ahk_icons folder has to be placed in the same directory as vim_ahk.exe, otherwise the tray menu icons will not work. That is a small thing, but it is the kind of detail that produces a support question when the tray icon looks wrong.
If you want the same behaviour on macOS, the README points to Karabiner-Elements complex modifications rules by the same author, which is a different tool entirely and a fair alternative to look at if you move between the two operating systems.
Building the executable yourself takes one batch file
If you want to run the latest source rather than a published zip, the build is a single step.
Clone the repository, move to the vim_ahk directory, and run build.bat. You can double-click the file, or run it in PowerShell or Command Prompt.
.\build.batThe result is a vim_ahk folder containing vim_ahk.exe and vim_ahk_icons. The icons folder is not optional decoration, since the executable looks for the tray icons there, as the installation note makes clear.
The repository layout supports a build like this. There is vim.ahk at the root, a lib directory with the implementation, a tests directory, the build.bat file, a pictures directory, the vim_ahk_icons directory, a renovate.json for dependency updates, and a GitHub directory for the workflows.
The presence of a tests directory alongside an AutoHotkey script is worth noting, because scripting languages that intercept every keystroke are exactly the kind of code that breaks quietly. A change to the mode handling can affect every application on the list, and the only way to notice is to have something that exercises the logic without a human pressing keys.
A note on the version cadence, since it affects whether you build from source. The releases go 0.17.0, 0.17.1 and 0.17.2 across August, September and October 2026, and the last push to the repository was on 2026-10-14, the same day as the v0.17.2 tag. The project is moving, so a source build is a reasonable way to stay on the newest behaviour.
Escape key handling is where the IME options live
The options table is the real specification of this project, and the largest cluster of options concerns the escape key.
VimEscNormal, default 1, means pressing ESC enters normal mode. VimEscNormalDirect, default 1, means ESC enters normal mode even while the IME is converting, and if set to 0 ESC behaves as a normal ESC while the IME is converting.
Then there is a parallel set for Ctrl-[, because on a Japanese or Chinese keyboard layout that is the physically available escape key. VimCtrlBracketToEsc makes Ctrl-[ behave as ESC, VimCtrlBracketNormal makes pressing Ctrl-[ enter normal mode, and VimCtrlBracketNormalDirect does the same while the IME is converting. VimSendCtrlBracketNormal controls whether a short Ctrl-[ press sends Ctrl-[ in normal mode, and VimLongCtrlBracketNormal swaps the short and long press behaviour.
The same short and long press distinction exists for ESC itself through VimSendEscNormal and VimLongEscNormal, which is a refinement most people never notice but which makes the key feel right once it is there.
Two more options complete the input side of the story. VimRestoreIME, default 1, saves the IME status in insert mode and restores it when returning to insert mode, which is what stops a Japanese user from having to re-enable the IME after every escape. And VimJJ, default 0, makes jj enter normal mode from insert mode, with VimJJInterval, default 100 milliseconds, setting the maximum interval between the two keys in jj or in a configured two-letter mapping. VimTwoLetter takes that further, letting you set one pair per line, exactly two different letters per pair, for a custom escape sequence.
The other side is the caret. VimChangeCaretWidth, default 0, changes the caret width by mode, thick in normal and visual and thin in insert, which is a small visual cue that many Vim users rely on more than they expect to.
The app list has an allow list and a deny list mode
One option is easy to misread, and it changes who vim mode applies to.
VimAppList is the application list mode, with three values. All enables vim_ahk on all applications and ignores the list. Allow List uses the list as an allow list. Deny List uses the list as a deny list. The default is Allow List.
So by default, vim mode is on only in the applications named in VimGroup, and nothing else. Setting VimAppList to All turns vim mode on everywhere, which is a large behavioural change on a Windows machine, since it affects every focused window, and it is the setting to think about before enabling.
The remaining options are about the mechanism rather than the scope. VimSetTitleMatchMode selects the matching mode, with Start with, Contain, Exact match and Regular expression as the options and Contain, mode 2, as the default. VimSetTitleMatchModeFS trades speed for coverage, with Fast not detecting text for some edit controls and Slow working for all windows but slower. VimIconCheckInterval, default 1000 milliseconds, is how often the status is checked and the tray icon updated, with 0 restoring the original AutoHotkey icon. VimVerbose sets the output level, from no output through a mode only tooltip and a full tooltip to a debug message box that does not auto-close.
VimDisableUnused describes what happens to keys outside insert mode, with three levels: do not disable unused keys, disable alphabets with Shift and symbols, and disable all including modified keys such as Ctrl+Z. Its default is 1.
Every one of these options can also be changed from the settings GUI, which is stated in the README, so nothing here requires editing the script.
Editorial conclusion
vim_ahk suits a Windows user who spends the day in Notepad, Explorer, Office and Visual Studio Code and wants h and j and :w without changing any of those applications, especially if you type in Japanese or Chinese where IME conversion complicates the escape key. It does not suit anyone who wants Vim itself, because there is no buffer, no register, no macro system and no command line, only key handling layered over whatever the application already does. Before you install it, check that your AutoHotkey is version 2, since the v1 script lives on a separate branch and an older release, and decide whether you want the script or the standalone executable, remembering that the executable needs its vim_ahk_icons folder beside it, and note that the last push to the repository was on 2026-10-14.
Frequently asked questions
What is vim_ahk and what does it do?
It is an AutoHotkey v2 script, vim.ahk, that adds Vim style normal, insert and visual mode key handling to ordinary Windows applications, plus a standalone executable build, vim_ahk.exe, that does not need AutoHotkey installed.
How do I add vim_ahk to my own AutoHotkey script?
Copy vim.ahk and the lib directory under the same parent directory as your script, then add #Include %A_LineFile%\..\vim.ahk to the end of the auto-execute section. The relative path is why the lib directory has to sit next to vim.ahk.
Which AutoHotkey version does vim_ahk require?
The current script is for AutoHotkey v2. If you are on AutoHotkey v1, the README directs you to release v0.13.2 or the ahk_v1 branch of the repository.
How do I make vim_ahk work in an application it does not attach to?
Use AutoHotkey Window Spy to inspect the window title, class and process, then add a matcher to VimGroup such as ahk_exe chrome.exe. Setting VimGroup in the script replaces the default list, so append the defaults after your own entries to keep them.
Does vim_ahk handle Japanese and Chinese input methods?
Yes, the options table has separate settings for ESC and Ctrl-[ behaviour while the IME is converting, such as VimEscNormalDirect and VimCtrlBracketNormalDirect, and VimRestoreIME saves and restores the IME status when switching back to insert mode.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/rcmdnk-vim-ahk)Was this useful?