1======
2Vimode
3======
4
5.. contents::
6
7
8About
9=====
10
11Vimode is a Vim-mode plugin for Geany written by a guy who does not use Vim.
12Expect problems unexpected by a Vim user and, please, report them.
13
14Despite the limited Vim knowledge of the author, the plugin tries to be a
15reasonably complete Vim mode implementation featuring:
16
17* normal mode, insert/replace mode, visual mode, line visual mode
18* repeated commands (e.g. 10dd - delete 10 lines)
19* "motion" commands (e.g. d10l - delete 10 characters to the right)
20* "text object" commands (e.g. di( - delete inner contents of parentheses)
21* visual mode commands (e.g. ~ to swap case of the selected text)
22* basic ex mode commands like :s, including range specifications (e.g.
23 :5,8s/foo/bar/g - replace foo with bar on lines 5 through 8)
24* most basic navigation, selection and text manipulation commands - see the end
25 of this file for the full list
26* command repetition using "." and repeated insert
27
28It should be relatively easy to add more (non-special) commands so if you run
29into something you are missing, please let me know.
30
31Setup and Configuration
32=======================
33The plugin can be enabled/disabled from the Plugin Manager of Geany. Once enabled,
34it adds a new menu called Vim Mode under the Tools menu with the following items.
35
36Enable Vim Mode
37---------------
38Enables/disables the Vim mode. A keybinding can be assigned to this action so
39you can for instance use Geany normally and enable/disable the Vim mode as
40needed.
41
42Insert Mode for Dummies
43-----------------------
44This makes the insert mode behave like normal Geany, only the escape key allows
45you to switch to the Vim command mode. This is basically "Vim for the rest of us"
46who want to use the editor in a standard (understand non-vim) way but who like
47the idea of having access to Vim commands from time to time. Highly unintrusive
48so you basically do not know about the Vim mode normally.
49
50Start in Insert Mode
51--------------------
52By default, the plugin starts in the normal mode. If you enable the "dummies"
53mode above, you might also want to enable this option so you do not have to
54switch to the insert mode manually when the application starts.
55
56Behavior
57========
58Upon changing mode, the plugin writes the current mode in the status bar. The
59caret shape also indicates the current mode:
60
61* block, not blinking - normal mode
62* vertical line, not blinking - visual mode
63* blinking vertical line - insert mode
64* blinking underscore - replace mode
65
66When evaluating key presses, the plugin checks if the keypress is a Vim command
67or a part of a command in which case the plugin consumes the key press event
68and does not propagate it to Geany. When the keypress is not a Vim command,
69the plugin sends it to Geany which processes it normally based in its internal
70logic. This means that it is still possible to use normal Geany keybindings
71with this plugin unless they conflict with a Vim command.
72
73If autocompletion popups or tooltips are present in insert mode, escape closes
74them first without entering the normal mode so you do not enter normal mode
75by accident.
76
77Limitations and Problems
78------------------------
79I tried to implement a reasonable subset of Vim commands but please note that
80the judgement what is a reasonable set of commands was made by a guy who does not
81use Vim. So it is very probable I missed some totally fundamental behavior
82of Vim every Vim user would expect to be present. Please report such problems.
83
84This is an incomplete list of known limitations of the plugin:
85
86* selection in visual mode does not behave the same way as in Vim - the reason is
87 that the editor component Geany uses (Scintilla) uses cursor which is always
88 between characters and not on characters (block cursor which appears to be
89 on top of a character behaves as if it were before the character). This may lead
90 to situations when the position of the cursor is off by one. This issue might
91 be fixed later but it will be tricky.
92* undo does not preserve cursor position the same way Vim does - probably fixable
93* block visual mode is not implemented - probably possible using Scintilla's
94 multiple selection feature
95* select submode of insert mode is not implemented
96* named registers and related commands are not implemented
97* Ctrl+X mode is not implemented
98* marks are not implemented
99* fold commands are not implemented
100* most commands starting with "'", "z", and "g" are not implemented
101* most ex mode commands are not implemented (excluding basic stuff like search,
102 replace, saving, etc.)
103* despite being mentioned below, none of the commands for quitting (:q, ZZ, etc.)
104 work because the corresponding function is not in Geany API yet - everything is
105 ready in the plugin though
106* only the 'g' flag is supported in the substitute command
107* in search and substitute the regular expressions are based on Scintilla regular
108 expressions which differ from Vim. Check the Scintilla documentation at
109 http://www.scintilla.org/ScintillaDoc.html#Searching for more details.
110 In addition, \c is also supported to allow case-insensitive search.
111
112FAQ
113===
114
115Why does Vimode suck so much?
116-----------------------------
117Well, it simulates the Vim behavior - what did you expect?
118
119No, stupid, I mean why does your implementation suck so much?
120-------------------------------------------------------------
121Ah, that's simple - I am not a Vim user. Before writing this plugin, I knew
122about 5 Vim commands (after writing this plugin, my knowledge has nearly doubled).
123Even though I kind of like the idea behind the editor, my poor brain isn't able
124to remember in which mode I currently am and what keypresses I can use. This
125means I don't really know how a typical user uses Vim and I probably miss
126some very basic things Vim users take for granted. Please report such issues
127so I can improve the plugin.
128
129So why the hell did you write this plugin?
130------------------------------------------
131It was the constant whining of Vim users at Prague and Chemnitz Linux Days which
132made me write the plugin. And it turned out that writing a Vim editor is
133quite a lot of fun - much more than using it.
134
135Meh, even I could write a better Vim plugin
136-------------------------------------------
137Great! Submit patches! Fix bugs! All contributions are really welcome.
138
139Help! I enabled your plugin together with others and the editor is really strange now!
140--------------------------------------------------------------------------------------
141This, my friend, is the world of Vim. Welcome! Fortunately, you can easily
142disable it using Geany's Plugin Manager. Phew!
143
144Help! I am a long-time Vim user and can't quit the editor, :q doesn't work!
145---------------------------------------------------------------------------
146Geany currently doesn't allow plugins to quit the editor so you have to do
147it in a non-vim way. This is where the tricky part starts for Vim users: with your
148mouse navigate to the top-right corner of the window to the X button and click
149it - behold, the window closes (I know, totally counter-intuitive for Vim users).
150
151After building the plugin, I noticed a binary called viw, what is it?
152---------------------------------------------------------------------
153After I started writing the plugin, I soon realized that in fact, I am writing
154a new editor. I nearly didn't use any Geany calls and most of the code just
155calls the Scintilla API. At this point I decided to separate the Geany plugin
156part from the rest of the code which is completely Geany-independent. And now
157I could write a simple editor which just uses Scintilla and GTK (well,
158not exactly - the way it builds now it still uses Scintilla from libgeany
159but the build could be easily modified to link against statically built
160Scintilla without any Geany dependency). So yeah, I'm a real man now, have my own
161editor - it only sucks it's a Vim clone. And in fact it turned out to be useful
162for the development of the plugin because one can use the viw (Vi Worsened)
163editor for testing instead of having to restart Geany all the time.
164
165So does it mean I could use your code and add Vim support to another editor?
166----------------------------------------------------------------------------
167Yes - as long as the editor is based on Scintilla and GTK. If it is, it should
168be really simple - just check the "backends" directory how it is done for Geany
169and viw. I believe it should still be quite simple to modify the code if
170the editor uses Scintilla but doesn't use GTK - the amount of the used GTK code
171is very small (most work will be with re-mapping the key event codes to the
172other library). If your editor isn't Scintilla-based, you are more or less
173doomed - most of the code deals with Scintilla and switching to a different
174editor component basically means rewriting the plugin.
175
176Contact
177=======
178
179Author
180------
181Jiří Techet, <techet(at)gmail(dot)com>.
182
183Bug Reports
184-----------
185To report bugs, please use the Geany-Plugins GitHub page at
186https://github.com/geany/geany-plugins/issues
187
188License
189=======
190
191Vimode is distributed under the terms of the GNU General Public License
192as published by the Free Software Foundation; either version 2 of the
193License, or (at your option) any later version. A copy of this license
194can be found in the file COPYING included with the source code of this
195program.
196
197Downloads
198=========
199
200Vimode is part of the combined Geany Plugins release. For more information and
201downloads, please visit http://plugins.geany.org/geany-plugins/
202
203Source Code
204===========
205
206The source code is available at::
207
208 git clone https://github.com/geany/geany-plugins.git
209
210Implemented Commands
211====================
212The rest of the file contains a list of Vim commands which have been at least
213partially implemented in the plugin. This is taken from the index.txt Vim help
214file which is also present in the root directory of the plugin. If you add
215a new command, please do not forget to update the table below.::
216
217 ==============================================================================
218 1. Insert mode insert-index
219
220 tag char action in Insert mode
221 -----------------------------------------------------------------------
222 i_CTRL-@ CTRL-@ insert previously inserted text and stop
223 insert
224 i_CTRL-A CTRL-A insert previously inserted text
225 i_CTRL-C CTRL-C quit insert mode, without checking for
226 abbreviation, unless 'insertmode' set.
227 i_CTRL-D CTRL-D delete one shiftwidth of indent in the current
228 line
229 i_CTRL-E CTRL-E insert the character which is below the cursor
230 i_<BS> <BS> delete character before the cursor
231 i_CTRL-H CTRL-H same as <BS>
232 i_<Tab> <Tab> insert a <Tab> character
233 i_CTRL-I CTRL-I same as <Tab>
234 i_<NL> <NL> same as <CR>
235 i_CTRL-J CTRL-J same as <CR>
236 i_<CR> <CR> begin new line
237 i_CTRL-M CTRL-M same as <CR>
238 i_CTRL-O CTRL-O execute a single command and return to insert
239 mode
240 i_CTRL-T CTRL-T insert one shiftwidth of indent in current
241 line
242 i_CTRL-W CTRL-W delete word before the cursor
243 i_CTRL-Y CTRL-Y insert the character which is above the cursor
244 i_<Esc> <Esc> end insert mode (unless 'insertmode' set)
245 i_CTRL-[ CTRL-[ same as <Esc>
246 i_<Del> <Del> delete character under the cursor
247
248 i_<Left> <Left> cursor one character left
249 i_<S-Left> <S-Left> cursor one word left
250 i_<C-Left> <C-Left> cursor one word left
251 i_<Right> <Right> cursor one character right
252 i_<S-Right> <S-Right> cursor one word right
253 i_<C-Right> <C-Right> cursor one word right
254 i_<Up> <Up> cursor one line up
255 i_<S-Up> <S-Up> same as <PageUp>
256 i_<Down> <Down> cursor one line down
257 i_<S-Down> <S-Down> same as <PageDown>
258 i_<Home> <Home> cursor to start of line
259 i_<C-Home> <C-Home> cursor to start of file
260 i_<End> <End> cursor past end of line
261 i_<C-End> <C-End> cursor past end of file
262 i_<PageUp> <PageUp> one screenful backward
263 i_<PageDown> <PageDown> one screenful forward
264 i_<Insert> <Insert> toggle Insert/Replace mode
265
266 ==============================================================================
267 2. Normal mode normal-index
268
269 CHAR any non-blank character
270 WORD a sequence of non-blank characters
271 N a number entered before the command
272 {motion} a cursor movement command
273 Nmove the text that is moved over with a {motion}
274 SECTION a section that possibly starts with '}' instead of '{'
275
276 note: 1 = cursor movement command; 2 = can be undone/redone
277
278 tag char note action in Normal mode
279 ------------------------------------------------------------------------------
280 CTRL-B CTRL-B 1 scroll N screens Backwards
281 CTRL-D CTRL-D scroll Down N lines (default: half a screen)
282 CTRL-E CTRL-E scroll N lines upwards (N lines Extra)
283 CTRL-F CTRL-F 1 scroll N screens Forward
284 <BS> <BS> 1 same as "h"
285 CTRL-H CTRL-H 1 same as "h"
286 <NL> <NL> 1 same as "j"
287 CTRL-J CTRL-J 1 same as "j"
288 <CR> <CR> 1 cursor to the first CHAR N lines lower
289 CTRL-M CTRL-M 1 same as <CR>
290 CTRL-N CTRL-N 1 same as "j"
291 CTRL-P CTRL-P 1 same as "k"
292 CTRL-R CTRL-R 2 redo changes which were undone with 'u'
293 CTRL-U CTRL-U scroll N lines Upwards (default: half a
294 screen)
295 CTRL-Y CTRL-Y scroll N lines downwards
296
297 <Space> <Space> 1 same as "l"
298 # # 1 search backward for the Nth occurrence of
299 the ident under the cursor
300 $ $ 1 cursor to the end of Nth next line
301 % % 1 find the next (curly/square) bracket on
302 this line and go to its match, or go to
303 matching comment bracket, or go to matching
304 preprocessor directive.
305 N% {count}% 1 go to N percentage in the file
306 & & 2 repeat last :s
307 star * 1 search forward for the Nth occurrence of
308 the ident under the cursor
309 + + 1 same as <CR>
310 , , 1 repeat latest f, t, F or T in opposite
311 direction N times
312 - - 1 cursor to the first CHAR N lines higher
313 . . 2 repeat last change with count replaced with
314 N
315 / /{pattern}<CR> 1 search forward for the Nth occurrence of
316 {pattern}
317 /<CR> /<CR> 1 search forward for {pattern} of last search
318 count 0 1 cursor to the first char of the line
319 count 1 prepend to command to give a count
320 count 2 "
321 count 3 "
322 count 4 "
323 count 5 "
324 count 6 "
325 count 7 "
326 count 8 "
327 count 9 "
328 : : 1 start entering an Ex command
329 ; ; 1 repeat latest f, t, F or T N times
330 < <{motion} 2 shift Nmove lines one 'shiftwidth'
331 leftwards
332 << << 2 shift N lines one 'shiftwidth' leftwards
333 > >{motion} 2 shift Nmove lines one 'shiftwidth'
334 rightwards
335 >> >> 2 shift N lines one 'shiftwidth' rightwards
336 ? ?{pattern}<CR> 1 search backward for the Nth previous
337 occurrence of {pattern}
338 ?<CR> ?<CR> 1 search backward for {pattern} of last search
339 A A 2 append text after the end of the line N times
340 B B 1 cursor N WORDS backward
341 C ["x]C 2 change from the cursor position to the end
342 of the line, and N-1 more lines [into
343 register x]; synonym for "c$"
344 D ["x]D 2 delete the characters under the cursor
345 until the end of the line and N-1 more
346 lines [into register x]; synonym for "d$"
347 E E 1 cursor forward to the end of WORD N
348 F F{char} 1 cursor to the Nth occurrence of {char} to
349 the left
350 G G 1 cursor to line N, default last line
351 H H 1 cursor to line N from top of screen
352 I I 2 insert text before the first CHAR on the
353 line N times
354 J J 2 Join N lines; default is 2
355 L L 1 cursor to line N from bottom of screen
356 M M 1 cursor to middle line of screen
357 N N 1 repeat the latest '/' or '?' N times in
358 opposite direction
359 O O 2 begin a new line above the cursor and
360 insert text, repeat N times
361 P ["x]P 2 put the text [from register x] before the
362 cursor N times
363 R R 2 enter replace mode: overtype existing
364 characters, repeat the entered text N-1
365 times
366 S ["x]S 2 delete N lines [into register x] and start
367 insert; synonym for "cc".
368 T T{char} 1 cursor till after Nth occurrence of {char}
369 to the left
370 V V start linewise Visual mode
371 W W 1 cursor N WORDS forward
372 X ["x]X 2 delete N characters before the cursor [into
373 register x]
374 Y ["x]Y yank N lines [into register x]; synonym for
375 "yy"
376 ZZ ZZ store current file if modified, and exit
377 ZQ ZQ exit current file always
378 ^ ^ 1 cursor to the first CHAR of the line
379 _ _ 1 cursor to the first CHAR N - 1 lines lower
380 a a 2 append text after the cursor N times
381 b b 1 cursor N words backward
382 c ["x]c{motion} 2 delete Nmove text [into register x] and
383 start insert
384 cc ["x]cc 2 delete N lines [into register x] and start
385 insert
386 d ["x]d{motion} 2 delete Nmove text [into register x]
387 dd ["x]dd 2 delete N lines [into register x]
388 e e 1 cursor forward to the end of word N
389 f f{char} 1 cursor to Nth occurrence of {char} to the
390 right
391 g g{char} extended commands, see g below
392 h h 1 cursor N chars to the left
393 i i 2 insert text before the cursor N times
394 j j 1 cursor N lines downward
395 k k 1 cursor N lines upward
396 l l 1 cursor N chars to the right
397 n n 1 repeat the latest '/' or '?' N times
398 o o 2 begin a new line below the cursor and
399 insert text, repeat N times
400 p ["x]p 2 put the text [from register x] after the
401 cursor N times
402 r r{char} 2 replace N chars with {char}
403 s ["x]s 2 (substitute) delete N characters [into
404 register x] and start insert
405 t t{char} 1 cursor till before Nth occurrence of {char}
406 to the right
407 u u 2 undo changes
408 v v start characterwise Visual mode
409 w w 1 cursor N words forward
410 x ["x]x 2 delete N characters under and after the
411 cursor [into register x]
412 y ["x]y{motion} yank Nmove text [into register x]
413 yy ["x]yy yank N lines [into register x]
414 bar | 1 cursor to column N
415 ~ ~ 2 'tildeop' off: switch case of N characters
416 under cursor and move the cursor N
417 characters to the right
418 <C-End> <C-End> 1 same as "G"
419 <C-Home> <C-Home> 1 same as "gg"
420 <C-Left> <C-Left> 1 same as "b"
421 <C-Right> <C-Right> 1 same as "w"
422 <Del> ["x]<Del> 2 same as "x"
423 <Down> <Down> 1 same as "j"
424 <End> <End> 1 same as "$"
425 <Home> <Home> 1 same as "0"
426 <Insert> <Insert> 2 same as "i"
427 <Left> <Left> 1 same as "h"
428 <PageDown> <PageDown> same as CTRL-F
429 <PageUp> <PageUp> same as CTRL-B
430 <Right> <Right> 1 same as "l"
431 <S-Down> <S-Down> 1 same as CTRL-F
432 <S-Left> <S-Left> 1 same as "b"
433 <S-Right> <S-Right> 1 same as "w"
434 <S-Up> <S-Up> 1 same as CTRL-B
435 <Up> <Up> 1 same as "k"
436
437 ==============================================================================
438 2.1 Text objects objects
439
440 These can be used after an operator or in Visual mode to select an object.
441
442 tag command action in op-pending and Visual mode
443 ------------------------------------------------------------------------------
444 v_aquote a" double quoted string
445 v_a' a' single quoted string
446 v_a( a( same as ab
447 v_a) a) same as ab
448 v_a< a< "a <>" from '<' to the matching '>'
449 v_a> a> same as a<
450 v_aB aB "a Block" from "[{" to "]}" (with brackets)
451 v_a[ a[ "a []" from '[' to the matching ']'
452 v_a] a] same as a[
453 v_a` a` string in backticks
454 v_ab ab "a block" from "[(" to "])" (with braces)
455 v_a{ a{ same as aB
456 v_a} a} same as aB
457 v_iquote i" double quoted string without the quotes
458 v_i' i' single quoted string without the quotes
459 v_i( i( same as ib
460 v_i) i) same as ib
461 v_i< i< "inner <>" from '<' to the matching '>'
462 v_i> i> same as i<
463 v_iB iB "inner Block" from "[{" and "]}"
464 v_i[ i[ "inner []" from '[' to the matching ']'
465 v_i] i] same as i[
466 v_i` i` string in backticks without the backticks
467 v_ib ib "inner block" from "[(" to "])"
468 v_i{ i{ same as iB
469 v_i} i} same as iB
470
471 ==============================================================================
472 2.4 Commands starting with 'g' g
473
474 tag char note action in Normal mode
475 ------------------------------------------------------------------------------
476 gE gE 1 go backwards to the end of the previous
477 WORD
478 gU gU{motion} 2 make Nmove text uppercase
479 ge ge 1 go backwards to the end of the previous
480 word
481 gg gg 1 cursor to line N, default first line
482 gu gu{motion} 2 make Nmove text lowercase
483 g~ g~{motion} 2 swap case for Nmove text
484
485 ==============================================================================
486 2.5 Commands starting with 'z' z
487
488 tag char note action in Normal mode
489 ------------------------------------------------------------------------------
490 z<CR> z<CR> redraw, cursor line to top of window,
491 cursor on first non-blank
492 z+ z+ cursor on line N (default line below
493 window), otherwise like "z<CR>"
494 z- z- redraw, cursor line at bottom of window,
495 cursor on first non-blank
496 z. z. redraw, cursor line to center of window,
497 cursor on first non-blank
498 zb zb redraw, cursor line at bottom of window
499 zt zt redraw, cursor line at top of window
500 zz zz redraw, cursor line at center of window
501
502 ==============================================================================
503 3. Visual mode visual-index
504
505 Most commands in Visual mode are the same as in Normal mode. The ones listed
506 here are those that are different.
507
508 tag command note action in Visual mode
509 ------------------------------------------------------------------------------
510 v_CTRL-C CTRL-C stop Visual mode
511 v_: : start a command-line with the highlighted
512 lines as a range
513 v_< < 2 shift the highlighted lines one
514 'shiftwidth' left
515 v_> > 2 shift the highlighted lines one
516 'shiftwidth' right
517 v_C C 2 delete the highlighted lines and start
518 insert
519 v_D D 2 delete the highlighted lines
520 v_J J 2 join the highlighted lines
521 v_O O Move horizontally to other corner of area.
522 v_R R 2 delete the highlighted lines and start
523 insert
524 v_S S 2 delete the highlighted lines and start
525 insert
526 v_U U 2 make highlighted area uppercase
527 v_V V make Visual mode linewise or stop Visual
528 mode
529 v_X X 2 delete the highlighted lines
530 v_Y Y yank the highlighted lines
531 v_c c 2 delete highlighted area and start insert
532 v_d d 2 delete highlighted area
533 v_o o move cursor to other corner of area
534 v_r r 2 delete highlighted area and start insert
535 v_s s 2 delete highlighted area and start insert
536 v_u u 2 make highlighted area lowercase
537 v_v v make Visual mode characterwise or stop
538 Visual mode
539 v_x x 2 delete the highlighted area
540 v_y y yank the highlighted area
541 v_~ ~ 2 swap case for the highlighted area
542
543 ==============================================================================
544 5. EX commands ex-cmd-index :index
545
546 This is a brief but complete listing of all the ":" commands, without
547 mentioning any arguments. The optional part of the command name is inside [].
548 The commands are sorted on the non-optional part of their name.
549
550 tag command action
551 ------------------------------------------------------------------------------
552 :& :& repeat last ":substitute"
553 :< :< shift lines one 'shiftwidth' left
554 :> :> shift lines one 'shiftwidth' right
555 :copy :co[py] copy lines
556 :cquit :cq[uit] quit Vim with an error code
557 :delete :d[elete] delete lines
558 :exit :exi[t] same as ":xit"
559 :join :j[oin] join lines
560 :move :m[ove] move lines
561 :put :pu[t] insert contents of register in the text
562 :quit :q[uit] quit current window (when one window quit Vim)
563 :quitall :quita[ll] quit Vim
564 :qall :qa[ll] quit Vim
565 :redo :red[o] redo one undone change
566 :substitute :s[ubstitute] find and replace text
567 :t :t same as ":copy"
568 :undo :u[ndo] undo last change(s)
569 :update :up[date] write buffer if modified
570 :write :w[rite] write to a file
571 :wall :wa[ll] write all (changed) buffers
572 :wq :wq write to a file and quit window or Vim
573 :wqall :wqa[ll] write all changed buffers and quit Vim
574 :xit :x[it] write if buffer changed and quit window or Vim
575 :xall :xa[ll] same as ":wqall"
576 :yank :y[ank] yank lines into a register
577 :~ :~ repeat last ":substitute"
578