Vimspector: zdařilá integrace debuggerů do Vimu

14. 12. 2023
Doba čtení: 20 minut

Sdílet

 Autor: Root.cz s využitím DALL-E
Seznámíme se s doplňujícím modulem určeným pro editor Vim, který se nazývá Vimspector. Umožňuje propojení Vimu s různými debuggery pro Python, C, C++, Lua a další. Vzhledem se snaží napodobit řešení známá z různých IDE.

Obsah

1. Vimspector: zdařilá integrace debuggerů do Vimu

2. Základní vlastnosti Vimspectoru

3. Kontrola, s jakými přepínači byl přeložen Vim

4. Instalace Vimspectoru

5. 400 megabajtů pro pouhý debugger?

6. Konfigurace projektu, který se má ladit

7. Nastavení breakpointů v laděném skriptu

8. Spuštění a ukončení debuggeru

9. Krokování a zobrazení obsahu proměnných při ladění

10. Zobrazení hodnot zadaných výrazů

11. Zobrazení zásobníkových rámců

12. Konfigurační soubor umožňující ladění dvou aplikací

13. Ladění aplikace s velkou hloubkou rekurze při spuštění

14. Zobrazení obsahu parametru či proměnné přímo v okně editoru se zdrojovým kódem

15. Časté problémy

16. Debugging debuggeru

17. Příloha: základní klávesové zkratky pro ovládání Vimspectoru

18. Závěr

19. Odkazy na relevantní články na Rootu

20. Odkazy na Internetu

1. Vimspector: zdařilá integrace debuggerů do Vimu

Textový editor Vim se díky své podpoře skriptování (včetně Pythonu), podpoře maker, záložek (tabů), oken a bufferů může po instalaci vhodných pluginů změnit v poměrně robustní a přitom výkonné integrované vývojové prostředí, které navíc odpovídá Unixové filozofii – Vim je v tomto případě komponentou volající další aplikace a nástroje, nikoli monolitickým programem, který teoreticky umí všechno, ovšem nic pořádně :-) V mnoha případech musí programátoři použít debugger pro nalezení chyby v programu a právě v této chvíli stojí před rozhodnutím, zda debugger spustit v samostatném terminálu nebo zda naopak použít vhodný plugin pro spuštění a především pro ovládání debuggeru přímo z Vimu. Druhá možnost je v některých ohledech lepší, protože debugger ovládaný z příkazové řádky (gdb apod.) sice uživatelům nabízí nepřeberné množství mnohdy i velmi komplikovaných příkazů, na druhou stranu však nemá všechny možnosti celoobrazovkového debuggeru, na který jsou dnešní programátoři zvyklí.

Obrázek 1: Typické „sezení“ programátora využívajícího debugger gdb. Přeložení programu s vygenerováním ladicích informací (-g) a následné spuštění debuggeru.

V současnosti existuje hned několik přídavných modulů určených pro textový editor Vim, které do tohoto editoru více či někdy spíš méně úspěšně integrují podporu pro debuggery. Jeden z takových modulů se jmenuje Vimspector. Předností tohoto modulu je poměrně robustní chování (což není zcela obvyklé) a taktéž podpora relativně velkého množství debuggerů, včetně debuggerů dostupných přes protokol DAP. A samozřejmě můžeme najít i některé nevýhody. První nevýhodou je, že instalace Vimspectoru je obrovská – několik set megabajtů(!). Jak ovšem uvidíme dále, je to zapříčiněno tím, že součástí Vimspectoru jsou i samotné debuggery, tj. například pro Go debugger delve, pro Python debugger debugpy atd. V praxi to znamená, že nepoužívané debuggery lze snadno smazat. A druhou nevýhodou je nutnost přípravy konfiguračního souboru, aby Python věděl, jaký debugger a s jakými parametry se má spustit.

td1

Obrázek 2: V minulosti velmi populární nástroj Turbo Debugger je vybaven celoobrazovkovým textovým uživatelským rozhraním (TUI) připomínajícím další produkty vytvořené společností Borland. Rozhraní a možnosti Turbo Debuggeru je stále možné považovat za etalon toho, jak by mohl vypadat moderní debugger s TUI či GUI (a popravdě řečeno – Vimspektor zde ještě není).

2. Základní vlastnosti Vimspectoru

Jaké vlastnosti vlastně plugin Vimspector programátorům nabízí? Jedná se o dnes zcela standardní operace, mezi něž patří zejména:

  • Definice breakpointů přímo v okně editovaného souboru
  • Možnost krokování (v režimu debuggeru)
  • Krokování se vstupem do volané funkce
  • Automatické zobrazení lokálních proměnných
  • Možnost zobrazení (a automatického přepočtu) libovolného výrazu
  • Zobrazení zásobníkových rámců – volaných funkcí s jejich parametry
  • Zobrazení obsahu výrazu, nad nímž se nachází kurzor myši (platí pro GVim a KVim, ne pro konzoli)
  • Zobrazení výstupní konzole, rozdělení výstupu na standardní výstup a chybový výstup
  • Zobrazení konzole s informacemi o komunikaci mezi Vimem a debuggerem

