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