Warum vi(m)?
vi ist der Texteditor, der sich auf wirklich jedem Unix-System findet - egal ob AIX, Solaris, HP-UX oder jedes beliebige Linux: Man kann sich (mit mindestens 99,9%iger Wahrscheinlichkeit) darauf verlassen, dass vi bereits im Grundsystem installiert ist. Die grundegende Bedienung sollte also jeder beherrschen, der mit Unix-artigen Betriebssystemen zu tun hat, denn damit kommt man immer weiter (z. B. um Konfigurationsdateien anzupassen).
vim (Vi IMproved) ist darüber hinaus ein extrem leistungsfähiger Texteditor. Er kann zumindest auf jedem Linux und darüber hinaus auf vielen anderen Unix-artigen Betriebssystemen nachinstalliert werden. Die Bedienung von beiden ist im Grunde weitgehend gleich, vim bietet einfach nur mehr Funktionen.
Einstieg in vim
Während man viele grafische Editoren einfach dadurch erlernen kann, dass man sie startet und in den vorhandenen Menüs die verschiedenen Funktionen anklickt, erfordert vim, dass man sich am Anfang zumindest einmal grundlegend mit seinen Funktionen beschäftigt. Es gibt sehr viele vim Einsteiger-Tutorials im Internet. Sehr gut gemacht ist aber auch das von vim mitgelieferte Tutorial "vimtutor". Viele Distributionen installieren vimtutor gleich mit, wenn man vim installiert, sonst in der Paketverwaltung danach suchen.
Einfach
vimtutor
auf der Kommmandozeile eingeben und das Tutorial startet.
Ich will nicht bei Adam und Eva anfangen und alles nochmal schreiben, was schon oft und gut beschrieben wurde, daher gehe ich im folgenden davon aus, dass die absoluten Basics von vim bekannt sind, d. h. dass Ihr z. B. den vimtutor schon mal durchgearbeitet habt.
The power of vim
Richtig eingesetzt kann vim viele Aufgaben schneller, effektiver und weniger fehleranfällig erledigen als andere Texteditoren - egal ob man damit jetzt einfache Texte, LaTeX, HTML, CSS, AsciiDoc oder Quellcode der verschiedensten Programmier- und Scriptsprachen bearbeitet.
Dazu sollte man einerseits ein paar nützliche Einstellungen vornehmen (normalerweise in ~/.vimrc) und andererseits ein paar interessante Befehle und Tastenkombinationen kennen. Ich habe mich dazu entschlossen, die beiden Dinge nicht in zwei unterschiedliche Files zu packen, sondern in ein gemeinsames. Damit kann man sich die .vimrc runterladen und in sein Home-Verzeichnis packen. Von dort läd vim die Einstellungen und man kann dort auch schnell mal nachschauen, wenn man einen Befehl sucht - sogar direkt von vim aus und ohne das aktuelle Dokument zu verlassen, z. B. mit
:tabnew ~/.vimrc
Gerade zum Nachschlagen ist es bestimmt nützlich, dass die einzelnen Abschnitte in vim auf- und zugeklappt werden können.
Berny’s vimrc nutzen
Meine vimrc steht zum Download zur Verfügung unter http://pub.stroessenreuther.info/vimrc/vimrc und muss direkt in Eurem Homeverzeichnis als .vimrc abgelegt werden. Das bekommt Ihr am einfachsten hin mit:
wget -O ~/.vimrc http://pub.stroessenreuther.info/vimrc/vimrc
Vorsicht:
Wenn Ihr Euch schon eine .vimrc angelegt habt, mit eigenen Inhalten, wollt Ihr diese vielleicht vorher wegsichern. |
Wer meine vimrc nutzt, hat dazu grundsätzlich zwei Möglichkeiten:
Berny’s vimrc als Vorlage
Ihr könnt meine vimrc einfach als "Inspiration" nutzen, diese also einmalig runterladen und so lange anpassen, bis Eure eigene vimrc daraus geworden ist, mit allen Einstellungen, die Euch persönlich am besten gefallen.
Berny’s vimrc immer aktuell
Meine vimrc includiert am Ende eine Datei
~/.vimrc.local
Damit habt Ihr prinzipiell auch die Möglichkeit, Eure persönlichen Einstellungen in dieser Datei vorzunehmen und meine vimrc unverändert zu lassen. Das bietet Euch die Chance, später eine aktualisierte Version meiner vimrc runterzuladen, ohne dass Eure persönlichen Einstellungen verloren gehen. Da .vimrc.local immer ganz am Ende geladen wird, gelten im Zweifelsfall die Einstellungen die da drin stehen (sie überschreiben bei Bedarf die Werte aus meiner vimrc).
Berny’s vimrc
Hier schon mal zum vorab lesen:
" .--pathogen------------------------------------------------------------. " | _ _ | " | _ __ __ _| |_| |__ ___ __ _ ___ _ __ | " | | '_ \ / _` | __| '_ \ / _ \ / _` |/ _ \ '_ \ | " | | |_) | (_| | |_| | | | (_) | (_| | __/ | | | | " | | .__/ \__,_|\__|_| |_|\___/ \__, |\___|_| |_| | " | |_| |___/ | " '----------------------------------------------------------------------' " pathogen (https://github.com/tpope/vim-pathogen) " uses ~/.vim/autoload and ~/.vim/bundle for easy installation of addons if filereadable($HOME . "/.vim/autoload/pathogen.vim") execute pathogen#infect() endif "#. " .--tabs + trailing characters------------------------------------------. " | _ _ _ _ _ _ | " | | |_ __ _| |__ ___ _ | |_ _ __ __ _(_) (_)_ __ __ _ | " | | __/ _` | '_ \/ __| _| |_ | __| '__/ _` | | | | '_ \ / _` | | " | | || (_| | |_) \__ \ |_ _| | |_| | | (_| | | | | | | | (_| | | " | \__\__,_|_.__/|___/ |_| \__|_| \__,_|_|_|_|_| |_|\__, | | " | |___/ | " '----------------------------------------------------------------------' " put 4 blanks when typing tab set expandtab set tabstop=4 set shiftwidth=4 " use: " :retab to convert all literal tabs to blanks according to the current " settings (e. g. like above) " make the settings (about tabs and trailing characters) below work on every encoding " according to " http://stackoverflow.com/questions/18321538/vim-error-e474-invalid-argument-listchars-tab-trail scriptencoding utf-8 set encoding=utf-8 " Show tabs and trailing characters. "set listchars=tab:»·,trail:·,eol:¬ set listchars=tab:»·,trail:· set list "#. " .--autocommands (asciidoc syntax highlighting, puppet-lint as make cmd). " | _ _ | " | __ _ _ _| |_ ___ ___ _ __ ___ __| | | " | / _` | | | | __/ _ \ / __| '_ ` _ \ / _` | | " | | (_| | |_| | || (_) | (__| | | | | | (_| | | " | \__,_|\__,_|\__\___/ \___|_| |_| |_|\__,_| | " '----------------------------------------------------------------------' " define syntax highlighting for asciidoc files autocmd BufRead,BufNewFile *.ad,*.asciidoc \ setlocal autoindent expandtab tabstop=8 softtabstop=2 shiftwidth=2 filetype=asciidoc \ textwidth=70 wrap formatoptions=tcqn \ formatlistpat=^\\s*\\d\\+\\.\\s\\+\\\\|^\\s*<\\d\\+>\\s\\+\\\\|^\\s*[a-zA-Z.]\\.\\s\\+\\\\|^\\s*[ivxIVX]\\+\\.\\s\\+ \ comments=s1:/*,ex:*/,://,b:#,:%,:XCOMM,fb:-,fb:*,fb:+,fb:.,fb:> " use puppet-lint as make command for puppet files " put results into the quickfix list (by defining it's format as errorformat) autocmd FileType puppet \ setlocal makeprg=puppet-lint\ --with-filename\ % \ errorformat=%f\ -\ %m\ on\ line\ %l " type in *.pp files " :make to execute puppet-lint on the current file " (jumps to the line of first ERROR or WARNING) " :cn(ext) / :cp(rev) to jump to the next / previous " :cnf(ile) to jump to the first match in the next file " :cpf(ile) to jump to the last match in the previous file " :cfirst / :clast to jump to the first / last " :copen / :cclose open / close a window showing the complete quickfix list " <CR> in this window jumps to the given line " " see section 'split window' below on how to jump " between quickfix window and the window with your code "#. " .--autocomplete--------------------------------------------------------. " | _ _ _ | " | __ _ _ _| |_ ___ ___ ___ _ __ ___ _ __ | | ___| |_ ___ | " | / _` | | | | __/ _ \ / __/ _ \| '_ ` _ \| '_ \| |/ _ \ __/ _ \ | " | | (_| | |_| | || (_) | (_| (_) | | | | | | |_) | | __/ || __/ | " | \__,_|\__,_|\__\___/ \___\___/|_| |_| |_| .__/|_|\___|\__\___| | " | |_| | " '----------------------------------------------------------------------' " For autocompletion always use content of ~/.vimdictionary too. " You might want to put any word into this file you always want to have " available for autocompletion. Depends on what kind of files you edit often. " If you e. g. often edit Puppet classes maybe put Puppet's keywords here. set dictionary=~/.vimdictionary set complete+=k " use <Ctrl-n> or <Ctrl-p> to navigate " <Ctrl-e> to abort "#. " .--block folding-------------------------------------------------------. " | _ _ _ __ _ _ _ | " | | |__ | | ___ ___| | __ / _| ___ | | __| (_)_ __ __ _ | " | | '_ \| |/ _ \ / __| |/ / | |_ / _ \| |/ _` | | '_ \ / _` | | " | | |_) | | (_) | (__| < | _| (_) | | (_| | | | | | (_| | | " | |_.__/|_|\___/ \___|_|\_\ |_| \___/|_|\__,_|_|_| |_|\__, | | " | |___/ | " '----------------------------------------------------------------------' " Start block with .-- end block with #. " You might want to use the figheader script " (http://git.mathias-kettner.de/git/?p=check_mk.git;a=blob;f=doc/helpers/figheader) " for this, like I did for producing the paragraph headings in this file. set foldmethod=marker set foldmarker=.--,#. " type za to fold/unfold one block " zR to unfold all blocks, zM to fold all "#. " .--macros and shortcuts------------------------------------------------. " | _ __ ___ __ _ ___ _ __ ___ ___ | " | | '_ ` _ \ / _` |/ __| '__/ _ \/ __| | " | | | | | | | (_| | (__| | | (_) \__ \ | " | |_| |_| |_|\__,_|\___|_| \___/|___/ | " '----------------------------------------------------------------------' " Insert prepared textblocks. " For this to work you need a script called textblock in your PATH, " that just prints the wanted textblock to STDOUT. The makros read them " into the current file (at cursor position). let @h=':r !textblock puppet-header ' let @x=':r !textblock puppet-header-xml ' let @f=':r !textblock puppet-file ' let @d=':r !textblock puppet-dir ' let @l=':r !textblock puppet-link ' let @s=':r !textblock puppet-service ' let @e=':r !textblock puppet-exec ' " record macros " qa<keys to record>q to record macro a " (you may use other letters for more macros) " @a to replay macro a " qA<keys to record>q to append more keys to macro a " (with lower case a it would be overwritten) " switch paste mode on and off set pastetoggle=<f5> "#. " .--split window--------------------------------------------------------. " | _ _ _ _ _ | " | ___ _ __ | (_) |_ __ _(_)_ __ __| | _____ __ | " | / __| '_ \| | | __| \ \ /\ / / | '_ \ / _` |/ _ \ \ /\ / / | " | \__ \ |_) | | | |_ \ V V /| | | | | (_| | (_) \ V V / | " | |___/ .__/|_|_|\__| \_/\_/ |_|_| |_|\__,_|\___/ \_/\_/ | " | |_| | " '----------------------------------------------------------------------' " <Ctrl-w>s split horizontal " :split split horizontal " :split <file> split horizontal and load <file> " <Ctrl-w>v split vertical " :vsplit split vertical " :vsplit <file> split vertical and load <file> " <Ctrl-w>w or <Ctrl-w><Ctrl-w> to switch between windows " <Ctrl-w>h one window left " <Ctrl-w>j one window down " <Ctrl-w>k one window up " <Ctrl-w>l one window right " <Ctrl-w>_ maximum height for current window " <Ctrl-w>| maximum width for current window " <Ctrl-w>= equal size for all windows "#. " .--tabbed view---------------------------------------------------------. " | _ _ _ _ _ | " | | |_ __ _| |__ | |__ ___ __| | __ _(_) _____ __ | " | | __/ _` | '_ \| '_ \ / _ \/ _` | \ \ / / |/ _ \ \ /\ / / | " | | || (_| | |_) | |_) | __/ (_| | \ V /| | __/\ V V / | " | \__\__,_|_.__/|_.__/ \___|\__,_| \_/ |_|\___| \_/\_/ | " '----------------------------------------------------------------------' " :tabnew <file> open a new tab and load <file> " gt to switch to next tab " gT to switch to previous tab " vim -p <file1> <file2> ... to start vim with each file in one tab "#. " .--colours-------------------------------------------------------------. " | _ | " | ___ ___ | | ___ _ _ _ __ ___ | " | / __/ _ \| |/ _ \| | | | '__/ __| | " | | (_| (_) | | (_) | |_| | | \__ \ | " | \___\___/|_|\___/ \__,_|_| |___/ | " '----------------------------------------------------------------------' set background=light syntax on " color settings for autocomplete menu " refer to http://vim.wikia.com/wiki/VimTip634 " section 'Color numbers for xterm and gvim' " for selecting colors " and http://vimdoc.sourceforge.net/htmldoc/syntax.html " for the items (Pmenu, PmenuSel, ...) highlight Pmenu ctermfg=0 ctermbg=3 gui=bold highlight PmenuSel ctermfg=8 ctermbg=4 gui=bold " Colored or not colored " If you want color you should set this to true let color = "true" if has("syntax") if color == "true" " This will switch colors ON so ${VIMRUNTIME}/syntax/syntax.vim else " this switches colors OFF syntax off set t_Co=0 endif endif "#. " .--misc----------------------------------------------------------------. " | _ | " | _ __ ___ (_)___ ___ | " | | '_ ` _ \| / __|/ __| | " | | | | | | | \__ \ (__ | " | |_| |_| |_|_|___/\___| | " '----------------------------------------------------------------------' " We use a vim (and not good old vi) and want to really use vim's features set nocompatible " when using tab completion on ex commands: show list of possible completions set wildmenu set wildmode=full " keep more than default of 20 entries in the history of ex commands set history=100 " do not activate visual mode on mouse selection set mouse-=a "#. " .--movements-----------------------------------------------------------. " | _ | " | _ __ ___ _____ _____ _ __ ___ ___ _ __ | |_ ___ | " | | '_ ` _ \ / _ \ \ / / _ \ '_ ` _ \ / _ \ '_ \| __/ __| | " | | | | | | | (_) \ V / __/ | | | | | __/ | | | |_\__ \ | " | |_| |_| |_|\___/ \_/ \___|_| |_| |_|\___|_| |_|\__|___/ | " '----------------------------------------------------------------------' " h/j/k/l left/down/up/right one character / one line " w/W next word / WORD " b/B back one word / WORD " e/E end of current word / WORD " where "WORD" includes punctuation, while "word" does not " f<Character> jump to next occurance of <Character> in current line " F<Character> jump to previous occurance of <Character> in current line " ; repeat search in same direction " , repeat search in oposit direction " g; jump to the position of last change (can be used multiple times) " g, jump backward " gi jump to the position of last insert and change to insert mode " gf (goto file): open file with filename under the cursor, " <Ctrl-o> to return to original file " m[a-zA-Z] set mark " '[a-zA-Z] jump back to mark " where marks [a-z] are per buffer and [A-Z] are global " % jump to matching brace - works with () [] and {} "#. " .--tipps + tricks------------------------------------------------------. " | _ _ _ _ _ | " | | |_(_)_ __ _ __ ___ _ | |_ _ __(_) ___| | _____ | " | | __| | '_ \| '_ \/ __| _| |_ | __| '__| |/ __| |/ / __| | " | | |_| | |_) | |_) \__ \ |_ _| | |_| | | | (__| <\__ \ | " | \__|_| .__/| .__/|___/ |_| \__|_| |_|\___|_|\_\___/ | " | |_| |_| | " '----------------------------------------------------------------------' " <Ctrl-g> show info about current file " gv re-select the last visual selection " zt puts current line to top of screen " z. or zz puts current line to center of screen " zb puts current line to bottom of screen " daw delete one word " ciw change one word " with " iw current word only " aw current word + one space " iW / aW current WORD " is / aS current sentence " ip / ap current paragraph only / + one blank line "#. " .--netrw---------------------------------------------------------------. " | _ | " | _ __ ___| |_ _ ____ __ | " | | '_ \ / _ \ __| '__\ \ /\ / / | " | | | | | __/ |_| | \ V V / | " | |_| |_|\___|\__|_| \_/\_/ | " | | " '----------------------------------------------------------------------' " you can use vim with netrw plugin to edit files on a remote system " (included directory browsing) " # start browsing in your HOME directory " vim scp://remotehost.example.com/ " # start browsing in root directory " vim scp://remotehost.example.com// " # edit a concrete file " # (in this case: relative to HOME) " vim scp://remotehost.example.com/data/test.txt "#. " .--copy & paste--------------------------------------------------------. " | ___ _ | " | ___ ___ _ __ _ _ ( _ ) _ __ __ _ ___| |_ ___ | " | / __/ _ \| '_ \| | | | / _ \/\ | '_ \ / _` / __| __/ _ \ | " | | (_| (_) | |_) | |_| | | (_> < | |_) | (_| \__ \ || __/ | " | \___\___/| .__/ \__, | \___/\/ | .__/ \__,_|___/\__\___| | " | |_| |___/ |_| | " '----------------------------------------------------------------------' " normally yy, dd, p use the unamed register, also known as " " prefix with "<register> to use named register <register> " e. g. "ayy " and later "ap " ""yy is the same as yy because unnamed register is " " "_ is the black whole register " therefor "_dd really deletes " (and does not cut the line into the unnamed register) " "0 is the copy register: it is only filled while yank (y) " actions, not while d, x or c " therefor "0p pastes what you copied, even if you did e. g. delete " action (dd, ...) in the mean time " "+ represents the system clipboard " "* represents the X11 mouse clipboard " "% always contains the name of the current file (read only) " :reg lists content of all registers " <Ctrl-r><register> pastes in insert mode " <Ctrl-r>" pastes unnamed register " <Ctrl-r>0 pastes copy register "#. " .--search/replace------------------------------------------------------. " | _ __ _ | " | ___ ___ __ _ _ __ ___| |__ / / __ ___ _ __ | | __ _ ___ ___ | " | / __|/ _ \/ _` | '__/ __| '_ \ / / '__/ _ \ '_ \| |/ _` |/ __/ _ \ | " | \__ \ __/ (_| | | | (__| | | |/ /| | | __/ |_) | | (_| | (_| __/ | " | |___/\___|\__,_|_| \___|_| |_/_/ |_| \___| .__/|_|\__,_|\___\___| | " | |_| | " '----------------------------------------------------------------------' " highlight all search results set hlsearch " :noh or :nohlsearch to temporary disable highlighting " (until next search) " show first hit while typing the search string set incsearch " star (*) and hash (#) in visual mode do a search for the visual selection xnoremap * :<C-u>call <SID>VSetSearch()<CR>/<C-R>=@/<CR><CR> xnoremap # :<C-u>call <SID>VSetSearch()<CR>?<C-R>=@/<CR><CR> function! s:VSetSearch() let temp = @s norm! gv"sy let @/ = '\V' . substitute(escape(@s, '/\'), '\n', '\\n', 'g') let @s = temp endfunction " /\v<regex> Search term is used as (mostly like Perl style) regex " braces () and curly braces {} have special meanings " with \v you might want to use: " \d instead of [0-9] " \a instaed of [A-Za-z] " \l instead of [a-z] " \u instaed of [A-Z] " and see " :h /character-classes " for more predefined character classes " /\V<literal text> Search term is used literally " no character has a special meaning except backslash \ " especially: dot . means a literal dot, " not 'any character' " :s/<source>/<target>/<flags> " with flags in " g global (replace all matches, not only the first " in the line " c ask for every match befor replacing it " while being asked you have the following answer " possibilities " y yes, replace this one " n no, do not replace this one " q quit " l last - replace this one and quit " a all - replace this one and all further " intelligent guess if search should be case sensitiv or not " if searchpattern includes upper case letters: search case sensitive " if not: search case insensitive set ignorecase set smartcase " /\c<search string> explicitly search case insensitive " /\C<search string> explicitly search case sensitive "#. " .--(vim)grep-----------------------------------------------------------. " | __ _ __ | " | / /_ _(_)_ __ ___\ \ __ _ _ __ ___ _ __ | " | | |\ \ / / | '_ ` _ \| |/ _` | '__/ _ \ '_ \ | " | | | \ V /| | | | | | | | (_| | | | __/ |_) | | " | | | \_/ |_|_| |_| |_| |\__, |_| \___| .__/ | " | \_\ /_/ |___/ |_| | " '----------------------------------------------------------------------' " :g/<string>/d delete all lines matching <string> " (think of g like grep) " :v/<string>/d delete all lines NOT matching <string> " (think of v like grep -v) " " for patterns in <string> see section " 'search/replace' above " :grep <string> * uses external grep command to find <string> " :grep <string> **/*.txt in all given files, opens matching files in vim " and adds matching lines to the quickfix list " " :grep -v <string> * same with non matching lines " :vim[grep] /<string>/[g] * internal vim function working similar, but with " vim style search patterns " g multiple entries in the quickfix list if " there is more than one match in one line " on how to navigate in the quickfix list see section autocmd above "#. " .--.vimrc.local--------------------------------------------------------. " | _ _ _ | " | __ _(_)_ __ ___ _ __ ___ | | ___ ___ __ _| | | " | \ \ / / | '_ ` _ \| '__/ __| | |/ _ \ / __/ _` | | | " | \ V /| | | | | | | | | (__ _| | (_) | (_| (_| | | | " | (_)_/ |_|_| |_| |_|_| \___(_)_|\___/ \___\__,_|_| | " '----------------------------------------------------------------------' " in ~/.vimrc.local you can do your own or local settings " e. g. not managed by Puppet if filereadable($HOME . "/.vimrc.local") source ~/.vimrc.local endif "#. " vim:filetype=vim