Hlavní navigace

Textový editor Vim jako IDE (3.část)

Pavel Tišnovský

Ve třetí části seriálu o použití textového editoru Vim (nejenom) ve funkci vývojového prostředí si připomeneme, které příkazy lze využít při editaci zdrojových kódů, jak lze odsazovat bloky zdrojového kódu a posléze si popíšeme relativně novou funkci Vimu – technologii „omni completion“. Na závěr si řekneme, jak lze přímo ve Vimu vytvořit ze zdrojových kódů HTML stránku obsahující program se zvýrazněním syntaxe.

Obsah

1. Příkazy určené pro editaci zdrojových kódů

2. Využití příkazu %

3. Odsazení bloků ve zdrojovém kódu

4. Nastavení parametrů shiftwidth a cinoptions

5. Omni completion – nová vlastnost Vimu 7

6. Využití omni completion při vývoji v jazyku C

7. Využití omni completion při editaci HTML, XHTML a XML

8. Vytvoření HTML stránky s obarveným zdrojovým kódem

9. Odkazy na Internetu

1. Příkazy určené pro editaci zdrojových kódů

„vi is small, fast, and easy to use. Emacs is huge, slow and easy to use :)“

V předchozí části seriálu o textovém editoru Vim jsme si kromě dalších informací stručně popsali některé přídavné moduly určené pro zjednodušení a současně i urychlení vývoje v různých programovacích jazycích (ostatně síla Vimu se ukáže právě ve chvíli, kdy se tento textový editor použije pro vývoj projektu, v němž se pracuje s větším množstvím programovacích jazyků a konfiguračních či datových souborů). Ovšem i bez využití přídavných modulů (pluginů) obsahuje samotný Vim poměrně velké množství příkazů využitelných při editaci zdrojových kódů. Některé z těchto příkazů existovaly již v původním editoru vi (dnes je na Linuxu dostupná jeho volná verze nazvaná nvi, která se snaží do co největší míry napodobit původní editor vi, včetně několika chyb, což ovšem jen vypovídá o síle tohoto editoru), ovšem většinu dále popsaných příkazů najdeme až v novějších verzích Vimu.

Obrázek 1: Zdrojový text otevřený v textovém editoru nvi, který se snaží svým chováním do co největší míry napodobit původní textový editor vi.

V následující tabulce jsou vypsány některé příkazy dostupné v normálním režimu, které lze využít při práci se zdrojovými kódy většiny programovacích jazyků:

Příkaz Mnemotechnická pomůcka Význam
dab delete a block vymazání textu mezi kulatými závorkami včetně závorek
dib delete inner block vymazání textu mezi kulatými závorkami bez závorek (ty zůstanou v textu zachovány)
daB delete a Block vymazání textu mezi složenými závorkami včetně závorek
diB delete inner Block vymazání textu mezi složenými závorkami bez závorek
dat delete a tag vymazání textu umístěného v párové značce, včetně otvírací i zavírací značky (platí zejména pro soubory HTML, XHTML a XML)
dit delete inner tag vymazání textu umístěného v párové značce, například v odstavci (platí zejména pro soubory HTML, XHTML a XML)
cab change a block změna textu mezi kulatými závorkami včetně závorek
cib change inner block změna textu mezi kulatými závorkami
caB change a Block změna textu mezi složenými závorkami včetně závorek
ciB change inner Block změna textu mezi složenými závorkami
% × přeskok mezi znaky definovanými volbou matchpairs
= × zarovnání textu vybraného libovolnou výběrovou operací
=aB indent a Block kombinace operátoru = a výběru bloku mezi {}
> posun textu vybraného libovolnou výběrovou operací doprava o shiftwidth
< posun textu vybraného libovolnou výběrovou operací doleva o shiftwidth
>> posun jediného řádku doprava o hodnotu nastavenou pomocí volby set shiftwidth
<< posun jediného řádku doleva o hodnotu nastavenou pomocí volby set shiftwidth

Obrázek 2: Odsazení části zdrojového textu doprava pomocí příkazu > v případě, že je volba shiftwidth nastavena na hodnotu 4.

2. Využití příkazu %

V tabulce vypsané v předchozí kapitole byl uveden i zdánlivě primitivní příkaz %, který je však ve skutečnosti velmi užitečný. Tento příkaz je součástí původního textového editoru vi, ovšem pro potřeby Vimu byl v několika ohledech vylepšen. V čem však vlastně spočívá užitečnost tohoto příkazu při editaci zdrojových kódů? Tento příkaz dokáže najít na aktuálně editovaném řádku takzvaný párový znak umístěný na místě kurzoru či napravo od kurzoru a posléze skočí na opačný párový znak. Tento druhý párový znak se může nacházet jak napravo, tak i nalevo od kurzoru, popř. na zcela jiném řádku v editovaném souboru. Chování příkazu % je ukázáno na screenshotu 3 až 5. Vzhledem k tomu, že se jedná o příkaz přesunu kurzoru, lze ho kombinovat s příkazy d, c, > atd.

Obrázek 3: Pozice textového kurzoru před zavoláním příkazu %.

Jako párové znaky jsou většinou nastaveny tři druhy závorek – kulaté závorky (), hranaté závorky [] a složené závorky {}. Ovšem pomocí volby matchpairs lze nastavit i další párové znaky, například ostré závorky <> (v současnosti jsou párové znaky omezeny skutečně na dvojici jednotlivých znaků, v případě potřeby však lze použít velmi užitečný plugin nazvaný matchit, který je součástí distribuce Vimu):

:set matchpairs=(:),[:],{:},<:>

