diff --git a/annotation-processors/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider b/annotation-processors/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider
index aa17eb85c..603b85792 100644
--- a/annotation-processors/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider
+++ b/annotation-processors/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider
@@ -1 +1,2 @@
-com.intellij.vim.providers.VimscriptFunctionProcessorProvider
\ No newline at end of file
+com.intellij.vim.providers.VimscriptFunctionProcessorProvider
+com.intellij.vim.providers.ExCommandProcessorProvider
\ No newline at end of file
diff --git a/annotation-processors/src/main/resources/META-INF/services/com.intellij.vim.providers.ExCommandProcessorProvider b/annotation-processors/src/main/resources/META-INF/services/com.intellij.vim.providers.ExCommandProcessorProvider
deleted file mode 100644
index f135dcc9c..000000000
--- a/annotation-processors/src/main/resources/META-INF/services/com.intellij.vim.providers.ExCommandProcessorProvider
+++ /dev/null
@@ -1 +0,0 @@
-com.intellij.vim.providers.ExCommandProcessorProvider
diff --git a/src/main/java/com/maddyhome/idea/vim/vimscript/model/commands/IntellijExCommandProvider.kt b/src/main/java/com/maddyhome/idea/vim/vimscript/model/commands/IntellijExCommandProvider.kt
new file mode 100644
index 000000000..3ab07faaf
--- /dev/null
+++ b/src/main/java/com/maddyhome/idea/vim/vimscript/model/commands/IntellijExCommandProvider.kt
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2003-2023 The IdeaVim authors
+ *
+ * Use of this source code is governed by an MIT-style
+ * license that can be found in the LICENSE.txt file or at
+ * https://opensource.org/licenses/MIT.
+ */
+
+package com.maddyhome.idea.vim.vimscript.model.commands
+
+public object IntellijExCommandProvider : ExCommandProvider {
+  override val exCommandsFileName: String = "intellij_ex_commands.yaml"
+}
\ No newline at end of file
diff --git a/src/main/java/com/maddyhome/idea/vim/vimscript/parser/VimscriptParser.kt b/src/main/java/com/maddyhome/idea/vim/vimscript/parser/VimscriptParser.kt
index ae8140e1d..89d61e68b 100644
--- a/src/main/java/com/maddyhome/idea/vim/vimscript/parser/VimscriptParser.kt
+++ b/src/main/java/com/maddyhome/idea/vim/vimscript/parser/VimscriptParser.kt
@@ -11,6 +11,9 @@ package com.maddyhome.idea.vim.vimscript.parser
 import com.intellij.openapi.diagnostic.logger
 import com.maddyhome.idea.vim.vimscript.model.Script
 import com.maddyhome.idea.vim.vimscript.model.commands.Command
+import com.maddyhome.idea.vim.vimscript.model.commands.EngineExCommandProvider
+import com.maddyhome.idea.vim.vimscript.model.commands.ExCommandTree
+import com.maddyhome.idea.vim.vimscript.model.commands.IntellijExCommandProvider
 import com.maddyhome.idea.vim.vimscript.model.expressions.Expression
 import com.maddyhome.idea.vim.vimscript.parser.errors.IdeavimErrorListener
 import com.maddyhome.idea.vim.vimscript.parser.generated.VimscriptLexer