Jak je z výše uvedeného seznamu zřejmé, skutečně jsou zahrnuty všechny základní operace, které navíc fungují velmi stabilně (například v porovnání s integrací debuggerů do textového editoru Helix, což je prozatím nejvíce bolestivá část tohoto editoru).

Obrázek 3: Pohled na textové uživatelské rozhraní debuggeru PuDB s pěti regiony. Vimspector se tomuto pohledu přibližuje, jak si ostatně ukážeme na screenshotech přidaných do navazujících kapitol.

3. Kontrola, s jakými přepínači byl přeložen Vim

V dalších kapitolách si ukážeme, jakým způsobem se Vimspector ovládá. Nejdříve je ho však nutné nainstalovat a taktéž se ujistit o tom, že tento plugin bude plnohodnotně ve Vimu spustitelný a provozovatelný. Vimspector je totiž částečně naprogramován v Pythonu, což nemusí být příliš překvapivé, když si uvědomíme, že VimScript, tedy skriptovací jazyk dostupný přímo ve Vimu, je pro větší přídavné moduly poměrně nešikovný. Aby byl Vimspector použitelný, musí být textový editor Vim přeložen s podporou Pythonu, resp. Pythonu 3 – díky tomu je umožněna tvorba skriptů přímo v tomto populárním programovacím jazyce. O tom, zda vámi používaný Vim skutečně přeložen s podporou Pythonu, se lze přesvědčit relativně snadno po zadání příkazu :ver. U volby python či python3/dyn by se měl objevit znak +.

Jak to může vypadat v praxi? Níže je vidět výsledek příkazu :ver se zvýrazněnou volbou +python3/dyn. V takto nakonfigurovaném a přeloženém Vimu tedy bude Vimspector funkční:

:ver
 
VIM - Vi IMproved 9.0 (2022 Jun 28, compiled Oct 05 2023 00:00:00)
Included patches: 1-1984
Modified by <bugzilla@redhat.com>
Compiled by <bugzilla@redhat.com>
Huge version without GUI.  Features included (+) or not (-):
+acl               +file_in_path      +mouse_urxvt       -tag_any_white
+arabic            +find_in_path      +mouse_xterm       -tcl
+autocmd           +float             +multi_byte        +termguicolors
+autochdir         +folding           +multi_lang        +terminal
-autoservername    -footer            -mzscheme          +terminfo
-balloon_eval      +fork()            +netbeans_intg     +termresponse
+balloon_eval_term +gettext           +num64             +textobjects
-browse            -hangul_input      +packages          +textprop
++builtin_terms    +iconv             +path_extra        +timers
+byte_offset       +insert_expand     +perl/dyn          +title
+channel           +ipv6              +persistent_undo   -toolbar
+cindent           +job               +popupwin          +user_commands
-clientserver      +jumplist          +postscript        +vartabs
-clipboard         +keymap            +printer           +vertsplit
+cmdline_compl     +lambda            +profile           +vim9script
+cmdline_hist      +langmap           -python            +viminfo
+cmdline_info      +libcall           +python3/dyn       +virtualedit
+comments          +linebreak         +quickfix          +visual
-- More --

4. Instalace Vimspectoru

Instalaci Vimspectoru lze provést různými způsoby, které jsou (i když pouze velmi stručně) vypsány zde, takže je zde nebudeme znovu opisovat. Namísto toho se zmiňme o plně ruční (neautomatické) instalaci, která nás naučí nejvíce o tom, jak Vim dokáže pracovat s přídavnými moduly. Nejdříve si stáhneme poslední verzi Vimspectoru, kterou nalezneme na stránce https://github.com/puremou­rning/vimspector/releases/tag/6997902219 (jak je patrné, k dispozici je varianta pro Linux i pro MacOS, čímž jsou pokryty všechny zajímavé operační systémy :-). Dále stažený tarball rozbalíme příkazem tar xvfz tarball. Rozbalenou strukturu (ovšem bez adresáře na nejvyšší úrovni) je nyní možné překopírovat do adresáře ~/.vim. Jeho struktura může po provedení všech tří operací vypadat následovně:

.
├── autoload
│   └── vimspector
│       └── internal
├── configurations
│   └── linux
│       └── _all
├── doc
├── gadgets
│   └── linux
│       ├── CodeLLDB -> download/CodeLLDB/v1.9.2/root/extension
│       ├── debugpy -> download/debugpy/1.7.0/root/debugpy-1.7.0
│       ├── delve -> download/delve
│       ├── download
│       ├── local-lua-debugger-vscode -> download/local-lua-debugger-vscode
│       ├── netcoredbg -> download/netcoredbg/2.2.3-992/root/netcoredbg
│       ├── tclpro -> download/tclpro
│       ├── vscode-bash-debug -> download/vscode-bash-debug/0.3.9/root/extension
│       ├── vscode-cpptools -> download/vscode-cpptools/1.17.5/root/extension
│       ├── vscode-go -> download/vscode-go/0.30.0/root/extension
│       └── vscode-js-debug -> download/vscode-js-debug/v1.82.0/root
├── plugin
├── python3
│   └── vimspector
│       ├── custom
│       ├── __pycache__
│       └── vendor
├── support
│   ├── bin
│   ├── doc
│   ├── gadget_upgrade
│   ├── test
│   │   ├── bash
│   │   ├── cpp
│   │   ├── csharp
│   │   ├── example
│   │   ├── go
│   │   ├── java
│   │   ├── kotlin
│   │   ├── lua
│   │   ├── multiple_filetypes
│   │   ├── node
│   │   ├── php
│   │   ├── python
│   │   ├── ruby
│   │   ├── rust
│   │   ├── tcl
│   │   └── web
│   └── vimspector_process_list
└── tests
Poznámka: samozřejmě můžeme využít schopnosti Vimu pracovat s balíčky a přesunout rozbalenou adresářovou strukturu do poadresáře ~/.vim/pack. To je výhodnější ve chvíli, kdy je nainstalováno větší množství balíčků, které je nutné nějakým způsobem spravovat.
Poznámka2: taktéž si nemusíte stahovat poslední oficiální vydání Vimspectoru, ale můžete si do ~/.vim/pack/plugins/ přímo naklonovat obsah repositáře https://github.com/puremou­rning/vimspector (s případným uvedením tagu atd.)

Dále je vhodné provést nepatrnou změnu konfiguračního souboru .vimrc. Následující konfigurační řádek (deklarace proměnné) slouží k nastavení klávesových zkratek, kterými se Vimspector ovládá:

let g:vimspector_enable_mappings = 'HUMAN'

5. 400 megabajtů pro pouhý debugger?

V úvodní kapitole jsme se zmínili o tom, že jednou z nevýhod Vimspectoru je fakt, že se jedná o obrovský balíček. Je tomu tak z toho důvodu, že tarball obsahuje i samotné debuggery, což jsou mnohdy velké balíčky (především díky statickému linkování). Můžeme se o tom ostatně velmi snadno přesvědčit pohledem do podadresáře … gadgets/linux, který debuggery obsahuje:

$ du -sh *
 
197M    CodeLLDB
60M     debugpy
71M     delve
111M    local-lua-debugger-vscode
13M     netcoredbg
30M     tclpro
2.1M    vscode-bash-debug
329M    vscode-cpptools
4.6M    vscode-go
4.3M    vscode-js-debug

V praxi to ovšem znamená to, že pokud například budete chtít používat pouze debugger pro Python, lze smazat všechny ostatní debuggery (samozřejmě kromě debugpy). Dtto pro programovací jazyk Go a debugger delve atd.

6. Konfigurace projektu, který se má ladit

Nyní, když již (doufejme) máme přídavný modul Vimspector nainstalován, si můžeme ukázat základní způsoby jeho používání. To ovšem není triviální, protože chování Vimspectoru je do značné míry ovlivněno konfiguračním souborem nazvaným .vimspector.json, který je nutné pro aktuální projekt vytvořit. Samotný konfigurační soubor umožňuje používat Vimspector velmi flexibilním způsobem (například i pro vzdálené ladění přes SSH), ovšem nutnost prvotního nastavení projektu je minimálně nepříjemná.

V dalším textu si ukážeme Vimspector použitý pro ladění Pythonovských skriptů, takže se podívejme, jak by mohl vypadat ten nejjednodušeji pojatý konfigurační soubor. Specifikujeme v něm jak konkrétní debugger (tedy debugpy – je součástí instalace Vimspectoru), tak i způsob načtení konkrétního zdrojového kódu (nebo modulu) do debuggeru (konkrétně se do debuggeru načte soubor add.py, který budeme ladit):

{
  "$schema": "https://puremourning.github.io/vimspector/schema/vimspector.schema.json",
  "configurations": {
      "main":{
          "adapter": "debugpy",
          "configuration": {
              "name": "run the executable",
              "type": "python",
              "request": "launch",
              "python.pythonPath": "/usr/bin/python3",
              "program": "~/add.py"
          },
          "breakpoints": {
              "exception": {
                  "raised": "N",
                  "caught": "N",
                  "uncaught": "Y",
                  "userUnhandled": "N"
              }
          }
      }
  }
}

7. Nastavení breakpointů v laděném skriptu

Nyní si již můžeme spustit textový editor Vim a otevřít v něm soubor nazvaný add.py. Tento soubor bude obsahovat testovanou funkci:

def add(x, y):
    return x+y
 
def main():
    x = add(10, 20)
    y = add("foo", "bar")
    z = add([1,2,3], [4,5,6])
 
print("add.py script started")
main()
print("add.py script finished")

Umístíme textový kurzor kamkoli na řádek s příkazem x = add(10, 20):

Obrázek 4: Soubor se zdrojovým kódem, který budeme ladit, otevřený ve Vimu.

Pokud nyní stiskneme klávesu F9 (a vše je dobře nakonfigurováno), zobrazí se v levé části okna nový pruh, který je typicky nazývaný gutter, ve Vimu pak sign(s). V tomto pruhu se objeví znak pro breakpoint, který jsme klávesou F9 nastavili:

Obrázek 5: Zobrazení informace o nastaveném breakpointu.

Poznámka: opětovným stiskem klávesy F9 se breakpoint vymaže.

8. Spuštění a ukončení debuggeru

V případě, kdy již máme nastavený breakpoint, můžeme spustit debugger. Tato operace se provádí klávesovou zkratkou F5, která navíc způsobí, že se textový editor Vim přepne do nového „pohledu“ (i když koncept pohledů samotný Vim nepodporuje). Na ploše editoru se zobrazí několik oken, z nichž každé zobrazuje určité ucelené informace: hodnoty globálních a lokálních symbolů, výsledek vyhodnocení nějakého výrazu (což může být jen jméno proměnné), obsah zásobníkových rámců pro všechna vlákna, samotný zdrojový kód s právě prováděným řádkem a samozřejmě taktéž okno s výstupem na standardní výstup a chybový výstup. Ve výchozím nastavení vypadá plocha Vimu při ladění následovně:

Obrázek 6: Plocha Vimu ve chvíli, kdy je aplikace laděna.

Poznámka: okna debuggeru se chovají jako běžná okna ve Vimu, takže je lze přesouvat (Ctrl-w+další znak), měnit jejich velikost, pořadí atd.

Debugger lze ukončit buď tlačítkem Reset nebo příkazem:

:VimspectorReset

(nestačí pouze zavřít všechna jeho speciální okna).

9. Krokování a zobrazení obsahu proměnných při ladění

Samotné krokování se provádí klávesami F10 (volání funkce je v tomto případě považováno za jeden krok), F11 (při volání funkce se krokují i příkazy v této funkci) a F12 (přesun na další příkaz v nadřazené funkci). Příkaz, který se má provést v dalším kroku, je v okně Vimu zvýrazněn. Navíc se při každém kroku automaticky detekují a zobrazují změny globálních proměnných, popř. proměnných lokálních:

Obrázek 7: V levém horním okně jsou zobrazeny obsahy globálních i lokálních proměnných. Dalším krokem bude provedení zvýrazněného příkazu, což mj. znamená, že v tento okamžik jsou známy pouze lokální proměnné x a y.

10. Zobrazení hodnot zadaných výrazů

Prakticky všechny moderní debuggery dokážou zobrazit i výsledky získané vyhodnocením nějakého výrazu, samozřejmě s tím, že se tyto výsledky po provedení kroků mohou aktualizovat. Tento koncept je podporován i Vimspectorem. Postačuje v okně „Watches“ s využitím tlačítka Add přidat do tohoto okna nový sledovaný výraz. Ten je následně v tomto okně zobrazován až do chvíle, kdy je vymazán tlačítkem Delete:

Obrázek 8: Zobrazení obsahu dvou výrazů v okně Watches.

Poznámka: v případě, že se vám nechce klikat na tlačítko Add (a kdo by ve Vimu používal myš, že?), lze namísto toho zavolat příkaz:
:VimspectorWatch výraz

Například:

:VimspectorWatch len(y)

11. Zobrazení zásobníkových rámců

V levém dolním rohu je implicitně zobrazeno okno, v němž jsou zobrazeny zásobníkové rámce všech běžících vláken. Zde je možné sledovat historii volání funkcí atd., podobně jako je tomu ve většině debuggerů:

Obrázek 9: Zobrazení zásobníkových rámců.

Pro zajímavost se podívejme, jak vypadá zobrazení zásobníkových rámců v případě, že ladíme vícevláknovou aplikaci:

Obrázek 10: Zobrazení zásobníkových rámců u vícevláknové aplikace.

Mimochodem, jedná se o ladění tohoto jednoduchého kódu:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
"""Multithreading."""
 
import threading
import time
 
 
def worker():
    threadName = threading.current_thread().name
    delay = 100
    n = 10
    for counter in range(1, n + 1):
        time.sleep(delay)
        print("{}: {}/{} - {}".format(threadName, counter, n, time.ctime(time.time())))
 
 
# vytvoření a spuštění trojice vláken
threading.Thread(target=worker).start()
threading.Thread(target=worker).start()
threading.Thread(target=worker).start()

