Kate Vim Progress

Hi all,

Just an eye-glazingly brief blog post about some of the stuff I’ve been working on in the Kate Vim emulation mode since my last blog. Once more, I’ll mostly be dumping them all as bullet points, Gräßlin-Style™, with some longer sections on the more important changes, but this time around I’ve added some nifty animated gifs which you can skip to should the full text prove too harrowing!

In roughly chronological order, I:

“Yank Highlighting”, 444KB, Click to Play.
 

… and a biggie:

Emulated Vim Command Bar

There are quite a lot of issues with the interaction between Vim mode and Kate’s own Find dialog:

etc. On top of that, we miss out on some nice features of Vim’s search bars, such as ctrl-r for insertion of register contents; ctrl-w for deleting previous word; ctrl-h for delete; ctrl-b/e for jumping to the beginning or end (more conveniently located, IMO, than HOME or END); plus the Qt regex syntax is different from Vim’s. In light of this, I decided to add a new KateViewBarWidget called “KateViEmulatedCommandBar”:

“Emulated Command Bar Search”, 697KB, Click to Play.
This behaves much more like Vim, and has the features and bugfixes mentioned above; it even does a reasonable job (in current master; it missed 4.11) of translating Vim regexes to Qt ones e.g. with Vim, a “+” is a literal “+”, not an “at least one of the preceding” marker; with Qt it is the reverse. The emulated command bar performs this, and other, conversions for you.

The searches carried out can be repeated correctly via “n” and “N”. Search history can be navigated via ctrl-p and ctrl-n, and searches “external” to the emulated command bar (e.g. those carried out by “*” and “#”) are added to this history. “Smart Case” is used for specifying case-sensitivity – if the search term has any capitals, then the search is assumed to be case-sensitive; else it is case-insensitive. More on the emulated command bar later! Back to the micro-fixes:

Everything above made it for 4.11, I think. The Emulated Command Bar was disabled by default but can be enabled by setting the hidden config option “Vi Input Mode Emulate Command Bar” to “true”. Continuing:

… and then on to:

Making the Emulated Command Bar Suitable for Default

The emulated command bar has a lot of advantages over the default Find dialog and command-line for Kate Vim users, but there are drawbacks, too: firstly, it can only perform regex searches and not literal searches, which is awkward when searching for complex expressions pasted from your document that may contain characters that have a special meaning when interpreted as regex’s (e.g. “*”) or which have special meaning in a Vim search bar (e.g. “/” when searching forward, and “?” when searching backwards). The necessity of going through the search term and escaping all such characters is a big strike against its use.

Secondly, Vim’s Find/ Replace dialog has most of the same flaws, when used in Vim mode, as its Find dialog has: in fact, incremental Find & Replace doesn’t work at all with Vim mode(!), and the emulated command bar is of no use here.

Since I’d really like to make the emulated command bar the default (and possibly only) option for use in Vim mode, I really needed to sort out a solution for these two dealbreakers.

For the first, there are basically two options: one is to add some kind of flag that says “look for literal matches for this string; don’t treat it as a regex!”; the other is to make it easy to perform the escaping of special characters. I eventually opted for the second, as it allowed one to treat portions of an expression as a regex if one desired, plus it allowed one to always use the same delimiters in a sed-replace expression (i.e. :s/find/replace/gci) without having to worry about whether the “find” term contained “/”‘s or not. So I added a shortcut (ctrl-g) to the emulated command bar that behaved much like ctrl-r (“insert contents of the following register”) except that it escapes the inserted register contents in such a way that a regex search for the contents would behave the same as a literal search for the contents. The gif below highlights the problem and the solution; the “:) :) :)” bit used ctrl-g to insert the (correctly escaped) yanked expression:

“Escape Expression for Regex”, 483KB, Click to Play.
For the second problem, improving the good old sed-replace seemed the obvious choice, so I added some code in the emulated command bar to translate the regex in the “find” term from Vim style to Qt style. Kate’s own Find/ Replace dialog maintains separate histories for both the “find” and “replace” terms, so I needed to follow suit if I wanted the emulated command bar to be a credible replacement: if the cursor is placed over the “find” or “replace” terms in a sed-replace expression, pressing ctrl-p will summon the relevant history:

“Sed Search/ Replace History”, 259KB, Click to Play.
Kate’s own Find/ Replace dialog makes it easy to focus on the “find” and “replace” fields, so I also added shortcuts “ctrl-d” and “ctrl-f” to the emulated command bar that clears and places the cursor at the “find” and “replace” portions of a sed-replace expression, respectively. As an extra bonus, ctrl-space can be used anywhere in the emulated command bar to complete words from the document, which is handy when filling out your find/ replace terms.

Still missing, though, were interactive search and replace; multi-line search; usage of \U and \L in the “replace” expression to make regex captures upper/ lower cased; etc. Multi-line search and \U and \L codes are available in a class called KateRegExpSearch, so I initially pulled out the guts of the SedReplace code and replaced it with that, and then made the whole thing interactive:

“Sed Multi-Line”, 399KB, Click to Play.
(in the gif above, I constructed my regex with the standard “/” search bar so I could get immediate feedback as I am a giant regex baby who still needs his stabilisers; this final regex was then added to the “find” history, which I then added to the sed-replace search expression with a ctrl-d + ctrl-p).

The emulated command bar now seemed to me to be a decent alternative to Kate’s own Find/ Find & Replace dialogs, so with that out of the way, I then moved on to …

Macro Support!

The lack of macro support is what got me into Kate Vim hacking in the first place, so it seems weird that it ended up being almost the last thing I tackled. The reason, of course, is that macro support would be a bit crippled if we couldn’t run searches or execute commands in our macros, so I really needed to finish the emulated command bar first. It ended up being quite easy in the end; the main difficulty was in interacting with mappings, especially the situation where a mapping triggered a macro which in turn needed to execute another mapping! Anyway, here’s a small, real-life example of a Kate Vim macro in action:

“Macro”, 300KB, Click to Play.
One difficulty with macros comes from recording and replaying auto-completions. In Vim itself, macros are “dumb” sequence of keypresses that are recorded and replayed verbatim, including those that summon, navigate and execute lists of completions. In Kate Vim, though, this approach doesn’t work so well, partly because the available completions at any time are less predictable (e.g. we could have a function appear in the list of completions when we record the macro, but not when we replay it, due to e.g. problems with the C++ parser etc) and also because, in KDevelop at least, the added completions are context-sensitive: for example, a completion of a function will add its own opening bracket if there is not one immediately after the cursor position, but will re-use the existing one otherwise. The “repeat last change” runs into a similar problem and has some measures to mitigate this, but is still far from fool-proof. The gif below illustrates the problem:

“Old Completion”, 184KB, Click to Play.
In what probably represents the worst effort:payoff ratio in all of history, I spent a while re-working the macro recording and playback system to store attributes of completions as they occur, and then attempt to play them back using the same context-sensitive system; the “repeat last change” mechanism was re-worked to also use this system, so I’ll use that to demonstrate:

“New Completion”, 176KB, Click to Play.
 

That’s about it for macro support; now back to the small changes!

… and that’s about it! I’m going to take a break from Kate stuff for a while to work on some other projects I’ve been neglecting, but will return to finish off some odds and ends later :)

The Kate Vim mode is in pretty good shape nowadays, so if you were thinking of trying it out, now (with the current master) would be a good time :)

Tags:  planet 

See also: