Textový editor Vim jako IDE (11.část: přenos textů mezi Vimem a dalšími aplikacemi)

15. 9. 2011
Doba čtení: 14 minut

Sdílet

V dnešní části seriálu o využití textového editoru Vim (nejenom) ve funkci vývojového prostředí si řekneme, jak je možné přenášet texty mezi Vimem a dalšími aplikacemi. Zatímco ve Windows je k tomuto účelu systémová schránka, v poněkud flexibilnějším X Window Systemu je k dispozici větší množství mechanismů.

Obsah

1. Přenos textů mezi Vimem a dalšími aplikacemi

2. Výběry versus cut-buffery

3. Přenos textů přes výběr PRIMARY (primární výběr)

4. Přenos textů přes výběr CLIPBOARD (schránka)

5. Přenos textů přes cut-buffer

6. Automagické použití primárního výběru (PRIMARY) ve vizuálním režimu, triky pro práci s registry + a *

7. Nastavení registru „*“ nebo „+“ jako implicitního registru pro editační operace

8. Konfigurace chování klávesnice a myši pro snadný přenos textů

9. Odkazy na Internetu

1. Přenos textů mezi Vimem a dalšími aplikacemi

V dnešní části seriálu o textovém editoru Vim si řekneme podrobnější informace o tom, jakým způsobem je možné přenášet části textu mezi Vimem a dalšími aplikacemi, především při spuštění tohoto textového editoru v X Window Systemu příkazem gvim nebo vim -g. V grafickém uživatelském rozhraní operačního systému Microsoft Windows se totiž aplikace při přenosu textů (či dalších dat) chovají poněkud odlišně, protože ve většině případů komunikují přes systémovou schránku (clipboard), zatímco X Window System je v tomto ohledu poněkud flexibilnější a zpočátku možná i matoucí. Již ve čtvrté části tohoto seriálu jsme si popsali takzvané registry, do nichž je možné ukládat bloky textu, popř. příkazy spouštěné jako makra. Tyto příkazy jsou samozřejmě taktéž reprezentovány textovými bloky, o čemž se můžete snadno přesvědčit po záznamu makra pomocí příkazu qx, kde x je jméno registru. Význam těch nejdůležitějších a nejčastěji využívaných registrů je vypsán v následující tabulce:

Registr Význam
a-z registry, které je možné přímo měnit uživatelem
0–9 registry naplňované automaticky příkazy dy
% registr obsahující jméno právě editovaného souboru
: registr obsahující poslední příkaz, vhodné při vyvolání tohoto příkazu jako makra
= pseudoregistr používaný pro výpočet matematických a „řetězcových“ výrazů
/ registr obsahující posledně vyhledávaný řetězec (resp. text odpovídající regulárnímu výrazu)
" implicitní registr pro operace c, d, s nebo y
implicitní registr pro operace, které mění menší část textu, než je jeden textový řádek
. registr obsahující poslední text zapsaný ve vkládacím režimu
   
~ registr obsahující text, který byl do Vimu přenesen pomocí technologie drag and drop
* registr reflektující obsah výběru nazvaného PRIMARY (viz další text)
+ registr reflektující obsah výběru nazvaného CLIPBOARD (viz další text)

2. Výběry versus cut-buffery

Poslední dvojice registrů vypsaná v tabulce zobrazené v předchozí kapitole má speciální význam, protože slouží mj. i k přenosu textů z jiných aplikací do Vimu a samozřejmě i opačným směrem. Tyto registry mají název „*“ (hvězdička) a „+“ (plus). Z jakého důvodu jsou však použity dva registry, když by teoreticky měl dostačovat registr jediný? V X Window Systemu jsou totiž pro přenos textů, popř. i dalších dat, používány hned tři konceptuálně zcela odlišné metody. První metoda spočívá v přenosu textů s využitím pojmenovaných výběrů (selection) [1] [2]. Druhá metoda využívá přenosu textů přes takzvané cut-buffery [3] [4] a metoda třetí využívá technologii drag and drop.

Obrázek 1: Výběr textu v externí aplikaci, konkrétně v Geditu.

Na moderních systémech s grafickým uživatelským rozhraním je převážně používaný přenos textů přes výběry, ovšem textový editor Vim dokáže za určitých okolností pracovat i s cut-buffery (důvod si řekneme v následujícím textu). V X Window Systemu si může každá aplikace vytvořit libovolný počet výběrů (selection), z nichž každý je pojmenován, tj. je jednoznačně identifikován řetězcem (jedná se o vlastnost/property přiřazenou k oknu). Většina aplikací pracuje, podobně jako Vim, s dvojicí výběrů nazvaných PRIMARYCLIPBOARD. V případě cut-bufferů, což jsou vlastnosti vytvořené v kořenovém okně, se většinou používají jména CUT_BUFFER0CUT_BUFFER7, přičemž Vim pracuje pouze s CUT_BUFFER0 (ostatně i mnohé další aplikace se spokojí s jediným cut bufferem, i když jich je možné využívat větší množství). Zatímco s využitím výběrů je možné obecně přenášet různé typy dat (texty, rastrové obrázky, vektorové obrázky atd.), u cut-bufferů je přenos omezen pouze na texty, což souvisí s tím, že aplikace do cut bufferu zapíše data a posléze se již o obsah bufferu nestará (může být dokonce ukončena).

Obrázek 2: Ihned po výběru textu v Geditu je naplněn registr *.

3. Přenos textů přes výběr PRIMARY (primární výběr)

Jak jsme si již řekli v předchozích kapitolách, umožňuje textový editor Vim práci jak s výběry, tak i s nultým cut-bufferem. Základem pro přenos textů je většinou výběr nazvaný PRIMARY, jenž je ve Vimu dostupný přes registr „*“ (hvězdička). Do tohoto výběru je při práci ve většině GUI aplikací zkopírován jakýkoli text vybraný pomocí klávesnice či myši, aniž by bylo nutné explicitně použít nějakou klávesovou zkratku či příkaz Cut/Copy z hlavního nebo kontextového menu. Obsah výběru PRIMARY může být vložen do textových políček libovolné aplikace pomocí prostředního tlačítka myši. Většinou se jedná o nejrychlejší způsob přenosu textu mezi různými aplikacemi, který má ovšem i některé nežádoucí vlastnosti o nichž je dobré vědět. První (diskutabilní) nevýhodou je to, že se výběr PRIMARY přepíše při každém dalším výběru textu. Někdy se jedná o operaci provedenou omylem (přemístění kurzoru s delším podržením tlačítka myši), ovšem v mnoha typech dialogů je automaticky vybrán nějaký text, který výběr PRIMARY přepisuje – viz též následující screenshot.

Obrázek 3: Ukázka situace, kdy je primární výběr automaticky přepsán při zobrazení dialogu s předvyplněným textem.

Druhou nevýhodou, která může v některých případech nemile překvapit, je fakt, že primární výběr (zde je myšlen datový blok „selection“) náleží aplikaci, v níž byl text vybrán, což znamená, že při kopiích textu (prostřední tlačítko myši) musí aplikace, do níž se má text vložit, aktivně komunikovat s aplikací vlastnící výběr PRIMARY. To ovšem v důsledku znamená, že výběr PRIMARY je nenávratně ztracen v případě, že je aplikace, z níž se text kopíruje (=vlastník primárního výběru), ukončena! Toto chování si můžete jednoduše vyzkoušet:

  1. Otevřete libovolnou GUI aplikaci pracující s textem, například Gedit
  2. Napište text a poté ho vyberte myší
  3. Otevřete textový editor Vim příkazem gvim
  4. Příkazem :echo @* zkontrolujte, že je vybraný text z Vimu dostupný
  5. Uzavřete Gedit (nyní tiše dojde ke ztrátě primárního výběru)
  6. Příkaz :echo @* bude nyní vypisovat obsah schránky, nikoli primárního výběru

4. Přenos textů přes výběr CLIPBOARD (schránka)

Textový editor Vim může kromě primárního výběru PRIMARY využívat i výběr nazvaný CLIPBOARD, který se v aplikacích určených pro X Window System používá pro implementaci schránky, což je zajisté patrné již z názvu tohoto výběru. Opět se jedná o výběr vlastněný aplikací, kde byla schránka naplněna, většinou přes kontextové či hlavní menu (jedná se o klasické příkazy CutCopy), popř. o příkazy spuštěné s využitím klávesových zkratek Ctrl+X, Ctrl+C, Ctrl+InsertShift+Delete. Vzhledem k tomu, že se při přenosu dat musí aktivně komunikovat s aplikací, v níž byla schránka naplněna, opět to znamená, že tuto aplikaci není vhodné zavírat před tím, než se text či další data skutečně přes schránku přenesou (zde je chování odlišné od „skutečné“, na aplikacích nezávislé schránce). Výběr CLIPBOARD odpovídá ve Vimu registru „+“, což znamená, že je například možné měnit obsah schránky uvnitř maker nebo skriptů:

Vymazání řádku s jeho vložením do schránky:

"+dd

Programová změna obsahu schránky:

:let @+="odpoved je " . 2*3*7

Pokud se registr + použije pro přenos textů mezi několika běžícími instancemi Vimu, bude společně s textem korektně přenesena i informace o tom, jakým způsobem byt text vybrán, tj. zda byl proveden normální výběr, výběr celých řádků nebo sloupcový výběr. To je důležité především při použití sloupcového výběru, například při kopiích dat mezi tabulkami apod. Můžeme si vyzkoušet jednoduchý příklad:

Začátek sloupcového výběru:

Ctrl+V
"+y

V další instanci Vimu:

"+p

nebo:

"+P

Další aplikace (kromě instancí Vimu) informaci o režimu výběru textu nevyužívají. Některé další možnosti, které nám textový editor Vim nabízí pro práci se schránkou (a.k.a. registrem „+“) si ukážeme v šesté a sedmé kapitole.

5. Přenos textů přes cut-buffer

Jak jsme si již řekli v úvodních odstavcích, dokáže Vim pracovat nejenom s výběry CLIPBOARDPRIMARY, ale i s cut-bufferem. Vzhledem k tomu, že se obsah výběrů ztratí při ukončení aplikace, která tyto výběry vlastní, jsou cut-buffery ve Vimu použity jako určitá poslední záchrana. V praxi to znamená to, že přímo ve Vimu je při jeho ukončení uložen obsah schránky (pokud ji ovšem Vim vlastní) do prvního cut-bufferu (prvním cut-bufferem je zde myšlen buffer s indexem 0, tj. vlastnost kořenového okna pojmenovaná CUT_BUFFER0). V případě, že Vim obsah schránky nevlastní, je do prvního cut-bufferu uložen obsah primárního výběru. Díky tomuto chování se Vim snaží na poslední chvíli zachránit text, který by jinak mohl být nenávratně ztracen (podobně defenzivně se ostatně tento textový editor chová ke svému swapovacímu souboru, který je z mnoha hledisek mnohem výhodnější, než pouhé záložní kopie).

První cut-buffer se taktéž využije v případě, že Vim buď nedokáže získat obsah primárního výběru ani schránky, popř. získá pouze prázdný obsah. V těchto případech Vim tiše předpokládá, že aplikace, která výběry vlastnila, byla ukončena, takže se alespoň pokusí získat data z cut-bufferu. Jelikož se některé aplikace při svém ukončení chovají stejně jako Vim, je určitá šance na to, že cut-buffer bude požadovaný text skutečně obsahovat.

Poznámka: pro kopie textů mezi primárním výběrem a prvním cut-bufferem je možné použít nástroj nazvaný xcutsel, který bývá součástí instalace X Window Systemu. Viz též xcutsel(1) – Linux man page.