12. Konfigurační soubor umožňující ladění dvou aplikací

Ukažme si, jak lze konfigurační soubor .vimspector.json pravit takovým způsobem, aby umožnil ladění dvou aplikací, přičemž pro jednoduchost každou aplikaci realizujeme v jediném pythonovském skriptu. Úprava je snadná, jen nesmíme zapomenout na oddělení jednotlivých konfigurací čárkou:

{
  "$schema": "https://puremourning.github.io/vimspector/schema/vimspector.schema.json",
  "configurations": {
      "add":{
          "adapter": "debugpy",
          "configuration": {
              "name": "run the executable",
              "type": "python",
              "request": "launch",
              "python.pythonPath": "/usr/bin/python3",
              "program": "~/add.py"
          },
          "breakpoints": {
              "exception": {
                  "raised": "N",
                  "caught": "N",
                  "uncaught": "Y",
                  "userUnhandled": "N"
              }
          }
      },
      "ackermann":{
          "adapter": "debugpy",
          "configuration": {
              "name": "run the executable",
              "type": "python",
              "request": "launch",
              "python.pythonPath": "/usr/bin/python3",
              "program": "~/ackermann.py"
          },
          "breakpoints": {
              "exception": {
                  "raised": "N",
                  "caught": "N",
                  "uncaught": "Y",
                  "userUnhandled": "N"
              }
          }
      }
  }
}

13. Ladění aplikace s velkou hloubkou rekurze při spuštění

Zajímavé bude zjistit, jakým způsobem dokáže Vimspector podpořit ladění aplikace (resp. přesněji řečeno v našem případě pouze jednoduchého skriptu), v případě, kdy se při výpočtu použije velká hloubka rekurze. Příkladem takového výpočtu je realizace algoritmu pro vyhodnocení Ackermannovy funkce pro zadanou dvojici parametrů m a n. Zdrojový kód, který budeme ladit, vypadá následovně:

# Výpočet Ackermannovy funkce, založeno na pattern matchingu
 
def A(m, n):
    """Ackermannova funkce."""
    match (m, n):
        case (0, n):
            return n + 1
        case (m, 0):
            return A(m-1, 1)
        case (m, n):
            return A(m - 1, A(m, n - 1))
 
print(A(5, 5))
Poznámka: schválně jsem použil pattern matching, aby bylo zřejmé, že ani s takovým kódem nebude mít Vimspector a pythonní debugger problémy.

Ze screenshotů je patrné, že i v případě velké hloubky zanoření je možné Vimspector použít:

Obrázek 11: Zobrazení zdrojového kódu, který se bude ladit, v okně textového editoru Vim.

Obrázek 12: Přidání breakpointu na zvolený řádek zdrojového kódu klávesovou zkratkou F9.

Obrázek 13: Před spuštěním debuggeru (klávesová zkratka F5) se Vimspector zeptá, jakou aplikaci budeme ladit. Je tomu tak z toho důvodu, že jsme do konfiguračního souboru .vimspector.json přidali konfiguraci pro druhou aplikaci.

Obrázek 14: Takto probíhá ladění aplikace pro výpočet Ackermannovy funkce.

Obrázek 15: Ladění aplikace pro výpočet Ackermannovy funkce – vyšší počet zanoření při rekurzivním výpočtu. Vimspector je stále plně funkční.

14. Zobrazení obsahu parametru či proměnné přímo v okně editoru se zdrojovým kódem

V případě, že namísto Vimu běžícího v konzoli (terminálu) použijete GVim či KVim, tedy Vim běžící ve vlastním grafickém okně, je možné využít další funkci, kterou můžeme znát z integrovaných vývojových prostředí – po najetí kurzorem myši na nějakou proměnnou či parametr funkce se v „popup okně“ zobrazí aktuální obsah této proměnné. Ostatně je možné si toto chování snadno otestovat:

Obrázek 16: Zobrazení obsahu proměnné m v popup okně v průběhu laděni.

15. Časté problémy

Po instalaci VimSpectoru a spuštění Vimu se pokuste vyvolat nějaký příkaz VimSpectoru, například:

:VimspectorDebugInfo

Tím se ověří minimálně to, že je plugin nalezen a inicializován.

V případě, že není možné nastavit breakpoint (F9) nebo spustit debugger (F5), přesvědčte se, že nemáte namapovány klávesové zkratky Fx na jiné operace. To byl můj případ, protože v konfiguračním souboru .vimrc mám pro Python využity mnohé zkratky, které jsou obsazeny i samotným Vimspectorem:

augroup __python__
  au!
  au BufRead,BufNewFile *.py highlight Comment ctermfg=green
  au BufRead,BufNewFile *.py map <F8> :!pep8 %<cr>
  au BufRead,BufNewFile *.py map <F9> :!/home/ptisnovs/.local/bin/pydocstyle ./%<cr>
  au BufRead,BufNewFile *.py map <F10> :!radon cc -s ./%<cr>
  au BufRead,BufNewFile *.py map <F11> :!radon mi ./%<cr>
  au BufRead,BufNewFile *.py map ,r :!python3 %<cr>
  au BufRead,BufNewFile *.py map <F5> :!python2 %<cr>
  au BufRead,BufNewFile *.py map <F6> :!python3 %<cr>
  au BufRead,BufNewFile *.py highlight OverLength ctermbg=yellow ctermfg=white guibg=#592929
  au BufRead,BufNewFile *.py match OverLength /\%99v.\+/
augroup END

A samozřejmě je vhodné zajistit existenci souboru .vimspector.json.

Většinu ostatních problémů už dokáže VimSpector zobrazit – chybějící debugger, zprávu o tom, že se nepodařilo propojení s debuggerem atd.

16. Debugging debuggeru

Při řešení komplikovanějších problémů s debuggerem je vhodné na prvním místě spustit příkaz, který jsme si uvedli v předchozí kapitole:

:VimspectorDebugInfo

Výstupem je text zobrazený v konzoli Vimspectoru (pravé dolní okno – viz příslušné tlačítko), což znamená, že si tento text můžete prohlížet a taktéž uložit (exportovat) do souboru. V mém konkrétním případě, tedy při ladění skriptu napsaného v Pythonu, vypadá výstup takto:

Vimspector Debug Info
--------------------------------------------------------------------------------
ConnectionType: job
Adapter:
--------------------------------------------------------------------------------
{
  "command": [
    "/usr/bin/python3",
    "/home/ptisnovs/.vim/gadgets/linux/debugpy/build/lib/debugpy/adapter"
  ],
  "configuration": {
    "python": "/usr/bin/python3"
  },
  "custom_handler": "vimspector.custom.python.Debugpy",
  "name": "debugpy",
  "env": {},
  "cwd": "/home/ptisnovs"
}
--------------------------------------------------------------------------------
Configuration:
--------------------------------------------------------------------------------
{
  "adapter": "debugpy",
  "configuration": {
    "name": "run the executable",
    "type": "python",
    "request": "launch",
    "python.pythonPath": "/usr/bin/python3",
    "program": "/home/ptisnovs/add.py"
  },
  "breakpoints": {
    "exception": {
      "raised": "N",
      "caught": "N",
      "uncaught": "Y",
      "userUnhandled": "N"
    }
  }
}
--------------------------------------------------------------------------------
API Prefix:
Launch/Init: True / True
Workspace Root: /home/ptisnovs
Launch Config:
--------------------------------------------------------------------------------
{
  "python": "/usr/bin/python3",
  "name": "run the executable",
  "type": "python",
  "request": "launch",
  "python.pythonPath": "/usr/bin/python3",
  "program": "/home/ptisnovs/add.py"
}
--------------------------------------------------------------------------------
Server Capabilities:
--------------------------------------------------------------------------------
{
  "supportsCompletionsRequest": true,
  "supportsConditionalBreakpoints": true,
  "supportsConfigurationDoneRequest": true,
  "supportsDebuggerProperties": true,
  "supportsDelayedStackTraceLoading": true,
  "supportsEvaluateForHovers": true,
  "supportsExceptionInfoRequest": true,
  "supportsExceptionOptions": true,
  "supportsFunctionBreakpoints": true,
  "supportsHitConditionalBreakpoints": true,
  "supportsLogPoints": true,
  "supportsModulesRequest": true,
  "supportsSetExpression": true,
  "supportsSetVariable": true,
  "supportsValueFormattingOptions": true,
  "supportsTerminateRequest": true,
  "supportsGotoTargetsRequest": true,
  "supportsClipboardContext": true,
  "exceptionBreakpointFilters": [
    {
      "filter": "raised",
      "label": "Raised Exceptions",
      "default": false,
      "description": "Break whenever any exception is raised."
    },
    {
      "filter": "uncaught",
      "label": "Uncaught Exceptions",
      "default": true,
      "description": "Break when the process is exiting due to unhandled exception."
    },
    {
      "filter": "userUnhandled",
      "label": "User Uncaught Exceptions",
      "default": false,
      "description": "Break when exception escapes into library code."
    }
  ],
  "supportsStepInTargetsRequest": true
}
--------------------------------------------------------------------------------
Line Breakpoints:
--------------------------------------------------------------------------------
{
  "/home/ptisnovs/add.py": [
    {
      "state": "ENABLED",
      "line": 7,
      "options": {},
      "is_instruction_breakpoint": null,
      "sign_id": 2,
      "server_bp": {
        "0": {
          "verified": true,
          "id": 0,
          "source": {
            "name": "add.py",
            "path": "/home/ptisnovs/add.py"
          },
          "line": 7
        }
      }
    }
  ]
}
--------------------------------------------------------------------------------
Func Breakpoints:
--------------------------------------------------------------------------------
[]
--------------------------------------------------------------------------------
Ex Breakpoints:
--------------------------------------------------------------------------------
{
  "filters": [
    "uncaught"
  ],
  "exceptionOptions": []
}
--------------------------------------------------------------------------------

17. Příloha: základní klávesové zkratky pro ovládání Vimspectoru

Pro úplnost si uveďme základní klávesové zkratky, kterými se Vimspector ovládá. K dispozici jsou dvě sady zkratek nastavované globální proměnnou vimspector_enable_mappings:

let g:vimspector_enable_mappings = 'VISUAL_STUDIO'

nebo:

let g:vimspector_enable_mappings = 'HUMAN'

Toto nastavení proveďte ve vašem souboru .vimrc.

Klávesové zkratky v režimu, který napodobuje Visual Studio:

Klávesová zkratka Stručný popis
F5 spuštění debuggeru, popř. pokračování ladění
Shift + F5 zastavení debuggeru (nebude funkční ve všech terminálech)
F6 pozastavení ladění
F8 skok na další breakpoint, který byl nastaven v laděném souboru
Shift + F8 skok na předchozí breakpoint, který byl nastaven v laděném souboru
F9 nastavení breakpointu na aktuálním řádku popř. naopak odstranění breakpointu
Shift + F9 nastavení breakpointu pro výraz, který se nachází pod kurzorem
F10 krok při ladění bez vstupu do volané funkce
F11 krok při ladění se vstupem do volané funkce
Shift + F11 výskok z laděné funkce
Alt + 8 zobrazení disassemblovaného kódu (není funkční pro Python)
Poznámka: klávesové zkratky Shift + Fn nemusí být plně funkční ve všech terminálech.

Klávesové zkratky v režimu nazvaném „HUMAN“:

Klávesová zkratka Stručný popis
F5 spuštění debuggeru, popř. pokračování ladění
F3 zastavení debuggeru
F4 znovuspuštění debuggeru
F6 pozastavení ladění
F8 nastavení breakpointu pro výraz, který se nachází pod kurzorem
F9 nastavení breakpointu na aktuálním řádku, popř. naopak odstranění breakpointu
klávesa leader F8 doskok na místo, na kterém se nachází kurzor
F10 krok při ladění bez vstupu do volané funkce
F11 krok při ladění se vstupem do volané funkce
F12 výskok z laděné funkce

18. Závěr

Z Vimspectoru mám popravdě řečeno poněkud rozporuplné pocity. Na jednu stranu je patrné, jak se jeho autoři snaží o dosažení stejné funkcionality, kterou v současnosti od moderních debuggerů (nebo od uživatelských rozhraní k nim) očekáváme. Současně je možné Vimspector skutečně v praxi používat. A velkou výhodou může být, že jsou stále k dispozici vimovské klávesové zkratky, a to i v konzolích (takže budou fungovat regulární výrazy atd.). A navíc má uživatel možnost si plně přenastavit klávesové zkratky.

bitcoin_skoleni

Ovšem na stranu druhou je patrné, že autoři již narazili na meze možností Vimu. Stále se totiž jedná v první řadě o textový editor a nikoli o platformu určenou pro tvorbu přídavných modulů s plnohodnotným textovým či grafickým uživatelským rozhraním. I z tohoto důvodu spíše v praxi používám kombinaci Vimu pro tvorbu programového kódu a samostatně běžící debugger PuDB, s nímž jsme se již na Rootu seznámili.

Obrázek 17: Krokování aplikace v debuggeru PuDB. V tomto barevném schématu je aktuální řádek zobrazen inverzně bíle. Navíc je zapnuto zobrazení čísel řádků, takže vidíme, že se nacházíme ve zdrojovém kódu na řádku číslo 47.