@@ -30,6 +33,12 @@ internal object VimscriptParser : com.maddyhome.idea.vim.api.VimscriptParser {
   private const val MAX_NUMBER_OF_TRIES = 5
   private var tries = 0
   private var deletionInfo: DeletionInfo = DeletionInfo()
+  override val exCommands = ExCommandTree()
+
+  init {
+    EngineExCommandProvider.getCommands().forEach { exCommands.addCommand(it.key, it.value) }
+    IntellijExCommandProvider.getCommands().forEach { exCommands.addCommand(it.key, it.value) }
+  }
 
   override fun parse(script: String): Script {
     val preprocessedText = uncommentIdeaVimIgnore(getTextWithoutErrors(script))
diff --git a/src/main/java/com/maddyhome/idea/vim/vimscript/parser/visitors/CommandVisitor.kt b/src/main/java/com/maddyhome/idea/vim/vimscript/parser/visitors/CommandVisitor.kt
index 6df85df25..6c6c9d4f2 100644
--- a/src/main/java/com/maddyhome/idea/vim/vimscript/parser/visitors/CommandVisitor.kt
+++ b/src/main/java/com/maddyhome/idea/vim/vimscript/parser/visitors/CommandVisitor.kt
@@ -9,92 +9,26 @@
 package com.maddyhome.idea.vim.vimscript.parser.visitors
 
 import com.intellij.openapi.diagnostic.logger
+import com.maddyhome.idea.vim.api.injector
 import com.maddyhome.idea.vim.common.TextRange
 import com.maddyhome.idea.vim.ex.ExException
 import com.maddyhome.idea.vim.ex.ranges.Range
 import com.maddyhome.idea.vim.ex.ranges.Range.Companion.createRange
 import com.maddyhome.idea.vim.ex.ranges.Ranges
-import com.maddyhome.idea.vim.vimscript.model.commands.ActionCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.ActionListCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.AsciiCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.BufferCloseCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.BufferCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.BufferListCommand
 import com.maddyhome.idea.vim.vimscript.model.commands.CallCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.CmdClearCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.CmdCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.CmdFilterCommand
 import com.maddyhome.idea.vim.vimscript.model.commands.Command
-import com.maddyhome.idea.vim.vimscript.model.commands.CopyTextCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.DelCmdCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.DeleteLinesCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.DeleteMarksCommand
 import com.maddyhome.idea.vim.vimscript.model.commands.DelfunctionCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.DigraphCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.DumpLineCommand
 import com.maddyhome.idea.vim.vimscript.model.commands.EchoCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.EditFileCommand
 import com.maddyhome.idea.vim.vimscript.model.commands.ExecuteCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.ExitCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.FileCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.FindClassCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.FindFileCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.FindSymbolCommand
 import com.maddyhome.idea.vim.vimscript.model.commands.GlobalCommand
 import com.maddyhome.idea.vim.vimscript.model.commands.GoToLineCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.GotoCharacterCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.HelpCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.HistoryCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.JoinLinesCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.JumpsCommand
 import com.maddyhome.idea.vim.vimscript.model.commands.LetCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.LockVarCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.MarkCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.MarksCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.MoveTextCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.NextFileCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.NextTabCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.NoHLSearchCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.NormalCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.OnlyCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.PackaddCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.PlugCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.PreviousFileCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.PreviousTabCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.PrintCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.PromptFindCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.PromptReplaceCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.PutLinesCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.QuitCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.RedoCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.RegistersCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.RepeatCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.SelectFileCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.SelectFirstFileCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.SelectLastFileCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.SetCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.SetHandlerCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.SetLocalCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.ShellCommand
 import com.maddyhome.idea.vim.vimscript.model.commands.ShiftLeftCommand
 import com.maddyhome.idea.vim.vimscript.model.commands.ShiftRightCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.SortCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.SourceCommand
 import com.maddyhome.idea.vim.vimscript.model.commands.SplitCommand
 import com.maddyhome.idea.vim.vimscript.model.commands.SplitType
 import com.maddyhome.idea.vim.vimscript.model.commands.SubstituteCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.TabCloseCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.TabMoveCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.TabOnlyCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.UndoCommand
 import com.maddyhome.idea.vim.vimscript.model.commands.UnknownCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.UnlockVarCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.WriteAllCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.WriteCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.WriteNextFileCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.WritePreviousFileCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.WriteQuitCommand
-import com.maddyhome.idea.vim.vimscript.model.commands.YankLinesCommand
 import com.maddyhome.idea.vim.vimscript.model.commands.mapping.MapClearCommand
 import com.maddyhome.idea.vim.vimscript.model.commands.mapping.MapCommand
 import com.maddyhome.idea.vim.vimscript.model.commands.mapping.UnMapCommand
@@ -338,536 +272,7 @@ internal object CommandVisitor : VimscriptBaseVisitor<Command>() {
     return TextRange(startOffset, endOffset)
   }
 
-  // todo I am ashamed of that
-  private val commands = mutableMapOf(
-    "delf" to DelfunctionCommand::class,
-    "delfu" to DelfunctionCommand::class,
-    "delfun" to DelfunctionCommand::class,
-    "delfunc" to DelfunctionCommand::class,
-    "delfunct" to DelfunctionCommand::class,
-    "delfuncti" to DelfunctionCommand::class,
-    "delfunctio" to DelfunctionCommand::class,
-    "delfunction" to DelfunctionCommand::class,
-    "action" to ActionCommand::class,
-    "actionlist" to ActionListCommand::class,
-    "as" to AsciiCommand::class,
-    "asc" to AsciiCommand::class,
-    "asci" to AsciiCommand::class,
-    "ascii" to AsciiCommand::class,
-    "b" to BufferCommand::class,
-    "bu" to BufferCommand::class,
-    "buf" to BufferCommand::class,
-    "buff" to BufferCommand::class,
-    "buffe" to BufferCommand::class,
-    "buffer" to BufferCommand::class,
-    "bd" to BufferCloseCommand::class,
-    "bde" to BufferCloseCommand::class,
-    "bdel" to BufferCloseCommand::class,
-    "bdele" to BufferCloseCommand::class,
-    "bdelet" to BufferCloseCommand::class,
-    "bdelete" to BufferCloseCommand::class,
-    "ls" to BufferListCommand::class,
-    "files" to BufferListCommand::class,
-    "buffers" to BufferListCommand::class,
-    "cal" to CallCommand::class,
-    "call" to CallCommand::class,
-    "cla" to FindClassCommand::class,
-    "clas" to FindClassCommand::class,
-    "class" to FindClassCommand::class,
-    "com" to CmdCommand::class,
-    "comm" to CmdCommand::class,
-    "comma" to CmdCommand::class,
-    "comman" to CmdCommand::class,
-    "command" to CmdCommand::class,
-    "!" to CmdFilterCommand::class,
-    "comc" to CmdClearCommand::class,
-    "comcl" to CmdClearCommand::class,
-    "comcle" to CmdClearCommand::class,
-    "comclea" to CmdClearCommand::class,
-    "comclear" to CmdClearCommand::class,
-    "t" to CopyTextCommand::class,
-    "co" to CopyTextCommand::class,
-    "cop" to CopyTextCommand::class,
-    "copy" to CopyTextCommand::class,
-    "delc" to DelCmdCommand::class,
-    "delco" to DelCmdCommand::class,
-    "delcom" to DelCmdCommand::class,
-    "delcomm" to DelCmdCommand::class,
-    "delcomma" to DelCmdCommand::class,
-    "delcomman" to DelCmdCommand::class,
-    "delcommand" to DelCmdCommand::class,
-    "d" to DeleteLinesCommand::class,
-    "de" to DeleteLinesCommand::class,
-    "del" to DeleteLinesCommand::class,
-    "dele" to DeleteLinesCommand::class,
-    "delet" to DeleteLinesCommand::class,
-    "delete" to DeleteLinesCommand::class,
-    "delm" to DeleteMarksCommand::class,
-    "delma" to DeleteMarksCommand::class,
-    "delmar" to DeleteMarksCommand::class,
-    "delmark" to DeleteMarksCommand::class,
-    "delmarks" to DeleteMarksCommand::class,
-    "dig" to DigraphCommand::class,
-    "digr" to DigraphCommand::class,
-    "digra" to DigraphCommand::class,
-    "digrap" to DigraphCommand::class,
-    "digraph" to DigraphCommand::class,
-    "digraphs" to DigraphCommand::class,
-    "dump" to DumpLineCommand::class,
-    "dumpl" to DumpLineCommand::class,
-    "dumpli" to DumpLineCommand::class,
-    "dumplin" to DumpLineCommand::class,
-    "dumpline" to DumpLineCommand::class,
-    "ec" to EchoCommand::class,
-    "ech" to EchoCommand::class,
-    "echo" to EchoCommand::class,
-    "e" to EditFileCommand::class,
-    "ed" to EditFileCommand::class,
-    "edi" to EditFileCommand::class,
-    "edit" to EditFileCommand::class,
-    "bro" to EditFileCommand::class,
-    "brow" to EditFileCommand::class,
-    "brows" to EditFileCommand::class,
-    "browse" to EditFileCommand::class,
-    "wqa" to ExitCommand::class,
-    "wqal" to ExitCommand::class,
-    "wqall" to ExitCommand::class,
-    "qa" to ExitCommand::class,
-    "qal" to ExitCommand::class,
-    "qall" to ExitCommand::class,
-    "xa" to ExitCommand::class,
-    "xal" to ExitCommand::class,
-    "xall" to ExitCommand::class,
-    "quita" to ExitCommand::class,
-    "quital" to ExitCommand::class,
-    "quitall" to ExitCommand::class,
-    "f" to FileCommand::class,
-    "fi" to FileCommand::class,
-    "fil" to FileCommand::class,
-    "file" to FileCommand::class,
-    "fin" to FindFileCommand::class,
-    "find" to FindFileCommand::class,
-    "sym" to FindSymbolCommand::class,
-    "symb" to FindSymbolCommand::class,
-    "symbo" to FindSymbolCommand::class,
-    "symbol" to FindSymbolCommand::class,
-    "g" to GlobalCommand::class,
-    "gl" to GlobalCommand::class,
-    "glo" to GlobalCommand::class,
-    "glob" to GlobalCommand::class,
-    "globa" to GlobalCommand::class,
-    "global" to GlobalCommand::class,
-    "v" to GlobalCommand::class,
-    "vg" to GlobalCommand::class,
-    "vgl" to GlobalCommand::class,
-    "vglo" to GlobalCommand::class,
-    "vglob" to GlobalCommand::class,
-    "vgloba" to GlobalCommand::class,
-    "vglobal" to GlobalCommand::class,
-    "go" to GotoCharacterCommand::class,
-    "got" to GotoCharacterCommand::class,
-    "goto" to GotoCharacterCommand::class,
-    "h" to HelpCommand::class,
-    "he" to HelpCommand::class,
-    "hel" to HelpCommand::class,
-    "help" to HelpCommand::class,
-    "his" to HistoryCommand::class,
-    "hist" to HistoryCommand::class,
-    "histo" to HistoryCommand::class,
-    "histor" to HistoryCommand::class,
-    "history" to HistoryCommand::class,
-    "j" to JoinLinesCommand::class,
-    "jo" to JoinLinesCommand::class,
-    "joi" to JoinLinesCommand::class,
-    "join" to JoinLinesCommand::class,
-    "ju" to JumpsCommand::class,
-    "jum" to JumpsCommand::class,
-    "jump" to JumpsCommand::class,
-    "jumps" to JumpsCommand::class,
-    "let" to LetCommand::class,
-    "k" to MarkCommand::class,
-    "ma" to MarkCommand::class,
-    "mar" to MarkCommand::class,
-    "mark" to MarkCommand::class,
-    "marks" to MarksCommand::class,
-    "m" to MoveTextCommand::class,
-    "mo" to MoveTextCommand::class,
-    "mov" to MoveTextCommand::class,
-    "move" to MoveTextCommand::class,
-    "n" to NextFileCommand::class,
-    "ne" to NextFileCommand::class,
-    "nex" to NextFileCommand::class,
-    "next" to NextFileCommand::class,
-    "bn" to NextFileCommand::class,
-    "bne" to NextFileCommand::class,
-    "bnex" to NextFileCommand::class,
-    "bnext" to NextFileCommand::class,
-    "tabn" to NextTabCommand::class,
-    "tabne" to NextTabCommand::class,
-    "tabnex" to NextTabCommand::class,
-    "tabnext" to NextTabCommand::class,
-    "noh" to NoHLSearchCommand::class,
-    "nohl" to NoHLSearchCommand::class,
-    "nohls" to NoHLSearchCommand::class,
-    "nohlse" to NoHLSearchCommand::class,
-    "nohlsea" to NoHLSearchCommand::class,
-    "nohlsear" to NoHLSearchCommand::class,
-    "nohlsearc" to NoHLSearchCommand::class,
-    "nohlsearch" to NoHLSearchCommand::class,
-    "norm" to NormalCommand::class,
-    "norma" to NormalCommand::class,
-    "normal" to NormalCommand::class,
-    "on" to OnlyCommand::class,
-    "onl" to OnlyCommand::class,
-    "only" to OnlyCommand::class,
-    "pa" to PackaddCommand::class,
-    "pac" to PackaddCommand::class,
-    "pack" to PackaddCommand::class,
-    "packa" to PackaddCommand::class,
-    "packad" to PackaddCommand::class,
-    "packadd" to PackaddCommand::class,
-    "Plug" to PlugCommand::class,
-    "Plugi" to PlugCommand::class,
-    "Plugin" to PlugCommand::class,
-    "N" to PreviousFileCommand::class,
-    "Ne" to PreviousFileCommand::class,
-    "Nex" to PreviousFileCommand::class,
-    "Next" to PreviousFileCommand::class,
-    "prev" to PreviousFileCommand::class,
-    "previ" to PreviousFileCommand::class,
-    "previo" to PreviousFileCommand::class,
-    "previou" to PreviousFileCommand::class,
-    "previous" to PreviousFileCommand::class,
-    "bp" to PreviousFileCommand::class,
-    "bpr" to PreviousFileCommand::class,
-    "bpre" to PreviousFileCommand::class,
-    "bprev" to PreviousFileCommand::class,
-    "bprevi" to PreviousFileCommand::class,
-    "bprevio" to PreviousFileCommand::class,
-    "bpreviou" to PreviousFileCommand::class,
-    "bprevious" to PreviousFileCommand::class,
-    "tabp" to PreviousTabCommand::class,
-    "tabpr" to PreviousTabCommand::class,
-    "tabpre" to PreviousTabCommand::class,
-    "tabprev" to PreviousTabCommand::class,
-    "tabprevi" to PreviousTabCommand::class,
-    "tabprevio" to PreviousTabCommand::class,
-    "tabpreviou" to PreviousTabCommand::class,
-    "tabprevious" to PreviousTabCommand::class,
-    "tabN" to PreviousTabCommand::class,
-    "tabNe" to PreviousTabCommand::class,
-    "tabNex" to PreviousTabCommand::class,
-    "tabNext" to PreviousTabCommand::class,
-    "p" to PrintCommand::class,
-    "pr" to PrintCommand::class,
-    "pri" to PrintCommand::class,
-    "prin" to PrintCommand::class,
-    "print" to PrintCommand::class,
-    "P" to PrintCommand::class,
-    "Pr" to PrintCommand::class,
-    "Pri" to PrintCommand::class,
-    "Prin" to PrintCommand::class,
-    "Print" to PrintCommand::class,
-    "pro" to PromptFindCommand::class,
-    "prom" to PromptFindCommand::class,
-    "promp" to PromptFindCommand::class,
-    "prompt" to PromptFindCommand::class,
-    "promptf" to PromptFindCommand::class,
-    "promptfi" to PromptFindCommand::class,
-    "promptfin" to PromptFindCommand::class,
-    "promptfind" to PromptFindCommand::class,
-    "promptr" to PromptReplaceCommand::class,
-    "promptre" to PromptReplaceCommand::class,
-    "promptrep" to PromptReplaceCommand::class,
-    "promptrepl" to PromptReplaceCommand::class,
-    "promptrepla" to PromptReplaceCommand::class,
-    "promptreplac" to PromptReplaceCommand::class,
-    "promptreplace" to PromptReplaceCommand::class,
-    "pu" to PutLinesCommand::class,
-    "put" to PutLinesCommand::class,
-    "q" to QuitCommand::class,
-    "qu" to QuitCommand::class,
-    "qui" to QuitCommand::class,
-    "quit" to QuitCommand::class,
-    "clo" to QuitCommand::class,
-    "clos" to QuitCommand::class,
-    "close" to QuitCommand::class,
-    "hid" to QuitCommand::class,
-    "hide" to QuitCommand::class,
-    "red" to RedoCommand::class,
-    "redo" to RedoCommand::class,
-    "di" to RegistersCommand::class,
-    "dis" to RegistersCommand::class,
-    "disp" to RegistersCommand::class,
-    "displ" to RegistersCommand::class,
-    "displa" to RegistersCommand::class,
-    "display" to RegistersCommand::class,
-    "exe" to ExecuteCommand::class,
-    "exec" to ExecuteCommand::class,
-    "execu" to ExecuteCommand::class,
-    "execut" to ExecuteCommand::class,
-    "execute" to ExecuteCommand::class,
-    "reg" to RegistersCommand::class,
-    "regi" to RegistersCommand::class,
-    "regis" to RegistersCommand::class,
-    "regist" to RegistersCommand::class,
-    "registe" to RegistersCommand::class,
-    "register" to RegistersCommand::class,
-    "registers" to RegistersCommand::class,
-    "@" to RepeatCommand::class,
-    "argu" to SelectFileCommand::class,
-    "argum" to SelectFileCommand::class,
-    "argume" to SelectFileCommand::class,
-    "argumen" to SelectFileCommand::class,
-    "argument" to SelectFileCommand::class,
-    "fir" to SelectFirstFileCommand::class,
-    "firs" to SelectFirstFileCommand::class,
-    "first" to SelectFirstFileCommand::class,
-    "la" to SelectLastFileCommand::class,
-    "las" to SelectLastFileCommand::class,
-    "last" to SelectLastFileCommand::class,
-    "se" to SetCommand::class,
-    "set" to SetCommand::class,
-    "setl" to SetLocalCommand::class,
-    "setlo" to SetLocalCommand::class,
-    "setloc" to SetLocalCommand::class,
-    "setloca" to SetLocalCommand::class,
-    "setlocal" to SetLocalCommand::class,
-    "sethandler" to SetHandlerCommand::class,
-    "sh" to ShellCommand::class,
-    "she" to ShellCommand::class,
-    "shel" to ShellCommand::class,
-    "shell" to ShellCommand::class,
-    "sor" to SortCommand::class,
-    "sort" to SortCommand::class,
-    "sp" to SplitCommand::class,
-    "spl" to SplitCommand::class,
-    "spli" to SplitCommand::class,
-    "split" to SplitCommand::class,
-    "vs" to SplitCommand::class,
-    "vsp" to SplitCommand::class,
-    "vspl" to SplitCommand::class,
-    "vspli" to SplitCommand::class,
-    "vsplit" to SplitCommand::class,
-    "so" to SourceCommand::class,
-    "sou" to SourceCommand::class,
-    "sour" to SourceCommand::class,
-    "sourc" to SourceCommand::class,
-    "source" to SourceCommand::class,
-    "~" to SubstituteCommand::class,
-    "&" to SubstituteCommand::class,
-    "s" to SubstituteCommand::class,
-    "su" to SubstituteCommand::class,
-    "sub" to SubstituteCommand::class,
-    "subs" to SubstituteCommand::class,
-    "subst" to SubstituteCommand::class,
-    "substi" to SubstituteCommand::class,
-    "substit" to SubstituteCommand::class,
-    "substitu" to SubstituteCommand::class,
-    "substitut" to SubstituteCommand::class,
-    "substitute" to SubstituteCommand::class,
-    "tabc" to TabCloseCommand::class,
-    "tabcl" to TabCloseCommand::class,
-    "tabclo" to TabCloseCommand::class,
-    "tabclos" to TabCloseCommand::class,
-    "tabclose" to TabCloseCommand::class,
-    "tabm" to TabMoveCommand::class,
-    "tabmo" to TabMoveCommand::class,
-    "tabmov" to TabMoveCommand::class,
-    "tabmove" to TabMoveCommand::class,
-    "tabo" to TabOnlyCommand::class,
-    "tabon" to TabOnlyCommand::class,
-    "tabonl" to TabOnlyCommand::class,
-    "tabonly" to TabOnlyCommand::class,
-    "u" to UndoCommand::class,
-    "un" to UndoCommand::class,
-    "und" to UndoCommand::class,
-    "undo" to UndoCommand::class,
-    "wa" to WriteAllCommand::class,
-    "wal" to WriteAllCommand::class,
-    "wall" to WriteAllCommand::class,
-    "w" to WriteCommand::class,
-    "wr" to WriteCommand::class,
-    "wri" to WriteCommand::class,
-    "writ" to WriteCommand::class,
-    "write" to WriteCommand::class,
-    "wn" to WriteNextFileCommand::class,
-    "wne" to WriteNextFileCommand::class,
-    "wnex" to WriteNextFileCommand::class,
-    "wnext" to WriteNextFileCommand::class,
-    "wN" to WritePreviousFileCommand::class,
-    "wNe" to WritePreviousFileCommand::class,
-    "wNex" to WritePreviousFileCommand::class,
-    "wNext" to WritePreviousFileCommand::class,
-    "wp" to WritePreviousFileCommand::class,
-    "wpr" to WritePreviousFileCommand::class,
-    "wpre" to WritePreviousFileCommand::class,
-    "wprev" to WritePreviousFileCommand::class,
-    "wprevi" to WritePreviousFileCommand::class,
-    "wprevio" to WritePreviousFileCommand::class,
-    "wpreviou" to WritePreviousFileCommand::class,
-    "wprevious" to WritePreviousFileCommand::class,
-    "wq" to WriteQuitCommand::class,
-    "x" to WriteQuitCommand::class,
-    "xi" to WriteQuitCommand::class,
-    "xit" to WriteQuitCommand::class,
-    "exi" to WriteQuitCommand::class,
-    "exit" to WriteQuitCommand::class,
-    "y" to YankLinesCommand::class,
-    "ya" to YankLinesCommand::class,
-    "yan" to YankLinesCommand::class,
-    "yank" to YankLinesCommand::class,
-    "map" to MapCommand::class,
-    "nm" to MapCommand::class,
-    "vm" to MapCommand::class,
-    "xm" to MapCommand::class,
-    "om" to MapCommand::class,
-    "im" to MapCommand::class,
-    "cm" to MapCommand::class,
-    "nma" to MapCommand::class,
-    "vma" to MapCommand::class,
-    "xma" to MapCommand::class,
-    "oma" to MapCommand::class,
-    "ima" to MapCommand::class,
-    "cma" to MapCommand::class,
-    "nmap" to MapCommand::class,
-    "vmap" to MapCommand::class,
-    "xmap" to MapCommand::class,
-    "omap" to MapCommand::class,
-    "imap" to MapCommand::class,
-    "cmap" to MapCommand::class,
-    "no" to MapCommand::class,
-    "nn" to MapCommand::class,
-    "vn" to MapCommand::class,
-    "xn" to MapCommand::class,
-    "ono" to MapCommand::class,
-    "ino" to MapCommand::class,
-    "cno" to MapCommand::class,
-    "nno" to MapCommand::class,
-    "vno" to MapCommand::class,
-    "xno" to MapCommand::class,
-    "nor" to MapCommand::class,
-    "nnor" to MapCommand::class,
-    "vnor" to MapCommand::class,
-    "xnor" to MapCommand::class,
-    "onor" to MapCommand::class,
-    "inor" to MapCommand::class,
-    "cnor" to MapCommand::class,
-    "nore" to MapCommand::class,
-    "nnore" to MapCommand::class,
-    "vnore" to MapCommand::class,
-    "xnore" to MapCommand::class,
-    "onore" to MapCommand::class,
-    "inore" to MapCommand::class,
-    "cnore" to MapCommand::class,
-    "norem" to MapCommand::class,
-    "nnorem" to MapCommand::class,
-    "vnorem" to MapCommand::class,
-    "xnorem" to MapCommand::class,
-    "onorem" to MapCommand::class,
-    "inorem" to MapCommand::class,
-    "cnorem" to MapCommand::class,
-    "norema" to MapCommand::class,
-    "nnorema" to MapCommand::class,
-    "vnorema" to MapCommand::class,
-    "xnorema" to MapCommand::class,
-    "onorema" to MapCommand::class,
-    "inorema" to MapCommand::class,
-    "cnorema" to MapCommand::class,
-    "noremap" to MapCommand::class,
-    "nnoremap" to MapCommand::class,
-    "vnoremap" to MapCommand::class,
-    "xnoremap" to MapCommand::class,
-    "onoremap" to MapCommand::class,
-    "inoremap" to MapCommand::class,
-    "cnoremap" to MapCommand::class,
-    "mapc" to MapClearCommand::class,
-    "nmapc" to MapClearCommand::class,
-    "vmapc" to MapClearCommand::class,
-    "xmapc" to MapClearCommand::class,
-    "smapc" to MapClearCommand::class,
-    "omapc" to MapClearCommand::class,
-    "imapc" to MapClearCommand::class,
-    "cmapc" to MapClearCommand::class,
-    "mapcl" to MapClearCommand::class,
-    "nmapcl" to MapClearCommand::class,
-    "vmapcl" to MapClearCommand::class,
-    "xmapcl" to MapClearCommand::class,
-    "smapcl" to MapClearCommand::class,
-    "omapcl" to MapClearCommand::class,
-    "imapcl" to MapClearCommand::class,
-    "cmapcl" to MapClearCommand::class,
-    "mapcle" to MapClearCommand::class,
-    "nmapcle" to MapClearCommand::class,
-    "vmapcle" to MapClearCommand::class,
-    "xmapcle" to MapClearCommand::class,
-    "smapcle" to MapClearCommand::class,
-    "omapcle" to MapClearCommand::class,
-    "imapcle" to MapClearCommand::class,
-    "cmapcle" to MapClearCommand::class,
-    "mapclea" to MapClearCommand::class,
-    "nmapclea" to MapClearCommand::class,
-    "vmapclea" to MapClearCommand::class,
-    "xmapclea" to MapClearCommand::class,
-    "smapclea" to MapClearCommand::class,
-    "omapclea" to MapClearCommand::class,
-    "imapclea" to MapClearCommand::class,
-    "cmapclea" to MapClearCommand::class,
-    "mapclear" to MapClearCommand::class,
-    "nmapclear" to MapClearCommand::class,
-    "vmapclear" to MapClearCommand::class,
-    "xmapclear" to MapClearCommand::class,
-    "smapclear" to MapClearCommand::class,
-    "omapclear" to MapClearCommand::class,
-    "imapclear" to MapClearCommand::class,
-    "cmapclear" to MapClearCommand::class,
-    "vu" to UnMapCommand::class,
-    "xu" to UnMapCommand::class,
-    "ou" to UnMapCommand::class,
-    "iu" to UnMapCommand::class,
-    "cu" to UnMapCommand::class,
-    "nun" to UnMapCommand::class,
-    "vun" to UnMapCommand::class,
-    "xun" to UnMapCommand::class,
-    "oun" to UnMapCommand::class,
-    "iun" to UnMapCommand::class,
-    "cun" to UnMapCommand::class,
-    "unm" to UnMapCommand::class,
-    "nunm" to UnMapCommand::class,
-    "vunm" to UnMapCommand::class,
-    "xunm" to UnMapCommand::class,
-    "sunm" to UnMapCommand::class,
-    "ounm" to UnMapCommand::class,
-    "iunm" to UnMapCommand::class,
-    "cunm" to UnMapCommand::class,
-    "unma" to UnMapCommand::class,
-    "nunma" to UnMapCommand::class,
-    "vunma" to UnMapCommand::class,
-    "xunma" to UnMapCommand::class,
-    "sunma" to UnMapCommand::class,
-    "ounma" to UnMapCommand::class,
-    "iunma" to UnMapCommand::class,
-    "cunma" to UnMapCommand::class,
-    "unmap" to UnMapCommand::class,
-    "nunmap" to UnMapCommand::class,
-    "vunmap" to UnMapCommand::class,
-    "xunmap" to UnMapCommand::class,
-    "sunmap" to UnMapCommand::class,
-    "ounmap" to UnMapCommand::class,
-    "iunmap" to UnMapCommand::class,
-    "cunmap" to UnMapCommand::class,
-    "lockv" to LockVarCommand::class,
-    "lockva" to LockVarCommand::class,
-    "lockvar" to LockVarCommand::class,
-    "unlo" to UnlockVarCommand::class,
-    "unloc" to UnlockVarCommand::class,
-    "unlock" to UnlockVarCommand::class,
-    "unlockv" to UnlockVarCommand::class,
-    "unlockva" to UnlockVarCommand::class,
-    "unlockvar" to UnlockVarCommand::class,
-  )
-
   private fun getCommandByName(commandName: String): KClass<out Command> {
-    return commands[commandName]!!
+    return injector.vimscriptParser.exCommands.getCommand(commandName)?.getKClass() ?: UnknownCommand::class
   }
 }
diff --git a/src/main/resources/intellij_ex_commands.yaml b/src/main/resources/intellij_ex_commands.yaml
new file mode 100644
index 000000000..8ba709bd7
--- /dev/null
+++ b/src/main/resources/intellij_ex_commands.yaml
@@ -0,0 +1,9 @@
+# This file was automatically generated by [com.intellij.vim.processor.EXCommandProcessor].
+# If you are going to change it, you are probably doing something wrong, as your changes will be overridden by the next `gradle kspKotlin` run.
+
+actionl[ist]: com.maddyhome.idea.vim.vimscript.model.commands.ActionListCommand
+b[uffer]: com.maddyhome.idea.vim.vimscript.model.commands.BufferCommand
+ls,files,buffers: com.maddyhome.idea.vim.vimscript.model.commands.BufferListCommand
+'!': com.maddyhome.idea.vim.vimscript.model.commands.CmdFilterCommand
+g[lobal],vg[lobal]: com.maddyhome.idea.vim.vimscript.model.commands.GlobalCommand
+h[elp]: com.maddyhome.idea.vim.vimscript.model.commands.HelpCommand
diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimscriptParser.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimscriptParser.kt
index aa3f3bb2b..e32a3b63e 100644
--- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimscriptParser.kt
+++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimscriptParser.kt
@@ -10,9 +10,11 @@ package com.maddyhome.idea.vim.api
 
 import com.maddyhome.idea.vim.vimscript.model.Script
 import com.maddyhome.idea.vim.vimscript.model.commands.Command
+import com.maddyhome.idea.vim.vimscript.model.commands.ExCommandTree
 import com.maddyhome.idea.vim.vimscript.model.expressions.Expression
 
 public interface VimscriptParser {
+  public val exCommands: ExCommandTree
 
   public fun parse(script: String): Script
   public fun parseCommand(command: String): Command?
diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/helper/EngineStringHelper.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/helper/EngineStringHelper.kt
index 1b193e538..00656ab7f 100644
--- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/helper/EngineStringHelper.kt
+++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/helper/EngineStringHelper.kt
@@ -67,12 +67,12 @@ public fun String.removeAsciiColorCodes(): String {
   return this.replace("\u001B\\[[;\\d]*m".toRegex(), "")
 }
 
-internal fun String.indexOfOrNull(char: Char, startIndex: Int): Int? {
+internal fun String.indexOfOrNull(char: Char, startIndex: Int = 0): Int? {
   val index = this.indexOf(char, startIndex)
   return if (index < 0) null else index
 }
 
-internal fun String.lastIndexOfOrNull(char: Char, startIndex: Int, endIndex: Int): Int? {
+internal fun String.lastIndexOfOrNull(char: Char, startIndex: Int = 0, endIndex: Int = length): Int? {
   if (startIndex < 0 || endIndex > this.length) return null
   var i = endIndex - 1
   while (i >= startIndex) {
diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/commands/EngineExCommandProvider.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/commands/EngineExCommandProvider.kt
new file mode 100644
index 000000000..fb08521f9
--- /dev/null
+++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/commands/EngineExCommandProvider.kt
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2003-2023 The IdeaVim authors
+ *
+ * Use of this source code is governed by an MIT-style
+ * license that can be found in the LICENSE.txt file or at
+ * https://opensource.org/licenses/MIT.
+ */
+
+package com.maddyhome.idea.vim.vimscript.model.commands
+
+public object EngineExCommandProvider : ExCommandProvider {
+  override val exCommandsFileName: String = "engine_ex_commands.yaml"
+}
\ No newline at end of file
diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/commands/ExCommandProvider.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/commands/ExCommandProvider.kt
new file mode 100644
index 000000000..8e9d4f4d2
--- /dev/null
+++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/commands/ExCommandProvider.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2003-2023 The IdeaVim authors
+ *
+ * Use of this source code is governed by an MIT-style
+ * license that can be found in the LICENSE.txt file or at
+ * https://opensource.org/licenses/MIT.
+ */
+
+package com.maddyhome.idea.vim.vimscript.model.commands
+
+import org.yaml.snakeyaml.Yaml
+import java.io.InputStream
+
+public interface ExCommandProvider {
+  public val exCommandsFileName: String
+
+  public fun getCommands(): Map<String, LazyExCommandInstance> {
+    val yaml = Yaml()
+    val classLoader = this.javaClass.classLoader
+    val commandToClass: Map<String, String> = yaml.load(getFile())
+    return commandToClass.entries.associate { it.key to LazyExCommandInstance(it.value, classLoader) }
+  }
+
+  private fun getFile(): InputStream {
+    return object {}.javaClass.classLoader.getResourceAsStream(exCommandsFileName)
+      ?: throw RuntimeException("Failed to fetch ex-commands for ${javaClass.name}")
+  }
+}
\ No newline at end of file
diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/commands/ExCommandTree.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/commands/ExCommandTree.kt
new file mode 100644
index 000000000..b32a554ce
--- /dev/null
+++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/commands/ExCommandTree.kt
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2003-2023 The IdeaVim authors
+ *
+ * Use of this source code is governed by an MIT-style
+ * license that can be found in the LICENSE.txt file or at
+ * https://opensource.org/licenses/MIT.
+ */
+
+package com.maddyhome.idea.vim.vimscript.model.commands
+
+import com.intellij.vim.model.LazyInstance
+import com.maddyhome.idea.vim.helper.indexOfOrNull
+import com.maddyhome.idea.vim.helper.lastIndexOfOrNull
+
+// TODO do we really need a tree structure here?
+public class ExCommandTree {
+  private val abbrevToCommand = mutableMapOf<String, String>()
+  private val commandToInstance = mutableMapOf<String, LazyExCommandInstance>()
+
+  public fun addCommand(commandsPattern: String, lazyInstance: LazyExCommandInstance) {
+    val subCommands = parseCommandPattern(commandsPattern)
+    for ((requiredPart, optionalPart) in subCommands) {
+      val fullCommand = requiredPart + optionalPart
+      commandToInstance[fullCommand] = lazyInstance
+
+      for (i in (0 .. optionalPart.length)) {
+        abbrevToCommand[requiredPart + optionalPart.substring(0, i)] = fullCommand
+      }
+    }
+  }
+
+  public fun getCommand(command: String): LazyExCommandInstance? {
+    return abbrevToCommand[command]?.let { commandToInstance[it] }
+  }
+
+  private fun parseCommandPattern(commandsPattern: String): List<Pair<String, String>> {
+    val result = mutableListOf<Pair<String, String>>()
+    val commands = commandsPattern.split(",")
+    for (command in commands) {
+      val leftBraceIndex = command.indexOfOrNull('[')
+      val rightBraceIndex = command.indexOfOrNull(']')
+      if (
+        (leftBraceIndex == null && rightBraceIndex != null) ||
+        (leftBraceIndex != null && rightBraceIndex == null) ||
+        (leftBraceIndex != null && rightBraceIndex != null && leftBraceIndex > rightBraceIndex) ||
+        (leftBraceIndex != null && leftBraceIndex != command.lastIndexOfOrNull('[')) ||
+        (rightBraceIndex != null && rightBraceIndex != command.lastIndexOfOrNull(']'))
+      ) {
+        throw RuntimeException("Invalid ex-command pattern $commandsPattern")
+      }
+      val primaryPart = command.substring(0, leftBraceIndex ?: command.length)
+      val optionalPart = if (leftBraceIndex != null && rightBraceIndex != null) command.substring(leftBraceIndex + 1, rightBraceIndex) else ""
+      result.add(Pair(primaryPart, optionalPart))
+    }
+    return result
+  }
+}
\ No newline at end of file
diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/commands/LazyExCommandInstance.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/commands/LazyExCommandInstance.kt
new file mode 100644
index 000000000..1acf4251d
--- /dev/null
+++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/commands/LazyExCommandInstance.kt
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2003-2023 The IdeaVim authors
+ *
+ * Use of this source code is governed by an MIT-style
+ * license that can be found in the LICENSE.txt file or at
+ * https://opensource.org/licenses/MIT.
+ */
+
+package com.maddyhome.idea.vim.vimscript.model.commands
+
+import kotlin.reflect.KClass
+
+public class LazyExCommandInstance(private val className: String, private val classLoader: ClassLoader) {
+  public fun getKClass(): KClass<out Command> {
+    @Suppress("UNCHECKED_CAST")
+    return classLoader.loadClass(className).kotlin as KClass<out Command>
+  }
+}
\ No newline at end of file
diff --git a/vim-engine/src/main/resources/engine_ex_commands.yaml b/vim-engine/src/main/resources/engine_ex_commands.yaml
new file mode 100644
index 000000000..e95654ab5
--- /dev/null
+++ b/vim-engine/src/main/resources/engine_ex_commands.yaml
@@ -0,0 +1,75 @@
+# This file was automatically generated by [com.intellij.vim.processor.EXCommandProcessor].
+# If you are going to change it, you are probably doing something wrong, as your changes will be overridden by the next `gradle kspKotlin` run.
+
+action: com.maddyhome.idea.vim.vimscript.model.commands.ActionCommand
+as[cii]: com.maddyhome.idea.vim.vimscript.model.commands.AsciiCommand
+bd[elete]: com.maddyhome.idea.vim.vimscript.model.commands.BufferCloseCommand
+cal[l]: com.maddyhome.idea.vim.vimscript.model.commands.CallCommand
+comc[lear]: com.maddyhome.idea.vim.vimscript.model.commands.CmdClearCommand
+com[mand]: com.maddyhome.idea.vim.vimscript.model.commands.CmdCommand
+t,co[py]: com.maddyhome.idea.vim.vimscript.model.commands.CopyTextCommand
+delc[ommand]: com.maddyhome.idea.vim.vimscript.model.commands.DelCmdCommand
+d[elete]: com.maddyhome.idea.vim.vimscript.model.commands.DeleteLinesCommand
+delm[arks]: com.maddyhome.idea.vim.vimscript.model.commands.DeleteMarksCommand
+delf[unction]: com.maddyhome.idea.vim.vimscript.model.commands.DelfunctionCommand
+dig[raphs]: com.maddyhome.idea.vim.vimscript.model.commands.DigraphCommand
+dump[line]: com.maddyhome.idea.vim.vimscript.model.commands.DumpLineCommand
+ec[ho]: com.maddyhome.idea.vim.vimscript.model.commands.EchoCommand
+e[dit],bro[wse]: com.maddyhome.idea.vim.vimscript.model.commands.EditFileCommand
+exe[cute]: com.maddyhome.idea.vim.vimscript.model.commands.ExecuteCommand
+qa[ll],xa[ll],wqa[ll],quita[ll]: com.maddyhome.idea.vim.vimscript.model.commands.ExitCommand
+f[ile]: com.maddyhome.idea.vim.vimscript.model.commands.FileCommand
+cla[ss]: com.maddyhome.idea.vim.vimscript.model.commands.FindClassCommand
+fin[d]: com.maddyhome.idea.vim.vimscript.model.commands.FindFileCommand
+sym[bol]: com.maddyhome.idea.vim.vimscript.model.commands.FindSymbolCommand
+go[to]: com.maddyhome.idea.vim.vimscript.model.commands.GotoCharacterCommand
+his[tory]: com.maddyhome.idea.vim.vimscript.model.commands.HistoryCommand
+j[oin]: com.maddyhome.idea.vim.vimscript.model.commands.JoinLinesCommand
+ju[mps]: com.maddyhome.idea.vim.vimscript.model.commands.JumpsCommand
+let: com.maddyhome.idea.vim.vimscript.model.commands.LetCommand
+lockv[ar]: com.maddyhome.idea.vim.vimscript.model.commands.LockVarCommand
+unlo[ckvar]: com.maddyhome.idea.vim.vimscript.model.commands.UnlockVarCommand
+k,ma[rks]: com.maddyhome.idea.vim.vimscript.model.commands.MarkCommand
+m[ove]: com.maddyhome.idea.vim.vimscript.model.commands.MoveTextCommand
+n[ext],bn[ext]: com.maddyhome.idea.vim.vimscript.model.commands.NextFileCommand
+tabn[ext]: com.maddyhome.idea.vim.vimscript.model.commands.NextTabCommand
+noh[lsearch]: com.maddyhome.idea.vim.vimscript.model.commands.NoHLSearchCommand
+norm[al]: com.maddyhome.idea.vim.vimscript.model.commands.NormalCommand
+on[ly]: com.maddyhome.idea.vim.vimscript.model.commands.OnlyCommand
+pa[ckadd]: com.maddyhome.idea.vim.vimscript.model.commands.PackaddCommand
+Plug[in]: com.maddyhome.idea.vim.vimscript.model.commands.PlugCommand
+prev[ious],bp[revious],N[ext]: com.maddyhome.idea.vim.vimscript.model.commands.PreviousFileCommand
+tabp[previous],tabN[ext]: com.maddyhome.idea.vim.vimscript.model.commands.PreviousTabCommand
+p[rint],P[rint]: com.maddyhome.idea.vim.vimscript.model.commands.PrintCommand
+pro[mptfind]: com.maddyhome.idea.vim.vimscript.model.commands.PromptFindCommand
+promptr[eplace]: com.maddyhome.idea.vim.vimscript.model.commands.PromptReplaceCommand
+pu[t]: com.maddyhome.idea.vim.vimscript.model.commands.PutLinesCommand
+q[uit],clo[se],hi[de]: com.maddyhome.idea.vim.vimscript.model.commands.QuitCommand
+red[o]: com.maddyhome.idea.vim.vimscript.model.commands.RedoCommand
+dis[play],reg[isters]: com.maddyhome.idea.vim.vimscript.model.commands.RegistersCommand
+'@': com.maddyhome.idea.vim.vimscript.model.commands.RepeatCommand
+argu[ment]: com.maddyhome.idea.vim.vimscript.model.commands.SelectFileCommand
+fir[st]: com.maddyhome.idea.vim.vimscript.model.commands.SelectFirstFileCommand
+la[st]: com.maddyhome.idea.vim.vimscript.model.commands.SelectLastFileCommand
+se[t]: com.maddyhome.idea.vim.vimscript.model.commands.SetCommand
+setl[ocal]: com.maddyhome.idea.vim.vimscript.model.commands.SetLocalCommand
+sethandler: com.maddyhome.idea.vim.vimscript.model.commands.SetHandlerCommand
+sh[ell]: com.maddyhome.idea.vim.vimscript.model.commands.ShellCommand
+sor[t]: com.maddyhome.idea.vim.vimscript.model.commands.SortCommand
+so[urce]: com.maddyhome.idea.vim.vimscript.model.commands.SourceCommand
+sp[lit],vs[plit]: com.maddyhome.idea.vim.vimscript.model.commands.SplitCommand
+~,&,s[ubstitute]: com.maddyhome.idea.vim.vimscript.model.commands.SubstituteCommand
+tabc[lose]: com.maddyhome.idea.vim.vimscript.model.commands.TabCloseCommand
+tabm[ove]: com.maddyhome.idea.vim.vimscript.model.commands.TabMoveCommand
+tabo[nly]: com.maddyhome.idea.vim.vimscript.model.commands.TabOnlyCommand
+u[ndo]: com.maddyhome.idea.vim.vimscript.model.commands.UndoCommand
+wa[ll]: com.maddyhome.idea.vim.vimscript.model.commands.WriteAllCommand
+w[rite]: com.maddyhome.idea.vim.vimscript.model.commands.WriteCommand
+wn[ext]: com.maddyhome.idea.vim.vimscript.model.commands.WriteNextFileCommand
+wp[revious],wN[ext]: com.maddyhome.idea.vim.vimscript.model.commands.WritePreviousFileCommand
+wq,x[it],exi[t]: com.maddyhome.idea.vim.vimscript.model.commands.WriteQuitCommand
+y[ank]: com.maddyhome.idea.vim.vimscript.model.commands.YankLinesCommand
+mapc[lear],nmapc[lear],vmapc[lear],xmapc[lear],smapc[lear],omapc[lear],mapc[lear],imapc[lear],lmapc[lear],cmapc[lear]: com.maddyhome.idea.vim.vimscript.model.commands.mapping.MapClearCommand
+? map,nm[ap],vm[ap],xm[ap],smap,om[ap],im[ap],lm[ap],cm[ap],no[map],nn[oremap],vn[oremap],xn[oremap],snor[emap],ono[remap],no[remap],ino[remap],ln[oremap],cno[remap]
+: com.maddyhome.idea.vim.vimscript.model.commands.mapping.MapCommand
+unm[ap],nun[map],vu[nmap],xu[nmap],sunm[ap],ou[nmap],unm[ap],iu[nmap],lu[nmap],cu[nmap]: com.maddyhome.idea.vim.vimscript.model.commands.mapping.UnMapCommand