6. Automagické použití primárního výběru (PRIMARY) ve vizuálním režimu, triky pro práci s registry + a *

Již v úvodních částech tohoto seriálu jsme si řekli, že při provádění běžných editačních operací typu d (delete), y (yank), c (change) či p (put) se implicitně využívá registr pojmenovaný " (uvozovky). V případě, že je nutné přenášet text mezi Vimem a nějakou další aplikací, je tedy nutné explicitně specifikovat registr * (primární výběr) nebo + (schránku), což je ukázáno na následujících příkladech.

Vymazání celého řádku a jeho vložení do primárního výběru (selection):

"*dd

Vložení obsahu, schránky naplněné třeba i nějakou externí aplikací, do textu za pozici textového kurzoru:

"+p

Zkopírování celého odstavce (operátor ap=a paragraph) do primárního výběru:

"*yap

Většina ostatních desktopových aplikací však pracuje s primárním výběrem a/nebo schránkou přímo, tj. nevyužívá své speciální (privátní) registry. Při rozsáhlých možnostech konfigurace textového editoru Vim však pravděpodobně nikoho nepřekvapí, že je možné chování tohoto editoru změnit tak, aby se začal podobat ostatním aplikacím, tj. aby v případě, že uživatel sám explicitně nezadá jiný registr, byl použit buď primární výběr a/nebo schránka. Prvním přiblížením k tomuto stavu je hodnota a přidaná do konfiguračního parametru guioptions:

:set guioptions+=a

V případě, že je tato volba použita, bude text vybraný ve vizuálním režimu, tj. pomocí příkazů v, V a Ctrl+V automaticky zkopírován do systémového primárního výběru, tj. bude ho možné ihned vložit do další aplikace, většinou pomocí prostředního tlačítka myši. Současně začne korektně pracovat i výběr pomocí myši se stlačeným levým tlačítkem, tj. i v tomto případě bude Vim automaticky vkládat vybraný text do systémového primárního výběru.

Alternativně je možné namísto hodnoty a použít hodnotu A:

:set guioptions-=a
:set guioptions+=A

V tomto případě se bude do primárního výběru automaticky kopírovat pouze text vybraný pomocí myši se stlačeným levým tlačítkem, nikoli však text označený ve vizuálním režimu (v, V, Ctrl+V).

Obrázek 4: Výpis obsahu primárního výběru pomocí klávesové zkratky Ctrl+F11.

Vzhledem k tomu, že v některých případech nemusí být zcela jasné, zda se přenášený text nachází v primárním výběru nebo ve schránce, může být výhodné si obsah obou registrů spojených s těmito výběry nějakým způsobem vypsat. Jednu z možností samozřejmě představuje příkaz :reg, ale je možné taktéž vytvořit nové klávesové zkratky pro výpis obsahu jednoho z těchto registrů spolu s informací o tom, jak se daný výběr jmenuje (PRIMARY/CLIPBOARD):

" nove klavesove zkratky Ctrl+F11 a Ctrl+F12
map <C-F11> :echo "*** PRIMARY *** " . @*<cr>
map <C-F12> :echo "*** CLIPBOARD *** " . @+<cr>

Osobně považuji tyto klávesové zkratky za mnohem užitečnější, než různé externí aplikace pro zobrazení obsahu schránky.

Obrázek 5: Výpis obsahu schránky pomocí klávesové zkratky Ctrl+F12.

7. Nastavení registru „*“ nebo „+“ jako implicitního registru pro editační operace

Kromě volby :set guioptions=a je možné textový editor Vim nakonfigurovat takovým způsobem, aby se registr * (primární výběr) používal jako implicitní registr pro všechny běžné editační operace typu d (delete), y (yank), c (change) či p (put). Tohoto chování lze docílit velmi jednoduše – postačuje použít následující příkaz:

:set clipboard=unnamed