Obrázek 4: Po zadání příkazu % je napravo od kurzoru nalezen první párový znak, kterým je v tomto případě levá složená závorka {. Posléze editor nalezne druhý párový znak (je na řádku 19) a přesune se na něj.

Z předchozího příkladu je patrné, jak se párové znaky zapisují – jsou od sebe odděleny dvojtečkou, přičemž jednotlivé dvojice jsou od sebe odděleny čárkou. Volba matchpairs má ještě jeden význam, a to v souvislosti s volbou showmatch. V případě, že je tato volba zapnuta příkazem:

:set showmatch

tak se při zápisu uzavíracího párového znaku textový kurzor na okamžik (stanovený pomocí matchtime) přemístí na otevírací párový znak, což například zjednodušuje zápis složitějších matematických výrazů, protože Vim se samozřejmě snaží o správné spojení párových znaků i v případě, že je jich ve výrazu zapsáno větší množství, a to v libovolné kombinaci, což je naznačeno níže (zpárované znaky jsou vizuálně spojeny):

#define MAX(a,b) ( (a)>(b) ? (a) : (b) )
           |   | | | |    | |   | |   | | |
           `---' | `-'    `-'   `-'   `-' |
                 `------------------------'

Obrázek 5: Opětovné zadání příkazu % způsobí návrat na otevírací složenou závorku {.

3. Odsazení bloků ve zdrojovém kódu

Dalším příkazem, který je určený především pro editaci zdrojových kódů, je příkaz =, jenž slouží pro zarovnání kódu podle nastavených pravidel. Tento příkaz musí být doplněný některým příkazem pro posun textového kurzoru, popř. příkazem, kterým se specifikuje rozsah platnosti. Například se může jednat o příkazy ab (a block), ib (inner block), aB či iB zmíněné v první kapitole tohoto článku, poměrně často se však taktéž může hodit výběr textu ve výběrovém režimu (příkazy v, V a Ctrl+V) následovaný zadáním příkazu =. Chování příkazu = je ovlivněno především volbou equalprg. Pokud tato volba neobsahuje žádnou hodnotu, tj. po zavolání příkazu:

:set equalprg=

je použit interní algoritmus pro zarovnání či odsazení textu, v opačném případě se zadaná hodnota považuje za jméno externího příkazu, který je zavolán a vybraný text je tomuto příkazu předán přes standardní vstup.

Obrázek 6: Nezformátovaný céčkový zdrojový text.

Pro formátování běžného textu (pokud se tedy nespokojíme s možnostmi formátování s využitím příkazu gq, které jsou poměrně velké) lze použít například externí nástroj (filtr) nazvaný fmt:

:set equalprg=fmt

popř. stejný filtr, ale s předáním konfiguračních parametrů na příkazové řádce:

:set equalprg=fmt\ -t\ -w60

V případě, že konfigurační parametr equalprg neobsahuje žádnou hodnotu, je vybraná část textu formátována interním algoritmem. Těchto algoritmů existuje několik, přičemž výběr jednoho z nich se provádí pomocí voleb smartindent, popř. cindent a taktéž (i když dnes již méně často, než v minulosti) lisp. Pro formátování/odsazování céčkovských zdrojových kódů se většinou používá volba cindent, popř. se volá externí filtr indent.

Obrázek 7: Výsledek příkazu =aB v případě, že je nastavena volba cindent.

4. Nastavení parametrů shiftwidth a cinoptions

Konfigurace interního algoritmu odsazování vybraného s využitím volby cindent jsou určeny pomocí hodnoty konfiguračního parametru cinoptions, navíc se ještě odsazování řídí parametry shiftwidthtabstop. Řídicí znaky ovlivňující formátování, které lze do konfiguračního parametru cinoptions dosadit, lze zobrazit přímo ve Vimu pomocí příkazu:

:help cinoptions-values

Některé často používané řídicí znaky jsou vypsány v následující tabulce (za N se dosazuje v některých případech celé číslo, v některých případech i číslo desetinné, v obou případech se jedná o relativní hodnotu vůči shiftwidth):

Řídicí znak Význam
fN úroveň posunutí otevírací levé závorky { pod jménem funkce
:N úroveň odsazení větví case/default v konstrukci switch-case (někdo preferuje, aby se příkazy case umisťovaly přímo pod switch, někdo tyto příkazy raději odsazuje)
=N odsazení příkazu/příkazů za klíčovým slovem case/default
bN odsazení příkazu break v konstrukci switch-case
hN podobné volbě =N, ale platné pro klíčová slova public atd. (C++)

Obrázek 8: Zdrojový kód zformátovaný pomocí příkazu g=G při nastavení konfiguračního parametru shiftwidth na hodnotu 2.

Počet mezer, o něž se interní programové bloky odsadí od levého okraje, se specifikuje konfiguračním parametrem shiftwidth. Rozdíl mezi nastavením:

:set shiftwidth=2

a nastavením:

:set shiftwidth=4

je patrný ze screenshotů číslo 8 a 9.

Obrázek 9: Zdrojový kód zformátovaný pomocí příkazu g=G při nastavení konfiguračního parametru shiftwidth na hodnotu 4.

Poznámka: pokud preferujete automatické přeformátování celého programového bloku ihned po zápisu uzavírací složené závorky }, je možné předefinovat funkci znaku „}“ v režimu vkládání následujícím příkazem:

:imap } }<Esc>=%``a

Tento příkaz zajistí, že se po zápisu znaku „}“ tento znak skutečně vloží do zdrojového kódu, nicméně ihned poté je zavolán příkaz = současně s pohybem kurzoru na začátek bloku (%) a posléze je pomocí příkazu `` (zpětné apostrofy, ne apostrofy přímé) obnovena pozice textového kurzoru v souboru.

5. Omni completion – nová vlastnost Vimu 7

Další vlastností textového editoru Vim, kterou se dnes budeme zabývat, je technologie nazvaná „omni completion“. Tato technologie, která se ve Vimu objevila až v jeho sedmé verzi, rozšiřuje možnosti automatického doplňování kódu o externí nástroje. Připomeňme si, že Vim nabízí ve vkládacím a přepisovacím režimu klávesovou zkratku Ctrl+P (previous) pro nalezení a doplnění slova nacházejícího se před kurzorem a taktéž zkratku Ctrl+N (next), která slouží ke stejnému účelu, ovšem hledá slovo pro doplnění v textu za kurzorem (pokud je k dispozici více možností, zobrazí se v kontextovém menu).

Obrázek 10: Doplňování kódu pomocí příkazů CTRL+P a CTRL+N.

Ovšem možnosti automatického doplňování kódu jsou daleko větší, textový editor Vim pro ně dokonce nabízí samostatný režim vyvolávaný z vkládacího či přepisovacího režimu klávesovou zkratkou Ctrl+X. Po stlačení této klávesové zkratky se v příkazové řádce objeví řádkové menu s příkazy platnými pro režim doplňování. Všechny dostupné příkazy jsou vypsány v tabulce níže:

# Příkaz Význam
1 Ctrl+X Ctrl+L nalezení a doplnění celého (shodného) řádku, užitečné především v případě editace některých typů konfiguračních souborů
2 Ctrl+X Ctrl+N doplnění slova, které se nalézá v aktuálně editovaném souboru
3 Ctrl+X Ctrl+K podobné Ctrl+N, ovšem slova se hledají v souborech specifikovaných pomocí konfiguračního parametru dictionary (jedná se o běžný textový soubor se seznamem slov)
4 Ctrl+X Ctrl+T podobné Ctrl+T, ovšem slova se hledají v souborech specifikovaných pomocí konfiguračního parametru thesaurus
5 Ctrl+X Ctrl+I podobné Ctrl+N, ovšem prohledávají se i všechny vkládané (included) soubory
6 Ctrl+X Ctrl+] vyhledávání v seznamu značek
7 Ctrl+X Ctrl+F doplnění názvu souboru a/nebo cesty, postačuje například zadat text ~/ za nímž následuje klávesová zkratka Ctrl+X Ctrl+F a zobrazí se výpis souborů v domácím adresáři
8 Ctrl+X Ctrl+D vyhledání definice makra a doplnění jména tohoto makra
9 Ctrl+X Ctrl+U zavolání funkce zadané v konfiguračním parametru completefunc, které se předá právě editovaný text
10 Ctrl+X Ctrl+O vyvolání omni completion popsané v následující kapitole (dostupné od Vimu 7)

Obrázek 11: Doplnění názvu souboru v pracovním adresáři pomocí příkazu CTRL+X CTRL+F.

6. Využití omni completion při vývoji v jazyku C

V předchozí kapitole jsme si řekli, že pomocí klávesové zkratky Ctrl+X Ctrl+O lze ve vkládacím a přepisovacím režimu zavolat technologii „omni completion“. Tuto technologii lze využít pro (pseudo)inteligentní doplňování textů založeném na analýze zdrojových kódů. Podobnou funkci můžeme najít v nejrůznějších integrovaných vývojových prostředích (Eclipse, Netbeans, Visual Studio), v nichž lze doplňovat například jména prvků ve strukturách či uniích, atributů objektů, metod objektů či tříd, jmen balíčků atd. Textový editor Vim při doplňování používá kombinaci externích nástrojů (například ctags v případě céčkových programů) a skriptů. Ukažme si nejdříve, jak lze omni completion využít u aplikací vyvíjených v programovacím jazyku C. Vzhledem k tomu, že samotný Vim nemá prakticky žádné kontextové informace o editovaných céčkovských zdrojových kódech, využívá k jejich získání výstup z externího nástroje ctags.

Obrázek 12: Využití technologie omni completion při práci s céčkovským zdrojovým kódem.

V případě, že je pro daný projekt vygenerován soubor se značkami pomocí nástroje ctags, je možné pomocí omni completion doplňovat názvy funkcí, maker, ale dokonce i jména prvků ve strukturách a uniích. Tato jména jsou doplňována po zapsání znaku tečky popř. šipky (->), samozřejmě v závislosti na tom, zda se jedná přímo o jméno struktury, nebo o jméno ukazatele na strukturu.

Obrázek 13: Využití technologie omni completion při editaci HTML stránky.

7. Využití omni completion při editaci HTML, XHTML a XML

Zajímavá je taktéž podpora technologie „omni completion“ pro soubory typu HTML, XHTML či XML. V tomto případě je (samozřejmě) možné doplňovat jména jednotlivých uzlů, ale i názvy elementů či atributů, a to včetně jejich hodnot. Textový editor Vim zjistí, které uzly/atributy/hodnoty lze v daném kontextu použít, což například znamená, že se v případě editace HTML stránky uvnitř značek <p> po zadání prefixu <st nenabídne možnost vložení uzlu <style>, zatímco při použití stejného prefixu v kořenovém uzlu ano.

Obrázek 14: Využití technologie omni completion při editaci HTML stránky.

Pokud se vám zdá použití klávesové zkratky CTRL+X CTRL+O poněkud krkolomné, není nic jednoduššího, než si tuto zkratku přemapovat pro vkládací a přepisovací režim příkazem imap. V případě, že Vim (či spíše Gvim) správně rozpozná klávesovou zkratku CTRL+mezera, lze využít následující mapování:

:imap <C-Space> <C-X><C-O>

Pokud se navíc ve zdrojových textech nikde nepoužívá tabulátor (záleží na zvolené štábní kultuře), může pomoci toto mapování:

:imap <Tab> <C-X><C-O>

Obrázek 15: Zavolání skriptu 2html.vim (viz následující kapitolu).

8. Vytvoření HTML stránky s obarveným zdrojovým kódem

Textový editor Vim obsahuje ve své standardní instalaci taktéž v mnoha případech užitečný skript nazvaný příznačně 2html.vim. Tento skript slouží pro vytvoření HTML stránky obsahující právě editovaný zdrojový kód se zvýrazněním syntaxe. Skript pro zvýraznění syntaxe přitom využívá stejné barvy, jaké jsou nastaveny v textovém editoru, takže odpadá nutnost mnohdy komplikovaných konfigurací externích „obarvovačů kódu“ (jediný problém může způsobit špatně nastavená hodnota konfiguračního parametru background, který lze nastavit na dark nebo light). Existence skriptu 2html.vim taktéž zaručuje, že jakýkoli typ textového souboru, u nějž se ve Vimu zvýrazňuje syntaxe, bude možné vyexportovat do formátu HTML. V současnosti obsahuje Vim v konfiguračních souborech syntaktická (či přesněji řečeno lexikální) pravidla pro více než 500 různých typů souborů, o čemž se ostatně můžete sami přesvědčit zadáním následujícího příkazu:

:!ls -1 $VIMRUNTIME/syntax | wc -l

521 (nebo podobné číslo)

Obrázek 16: HTML stránka vygenerovaná skriptem 2html.vim (nahoře) a původní textový soubor (dole).

Použití skriptu 2html.vim je velmi jednoduché. Nejprve se přímo ve Vimu otevře textový soubor (například zdrojový kód), který se má vyexportovat do HTML. Posléze se může načíst či upravit barevné schéma, což je mimochodem téma, kterému se budeme věnovat v následující části tohoto seriálu. Posléze již stačí skript spustit pomocí příkazu:

:source $VIMRUNTIME/syntax/2html.vim

popř. pouze:

:so $VIMRUNTIME/syntax/2html.vim

Tento příkaz lze samozřejmě namapovat na libovolnou klávesovou zkratku a při zápisu cesty ke skriptu je možné využít automatické doplňování cesty pomocí klávesy Tab. Po spuštění skriptu 2html.vim se v novém okně otevře nový buffer obsahující zdrojový kód HTML stránky, který lze samozřejmě libovolným způsobem upravovat, typicky změnit titulek, změnit název souboru, přidat cestu ke style sheetu atd. Export do HTML je proveden pro aktuálně editovaný buffer, tj. pro buffer, v němž se nachází textový kurzor.

Obrázek 17: Vygenerovaná HTML stránka zobrazená ve WWW prohlížeči.

9. Odkazy na Internetu

  1. Clewn home page
    http://clewn.sourceforge.net/
  2. How to connect vim with gdb – using clewn
    http://chunhao.net/blog/how-to-connect-vim-with-gdb-using-clewn
  3. yavdb : Yet Another (Generic) Vim Debugger Integration
    http://www.vim.org/scripts/scrip­t.php?script_id=1954
  4. Vim home page
    http://www.vim.org/
  5. Exuberant ctags
    http://ctags.sourceforge.net/
  6. xxd (man page)
    http://www.linux-tutorial.info/modules.php?na­me=ManPage&sec=1&manpage=xxd
  7. vim (man page)
    http://www.linux-tutorial.info/modules.php?na­me=ManPage&sec=1&manpage=vim
  8. ctags (man page)
    http://www.linux-tutorial.info/modules.php?na­me=ManPage&sec=1&manpage=ctags
  9. cscope (man page)
    http://www.linux-tutorial.info/modules.php?na­me=ManPage&sec=1&manpage=csco­pe
  10. 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/
  11. c.vim : C/C++ IDE
    http://vim.sourceforge.net/scrip­ts/script.php?script_id=213
  12. c.vim : C/C++ IDE key mappings
    http://lug.fh-swf.de/vim/vim-c/c-hotkeys.pdf
  13. Základní základy editoru Vim
    http://www.root.cz/clanky/zakladni-zaklady-editoru-vim/
  14. Jak si přizpůsobit Vim
    http://www.root.cz/serialy/jak-si-prizpusobit-vim/
  15. Novinky ve VIM 7: Úvodní část – speller
    http://www.root.cz/vim-sedm-prvni-cast/
  16. Novinky ve VIM 7: Skriptovací jazyk
    http://www.root.cz/vim-sedm-druha-cast/
  17. vim2elvis: Přednosti a nedostaky Elvise v porovnání s Vimem
    http://www.root.cz/clanky/vim2elvis-1/
  18. vim2elvis: Shodné znaky mezi Elvisem a Vimem, nastaveníeditoru
    http://www.root.cz/clanky/vim2elvis-2/
  19. Nej… VIM pluginy (1)
    http://www.root.cz/clanky/nej-vim-pluginy/
  20. Taglist (plugin)
    http://www.vim.org/scripts/scrip­t.php?script_id=273
  21. The NERD tree: A tree explorer plugin for navigating the filesystem
    http://www.vim.org/scripts/scrip­t.php?script_id=1658
  22. 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
  23. snippetsEmu : An attempt to emulate TextMate's snippet expansion
    http://www.vim.org/scripts/scrip­t.php?script_id=1318
  24. Scroll Lock (Necyklopedie)
    http://necyklopedie.wikia­.com/wiki/Scroll_lock
  25. Caps Lock (Necyklopedie)
    http://necyklopedie.wikia­.com/wiki/Caps_Lock
  26. Avoid the escape key
    http://vim.wikia.com/wiki/A­void_the_escape_key
  27. Map caps lock to escape in XWindows
    http://vim.wikia.com/wiki/VimTip166
Našli jste v článku chybu?

14. 7. 2011 15:40

Jeste dodam, ze skutecne pro Vim existuje mene vetsich modulu typu postovni klient nebo webovy browser, protoze (pravdepodobne) po techto funkcich neni az takova poptavka, spis se pouziva opacny pristup, tj. postovni klient ma jako editor posty nastaveny Vim, pro spravu souboru neni nad CLI+MC :-) atd.

Nemyslim ted, ze je Vim lepsi nez Emacs nebo naopak, proste se jen uplatnuje jina filozofie, tot vse.

DigiZone.cz: Flix TV startuje i na Slovensku

Flix TV startuje i na Slovensku

Podnikatel.cz: Přehledná titulka, průvodci, responzivita

Přehledná titulka, průvodci, responzivita

Podnikatel.cz: 1. den EET? Problémy s pokladnami

1. den EET? Problémy s pokladnami

DigiZone.cz: „Black Friday 2016“: závěrečné zhodnocení

„Black Friday 2016“: závěrečné zhodnocení

Lupa.cz: Kdo pochopí vtip, může jít do ČT vyvíjet weby

Kdo pochopí vtip, může jít do ČT vyvíjet weby

Měšec.cz: mBank cenzuruje, zrušila mFórum

mBank cenzuruje, zrušila mFórum

Vitalia.cz: I církev dnes vyrábí potraviny

I církev dnes vyrábí potraviny

Měšec.cz: Air Bank zruší TOP3 garanci a zdražuje kurzy

Air Bank zruší TOP3 garanci a zdražuje kurzy

Měšec.cz: Kdy vám stát dá na stěhování 50 000 Kč?

Kdy vám stát dá na stěhování 50 000 Kč?

Vitalia.cz: Spor o mortadelu: podle Lidlu falšovaná nebyla

Spor o mortadelu: podle Lidlu falšovaná nebyla

Vitalia.cz: Jsou čajové sáčky toxické?

Jsou čajové sáčky toxické?

Podnikatel.cz: Podnikatelům dorazí varování od BSA

Podnikatelům dorazí varování od BSA

Podnikatel.cz: Snížení DPH na 15 % se netýká všech

Snížení DPH na 15 % se netýká všech

Lupa.cz: Proč firmy málo chrání data? Chovají se logicky

Proč firmy málo chrání data? Chovají se logicky

120na80.cz: Co všechno ovlivňuje ženskou plodnost?

Co všechno ovlivňuje ženskou plodnost?

DigiZone.cz: Recenze Westworld: zavraždit a...

Recenze Westworld: zavraždit a...

Vitalia.cz: „Připluly“ z Německa a možná obsahují jed

„Připluly“ z Německa a možná obsahují jed

Vitalia.cz: Taky věříte na pravidlo 5 sekund?

Taky věříte na pravidlo 5 sekund?

120na80.cz: Pánové, pečujte o svoje přirození a prostatu

Pánové, pečujte o svoje přirození a prostatu

Podnikatel.cz: Chtějte údaje k dani z nemovitostí do mailu

Chtějte údaje k dani z nemovitostí do mailu