As I said the VISUAL features bundles commands together. I was thinking to write a big article after I finished this feature. But then I realize that I probably won't remember much of those after the feature is complete. Instead I decided to split up article for each commands I've made.
Controls structure
This is the flow I've finally came up with. The ViSUAL action will take place after the cursor movements handler. Then it monitors to see if the cursor has been moved. However this is only a portion of the control flow. To better support the Action structure I described in previous post . I have to extends the flow to check whether an action support a cursor movement:
The reason to have cursor movement properties for each action is because some commands like d, v, y needs further input to take action. The purple portion of the diagram is where the VISUAL command take place. As you can see commands such as d also take place in here.
To further explain this. Let's take the VISUAL command as an example and zoom in to the purple area:
The procedure on VISUAL is:
1. Select text
2. Take action
In order to select text I have to check if the cursor has been moved. To determine whether the cursor is moved, I need a reference starting point. Which is created when the VISUAL action is initialized.
Both cursor and action command should be called within the same InputEvent. That is because the cursor command will push information to the event when needed. I would explain this at later section.
SyntaxAnalyzer
The first step is to complete the selection feature. Which the
selection itself is a super set of cursor motions. I will list them one
by one.
1. i group - iw, i{bracket}, etc.
2. t group - t[char]
3. General movements - hjklLGgg...
General movements, t group
By design these movements are automatically handled from the movement commands. There should be little to worried about.
i group
The most common command I use for this group are viw and vi{bracket|quote}. To have the bracket range selected. I need a parser to find the matching bracket first. To have the word boundary selected. I also need a parser to check if the preceding/following characters are in the same group. That is also a parser function.
And that's where the SyntaxAnalyzer comes from.
% command
"Matching brackets", that's what % command do! Guess I'll start with this command first.
Writing a bracket parser is simple. Feeding the content from the start, pushing brackets into the stack. Advancing the levels for each opening bracket. Decreasing the level for each closing bracket. Unmatched bracket are discarded, matched bracket are coupled into a object.
But the tricky part of the % command is not about the bracket. It is about the item. It is opening token and closing token, which the length of the token varies. Thus I need to be aware of how the parser is handling the fed content.
Word boundary - Unicode Range
After some observation of how viw behaves. I've discovered that it somehow detects the Unicode range for selections. For example, selected abc2def from b will result in selecting abc. But with characters other than a-z it could also select a Latin word caleō, this is surprising because general ascii table and Latin characters does not fall into the same char code range! So how does Vim know this is THE word to choose?
After some inspection it seemed Vim is not really that intelligent. Most of the Latin symbols were not identified like ASCII symbol does. Well I could do better but I actually do not want to pay much effort on finding out all symbols for each Unicode range myself. Furthermore, since this is written for casually writing code in Web. I have no intention to support language other the English.
Articles in the series
Useful Links
Project home |
Demo
斟酌 鵬兄
Wed Mar 30 2016 12:04:00 GMT+0000 (Coordinated Universal Time)
Last modified: Sun Apr 10 2022 07:55:53 GMT+0000 (Coordinated Universal Time)