-
Notifications
You must be signed in to change notification settings - Fork 0
Getting started
Big part of Vrapper's design was inspired by Yi - a text editor written in Haskell. Because of that, there is quite huge (as for a Java code) emphasis put on immutability and composition.
Modes are the heart of Vim and Vrapper implements quite a few of them. Let's concentrate on normal mode and visual modes - they all extend CommandBasedMode. CommandBasedMode parses incoming keys by using keyboard map.
Keyboard map consists of States and Transitions. Each time a key is pressed you move to next state via transition. When there is a command associated with transition - it's executed. If there is no next state you return to mode's initial state.
Of course, this is simplification. States and transitions aren't just dumb data holders - they are full blown Java objects so they can do a lot more. For example, commands' counts are handled using CountingState.
Commands are what modes execute. You can have "move to beginning of the next word" command ('w'), uppercase everything inside these parentheses ('gUip'), execute JDT's rename refactoring ('gR'), delete three characters ('3x'), etc.
There are few commands that just do one thing. Usually command is composed, for example 'de' command ("delete to the end of a word") is an instance of TextOperationOnTextObjectCommand that executes text operation (DeleteOperation) on text object that can be described as "from the cursor to where 'e' motion would take us". This is MotionTextObject that encomposes MoveWordEndRight motion.
TextOperationOnTextObjectCommand
DeleteOperation
MotionTextObject
MoveWordEndRight
MotionTextObject is described by one motion. There are other - MotionPairTextObject (like 'ip' - inside parentheses) which takes two motions. Selection is an TextObject as well.
- Commands - they do something, they have side effects
- TextObjects - they describe an amount of text
- Motions - they show you where to move the cursor (but they don't do it, MotionCommand does)
- TextOperations - they do something to text (change, delete, yank, uppercase)
Not all keyboard maps return Commands, some return Motions, other do return TextObjects. There is ConvertingState that can take a function (eg. one that turns Motion into MotionPairTextObject), State that returns Motions and you have a state that translates keystroke into TextObjects.
As you can see, one can easily compose states. They go not only into parent-child relationship (as in previous example), but can also be siblings - you can create state that is an union of two states.
This gives us the ease of declaratively describing Vim behaviour and it allows us to make Vrapper more extensible. Vrapper Java editor modes' initial states are unions of standard Vim behaviour and Java-only bonus.
There are formatting settings in trunk/misc/formatter.xml. You can set it globally for workspace (Preferences -> Java -> Code Style -> Formatter -> Import) or set it per-project.
Wrapper uses excellent Mockito library to create mocks in our tests. Go to http://www.mockito.org and get mockito-all-1.7.jar. Go (Preferences -> Java -> Build Path -> User Libraries) create new library, call it 'Mockito' and add it jar file you've just downloaded.
Go (Preferences -> Java -> JUnit) and add two filters: net.sourceforge.vrapper.core.tests.cases.NormalModeTests.checkCommand , net.sourceforge.vrapper.core.tests.cases.VisualModeTests.checkCommand and net.sourceforge.vrapper.core.tests.cases.VisualModeTests.checkLeavingCommand.
Those have nothing to do with Vrapper, but I found them being good ideas.
Go (Preferences -> Java -> Code Style -> Code Templates -> Code -> Method body) and change it to
// ${todo} Auto-generated method stub
throw new UnsupportedOperationException("not yet implemented");
Go (Preferences -> General -> Keys) and bind 'Rerun JUnit Test' to some key combination. You will find yourself hitting that key combo a lot.
It's always a good idea to start with a test. Vrapper have some nice utilities for testing - we can run our tests in seconds, without need to actually start a new Eclipse instance with freshly modified Vrapper. This speeds up development a lot.
Let's suppose you want to add new normal mode command. Open the NormalModeTests.java file.
Add new test case
@Test
public void testFooCommand() {
checkCommand(new FooCommand(new BarMotion("baz")),
"This is ",'w',"ay too cool!",
"This is ",'m',"assively cool!");
}
Code reads as follows:
The editor contains text:
This is way too cool!
with the cursor is on the letter w.
We call command new FooCommand(new BarMotion("baz")).
When it's done, editor contains:
This is massively cool!
with the cursor on the letter m.
Instead of crating command in your test you can specify key sequence that can yield your command using forKeySeq method. Above check can be rewritten as:
checkCommand(forKeySeq("<C-S-f>oobaz<CR>"),
"This is ",'w',"ay too cool!",
"This is ",'m',"assively cool!");
One specifies key sequence using the same syntax as you use in Vim's :map.
Those tests are very easy to write, especially when you run Vim and Eclipse side by side when doing so.
Obviously, you want to use your new shiny feature as soon as possible :-)
Go for File -> Export -> Deployable fragments and plug-ins, select stuff you want to use and your Eclipse installation in Destination -> Directory
If you added new features (or new features appeared since last release) you man need to export them as well. File -> Export -> Deployable features.
You have to restart Eclipse for new version of Vrapper to kick in.