Toto nastavení má přibližně podobný význam, jako by byla použita sekvence mapování původních editačních příkazů na editační příkazy, před nimiž je uvedeno jméno registru (*), které se má použít:

:noremap d "*d
:noremap dd "*dd
:noremap D "*d$
:noremap y "*y
:noremap y "*y
:noremap Y "*Y
:noremap yy "*yy
atd.

Zajímavé je, že nastavení clipboard=unnamed bude pracovat i ve Vimu spuštěném v terminálu, ovšem pouze za předpokladu, že byl Vim přeložen s volbami +clipboard a +xterm_clipboard. Možnosti Vimu nastavené v době překladu lze získat pomocí příkazu:

:version

Obrázek 6: Textový editor Vim verze 7.2 ještě nepodporuje volbu :set clipboard=unnamedplus.

V novějších verzích textového editoru Vim, konkrétně od verze vim-7.3.74, je navíc možné pomocí volby:

:set clipboard=unnamedplus

nastavit registr „+“ (tj. schránku) jako implicitní registr pro provádění veškerých editačních operací. Pokud vám toto chování vyhovuje, ale nemáte nainstalovánu dostatečně aktuální verzi Vimu, je možné se uchýlit k triku s mapováním uvedeném výše, tentokrát samozřejmě s využitím registru „+“:

:noremap d "+d
:noremap dd "+dd
:noremap D "+d$
:noremap y "+y
:noremap y "+y
:noremap Y "+Y
:noremap yy "+yy
atd.

Obrázek 7: Při pokusu o nastavení volby :set clipboard=unnamedplus ve Vimu verze 7.2 se vypíše chybové hlášení.

8. Konfigurace chování klávesnice a myši pro snadný přenos textů

Mnoho uživatelů při práci s textovým editorem očekává, že se při posunu v textu pomocí kurzorových kláves společně se stlačeným modifikátorem Shift začne vybírat blok. Ve Vimu, který má implicitně na klávesové zkratky Shift+kurzorové šipky namapován horizontální posun kurzoru po slovech a vertikální posun po stránkách, je možné alternativní chování povolit pomocí příkazu:

:set keymodel=startsel,stopsel

Tímto způsobem však není možné zvolit výběr celých řádků, popřípadě výběr sloupcových bloků.

Mezi další vlastnost textového editoru Vim, kterou je možné ovlivnit, patří chování pravého tlačítka myši. To může sloužit buď k zobrazení kontextového menu, nebo ho lze použít pro rozšíření výběru od původní pozice textového kurzoru k místu, kde se nachází kurzor myši v době stlačení pravého tlačítka. Toto chování se nastavuje konfiguračním parametrem mousemodel:

" povolení zobrazení kontextového menu
:set mousemodel=popup
" rozšíření výběru po stlačení pravého tlačítka myši
:set mousemodel=extend

Obrázek 8: Textový editor Vim verze 7.3 již volbu :set clipboard=unnamedplus podporuje.

Namísto předchozích dvou konfiguračních parametrů keymodelmousemodel je možné využít i „globální přepínač“ reprezentovaný příkazem (nikoli konfiguračním parametrem!) behave. Parametrem tohoto příkazu je buď xterm nebo mswin:

:behave xterm
:behave mswin

Tento „globální přepínač“ ve skutečnosti ovlivňuje čtyři konfigurační parametry vypsané v tabulce níže:

bitcoin_skoleni

Parametr :behave mswin :behave xterm
selectmode mouse,key ""
mousemodel popup extend
keymodel startsel,stopsel ""
selection exclusive inclusive

Konfiguračním parametrem selectmode se určuje, ve kterých případech se použije režim výběru (selection) a ve kterých vizuální režim (visual).

Obrázek 9: Bezproblémové nastavení volby :set clipboard=unnamedplus ve Vimu 7.3.