19. Odkazy na relevantní články na Rootu

  1. Užitečné skripty a pluginy pro textový editor Vim
    http://www.root.cz/clanky/uzitecne-skripty-a-pluginy-pro-textovy-editor-vim/
  2. Užitečné skripty a pluginy pro textový editor Vim (2.část)
    http://www.root.cz/clanky/uzitecne-skripty-a-pluginy-pro-textovy-editor-vim-2-cast/
  3. Užitečné skripty a pluginy pro textový editor Vim (3.část)
    http://www.root.cz/clanky/uzitecne-skripty-a-pluginy-pro-textovy-editor-vim-3-cast/
  4. Užitečné skripty a pluginy pro textový editor Vim (4.část)
    http://www.root.cz/clanky/uzitecne-skripty-a-pluginy-pro-textovy-editor-vim-4-cast/
  5. Užitečné skripty a pluginy pro textový editor Vim (5.část)
    http://www.root.cz/clanky/uzitecne-skripty-a-pluginy-pro-textovy-editor-vim-5-cast/
  6. Užitečné skripty a pluginy pro textový editor Vim (6.část)
    http://www.root.cz/clanky/uzitecne-skripty-a-pluginy-pro-textovy-editor-vim-6-cast-cestovani-v-case/
  7. Užitečné skripty a pluginy pro textový editor Vim (7.část)
    http://www.root.cz/clanky/uzitecne-skripty-a-pluginy-pro-textovy-editor-vim-7-cast/
  8. Tvorba vlastního pluginu pro textový editor Vim
    http://www.root.cz/clanky/tvorba-vlastniho-pluginu-pro-textovy-editor-vim/
  9. Vim ve funkci textového editoru pro tvůrčí psaní
    https://www.root.cz/clanky/vim-ve-funkci-textoveho-editoru-pro-tvurci-psani/
  10. Asynchronní skripty: další přiblížení Vimu k možnostem IDE
    https://www.root.cz/clanky/asynchronni-skripty-dalsi-priblizeni-vimu-k-moznostem-ide/
  11. Evil: kombinace editačních příkazů Vimu a síly Emacsu
    https://www.root.cz/clanky/evil-kombinace-editacnich-prikazu-vimu-a-sily-emacsu/
  12. Spacemacs: to nejlepší z editorů Emacs a Vim
    https://www.root.cz/clanky/spacemacs-to-nejlepsi-z-editoru-emacs-a-vim/
  13. Spacemacs: práce s projekty psanými v Pythonu a režim Org
    https://www.root.cz/clanky/spacemacs-prace-s-projekty-psanymi-v-pythonu-a-rezim-org/
  14. Projekt SpaceVim – moderní distribuce Vimu inspirovaná Spacemacsem
    https://www.root.cz/clanky/projekt-spacevim-moderni-distribuce-vimu-inspirovana-spacemacsem/
  15. PuDB: výkonný debugger pro Python s retro uživatelským rozhraním
    https://www.root.cz/clanky/pudb-vykonny-debugger-pro-python-s-retro-uzivatelskym-rozhranim/

20. Odkazy na Internetu

  1. vimspectorpy – python default configurations for vimspector
    https://github.com/sagi-z/vimspectorpy
  2. Setting up Vimspector
    https://puremourning.github­.io/vimspector-web/demo-setup.html#starting-debugging
  3. Vimspector na GitHubu
    https://github.com/puremou­rning/vimspector
  4. Vimspector releases
    https://github.com/puremou­rning/vimspector/releases
  5. Poslední dostupný build Vimspectoru
    https://github.com/puremou­rning/vimspector/releases/tag/6997902219
  6. Vimspector configuration
    https://puremourning.github­.io/vimspector/configurati­on.html#python-debugpy-example
  7. Užitečné skripty a pluginy pro textový editor Vim: propojení Vimu s debuggery
    https://www.root.cz/clanky/uzitecne-skripty-a-pluginy-pro-textovy-editor-vim-propojeni-vimu-s-debuggery/
  8. Introduction to the PuDB Python Debugging Tool
    http://heather.cs.ucdavis­.edu/~matloff/pudb.html
  9. pudb’s documentation
    https://documen.tician.de/pudb/
  10. pudb 2018.1 na PyPi
    https://pypi.org/project/pudb/
  11. PuDB, the IDE debugger without an IDE!
    https://www.youtube.com/watch?v=IEXx-AQLOBk
  12. Debuggery a jejich nadstavby v Linuxu
    http://mojefedora.cz/debuggery-a-jejich-nadstavby-v-linuxu/
  13. Debuggery a jejich nadstavby v Linuxu (2. část)
    http://mojefedora.cz/debuggery-a-jejich-nadstavby-v-linuxu-2-cast/
  14. Debuggery a jejich nadstavby v Linuxu (3): Nemiver
    http://mojefedora.cz/debuggery-a-jejich-nadstavby-v-linuxu-3-nemiver/
  15. Debuggery a jejich nadstavby v Linuxu (4): KDbg
    http://mojefedora.cz/debuggery-a-jejich-nadstavby-v-linuxu-4-kdbg/
  16. Debuggery a jejich nadstavby v Linuxu (5): ladění aplikací v editorech Emacs a Vim
    http://mojefedora.cz/debuggery-a-jejich-nadstavby-v-linuxu-5-ladeni-aplikaci-v-editorech-emacs-a-vim/
  17. Pyclewn installation notes
    http://pyclewn.sourceforge­.net/install.html
  18. Clewn
    http://clewn.sourceforge.net/
  19. Clewn installation
    http://clewn.sourceforge.net/in­stall.html
  20. Clewn – soubory
    http://sourceforge.net/pro­jects/clewn/files/OldFiles/
  21. Writing Vim Plugins
    http://stevelosh.com/blog/2011/09/wri­ting-vim-plugins/

Autor článku

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