9. Odkazy na Internetu

  1. X Selections, Cut Buffers, and Kill Rings
    http://www.jwz.org/doc/x-cut-and-paste.html
  2. Accessing the system clipboard
    http://vim.wikia.com/wiki/Ac­cessing_the_system_clipbo­ard
  3. xcutsel(1) – Linux man page
    http://linux.die.net/man/1/xcutsel
  4. snipMate : TextMate-style snippets for Vim
    http://www.vim.org/scripts/scrip­t.php?script_id=2540
  5. msanders / snipmate.vim
    https://github.com/msander­s/snipmate.vim
  6. snipMate.vim Introductory Screencast
    http://vimeo.com/3535418
  7. Clewn home page
    http://clewn.sourceforge.net/
  8. How to connect vim with gdb – using clewn
    http://chunhao.net/blog/how-to-connect-vim-with-gdb-using-clewn
  9. yavdb : Yet Another (Generic) Vim Debugger Integration
    http://www.vim.org/scripts/scrip­t.php?script_id=1954
  10. Vim home page
    http://www.vim.org/
  11. Exuberant ctags
    http://ctags.sourceforge.net/
  12. xxd (man page)
    http://www.linux-tutorial.info/modules.php?na­me=ManPage&sec=1&manpage=xxd
  13. vim (man page)
    http://www.linux-tutorial.info/modules.php?na­me=ManPage&sec=1&manpage=vim
  14. ctags (man page)
    http://www.linux-tutorial.info/modules.php?na­me=ManPage&sec=1&manpage=ctags
  15. cscope (man page)
    http://www.linux-tutorial.info/modules.php?na­me=ManPage&sec=1&manpage=csco­pe
  16. Tutorial: Make Vim as Your C/C++ IDE Using c.vim Plugin
    http://www.thegeekstuff.com/2009/01/tu­torial-make-vim-as-your-cc-ide-using-cvim-plugin/
  17. c.vim : C/C++ IDE
    http://vim.sourceforge.net/scrip­ts/script.php?script_id=213
  18. c.vim : C/C++ IDE key mappings
    http://lug.fh-swf.de/vim/vim-c/c-hotkeys.pdf
  19. Základní základy editoru Vim
    http://www.root.cz/clanky/zakladni-zaklady-editoru-vim/
  20. Jak si přizpůsobit Vim
    http://www.root.cz/serialy/jak-si-prizpusobit-vim/
  21. Novinky ve VIM 7: Úvodní část – speller
    http://www.root.cz/vim-sedm-prvni-cast/
  22. Novinky ve VIM 7: Skriptovací jazyk
    http://www.root.cz/vim-sedm-druha-cast/
  23. vim2elvis: Přednosti a nedostaky Elvise v porovnání s Vimem
    http://www.root.cz/clanky/vim2elvis-1/
  24. vim2elvis: Shodné znaky mezi Elvisem a Vimem, nastaveníeditoru
    http://www.root.cz/clanky/vim2elvis-2/
  25. Nej… VIM pluginy (1)
    http://www.root.cz/clanky/nej-vim-pluginy/
  26. Taglist (plugin)
    http://www.vim.org/scripts/scrip­t.php?script_id=273
  27. The NERD tree: A tree explorer plugin for navigating the filesystem
    http://www.vim.org/scripts/scrip­t.php?script_id=1658
  28. JavaBrowser : Shows java file class, package in a tree as in IDEs. Java source browser.
    http://www.vim.org/scripts/scrip­t.php?script_id=588
  29. snippetsEmu : An attempt to emulate TextMate's snippet expansion
    http://www.vim.org/scripts/scrip­t.php?script_id=1318
  30. Scroll Lock (Necyklopedie)
    http://necyklopedie.wikia­.com/wiki/Scroll_lock
  31. Caps Lock (Necyklopedie)
    http://necyklopedie.wikia­.com/wiki/Caps_Lock
  32. Avoid the escape key
    http://vim.wikia.com/wiki/A­void_the_escape_key
  33. Map caps lock to escape in XWindows
    http://vim.wikia.com/wiki/VimTip166

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.