1
2" Vim script glue code for LLDB integration
3
4function! s:FindPythonScriptDir()
5  for dir in pathogen#split(&runtimepath)
6    let searchstr = "python-vim-lldb"
7    let candidates = pathogen#glob_directories(dir . "/" . searchstr)
8    if len(candidates) > 0
9      return candidates[0]
10    endif
11  endfor
12  return
13endfunction()
14
15function! s:InitLldbPlugin()
16  if has('python') == 0
17    call confirm('ERROR: This Vim installation does not have python support. lldb.vim will not work.')
18    return
19  endif
20  
21  " Key-Bindings
22  " FIXME: choose sensible keybindings for:
23  " - process: start, interrupt, continue, continue-to-cursor
24  " - step: instruction, in, over, out
25  "
26  if has('gui_macvim')
27    " Apple-B toggles breakpoint on cursor
28    map <D-B>     :Lbreakpoint<CR>
29  endif
30
31  "
32  " Setup the python interpreter path
33  "
34  let vim_lldb_pydir = s:FindPythonScriptDir()
35  execute 'python import sys; sys.path.append("' . vim_lldb_pydir . '")'
36
37  "
38  " Register :L<Command>
39  " The LLDB CommandInterpreter provides tab-completion in Vim's command mode.
40  " FIXME: this list of commands, at least partially should be auto-generated
41  "
42
43  " Window show/hide commands
44  command -complete=custom,s:CompleteWindow -nargs=1 Lhide               python ctrl.doHide('<args>')
45  command -complete=custom,s:CompleteWindow -nargs=0 Lshow               python ctrl.doShow('<args>')
46 
47  " Launching convenience commands (no autocompletion)
48  command -nargs=* Lstart                                                python ctrl.doLaunch(True,  '<args>')
49  command -nargs=* Lrun                                                  python ctrl.doLaunch(False, '<args>')
50  command -nargs=1 Lattach                                               python ctrl.doAttach('<args>')
51  command -nargs=0 Ldetach                                               python ctrl.doDetach()
52
53  " Regexp-commands: because vim's command mode does not support '_' or '-'
54  " characters in command names, we omit them when creating the :L<cmd>
55  " equivalents.
56  command -complete=custom,s:CompleteCommand -nargs=* Lregexpattach      python ctrl.doCommand('_regexp-attach', '<args>')
57  command -complete=custom,s:CompleteCommand -nargs=* Lregexpbreak       python ctrl.doCommand('_regexp-break', '<args>')
58  command -complete=custom,s:CompleteCommand -nargs=* Lregexpbt          python ctrl.doCommand('_regexp-bt', '<args>')
59  command -complete=custom,s:CompleteCommand -nargs=* Lregexpdown        python ctrl.doCommand('_regexp-down', '<args>')
60  command -complete=custom,s:CompleteCommand -nargs=* Lregexptbreak      python ctrl.doCommand('_regexp-tbreak', '<args>')
61  command -complete=custom,s:CompleteCommand -nargs=* Lregexpdisplay     python ctrl.doCommand('_regexp-display', '<args>')
62  command -complete=custom,s:CompleteCommand -nargs=* Lregexpundisplay   python ctrl.doCommand('_regexp-undisplay', '<args>')
63  command -complete=custom,s:CompleteCommand -nargs=* Lregexpup          python ctrl.doCommand('_regexp-up', '<args>')
64
65  command -complete=custom,s:CompleteCommand -nargs=* Lapropos           python ctrl.doCommand('apropos', '<args>')
66  command -complete=custom,s:CompleteCommand -nargs=* Lbacktrace         python ctrl.doCommand('bt', '<args>')
67  command -complete=custom,s:CompleteCommand -nargs=* Lbreakpoint        python ctrl.doBreakpoint('<args>')
68  command -complete=custom,s:CompleteCommand -nargs=* Lcommand           python ctrl.doCommand('command', '<args>')
69  command -complete=custom,s:CompleteCommand -nargs=* Ldisassemble       python ctrl.doCommand('disassemble', '<args>')
70  command -complete=custom,s:CompleteCommand -nargs=* Lexpression        python ctrl.doCommand('expression', '<args>')
71  command -complete=custom,s:CompleteCommand -nargs=* Lhelp              python ctrl.doCommand('help', '<args>')
72  command -complete=custom,s:CompleteCommand -nargs=* Llog               python ctrl.doCommand('log', '<args>')
73  command -complete=custom,s:CompleteCommand -nargs=* Lplatform          python ctrl.doCommand('platform','<args>')
74  command -complete=custom,s:CompleteCommand -nargs=* Lplugin            python ctrl.doCommand('plugin', '<args>')
75  command -complete=custom,s:CompleteCommand -nargs=* Lprocess           python ctrl.doProcess('<args>')
76  command -complete=custom,s:CompleteCommand -nargs=* Lregister          python ctrl.doCommand('register', '<args>')
77  command -complete=custom,s:CompleteCommand -nargs=* Lscript            python ctrl.doCommand('script', '<args>')
78  command -complete=custom,s:CompleteCommand -nargs=* Lsettings          python ctrl.doCommand('settings','<args>')
79  command -complete=custom,s:CompleteCommand -nargs=* Lsource            python ctrl.doCommand('source', '<args>')
80  command -complete=custom,s:CompleteCommand -nargs=* Ltype              python ctrl.doCommand('type', '<args>')
81  command -complete=custom,s:CompleteCommand -nargs=* Lversion           python ctrl.doCommand('version', '<args>')
82  command -complete=custom,s:CompleteCommand -nargs=* Lwatchpoint        python ctrl.doCommand('watchpoint', '<args>')
83 
84  " Convenience (shortcut) LLDB commands
85  command -complete=custom,s:CompleteCommand -nargs=* Lprint             python ctrl.doCommand('print', vim.eval("s:CursorWord('<args>')"))
86  command -complete=custom,s:CompleteCommand -nargs=* Lpo                python ctrl.doCommand('po', vim.eval("s:CursorWord('<args>')"))
87  command -complete=custom,s:CompleteCommand -nargs=* LpO                python ctrl.doCommand('po', vim.eval("s:CursorWORD('<args>')"))
88  command -complete=custom,s:CompleteCommand -nargs=* Lbt                python ctrl.doCommand('bt', '<args>')
89
90  " Frame/Thread-Selection (commands that also do an Uupdate but do not
91  " generate events in LLDB)
92  command -complete=custom,s:CompleteCommand -nargs=* Lframe             python ctrl.doSelect('frame', '<args>')
93  command -complete=custom,s:CompleteCommand -nargs=? Lup                python ctrl.doCommand('up', '<args>',     print_on_success=False, goto_file=True)
94  command -complete=custom,s:CompleteCommand -nargs=? Ldown              python ctrl.doCommand('down', '<args>', print_on_success=False, goto_file=True)
95  command -complete=custom,s:CompleteCommand -nargs=* Lthread            python ctrl.doSelect('thread', '<args>')
96
97  command -complete=custom,s:CompleteCommand -nargs=* Ltarget            python ctrl.doTarget('<args>')
98
99  " Continue
100  command -complete=custom,s:CompleteCommand -nargs=* Lcontinue          python ctrl.doContinue()
101
102  " Thread-Stepping (no autocompletion)
103  command -nargs=0 Lstepinst                                             python ctrl.doStep(StepType.INSTRUCTION)
104  command -nargs=0 Lstepinstover                                         python ctrl.doStep(StepType.INSTRUCTION_OVER)
105  command -nargs=0 Lstepin                                               python ctrl.doStep(StepType.INTO)
106  command -nargs=0 Lstep                                                 python ctrl.doStep(StepType.INTO)
107  command -nargs=0 Lnext                                                 python ctrl.doStep(StepType.OVER)
108  command -nargs=0 Lfinish                                               python ctrl.doStep(StepType.OUT)
109
110  " hack: service the LLDB event-queue when the cursor moves
111  " FIXME: some threaded solution would be better...but it
112  "        would have to be designed carefully because Vim's APIs are non threadsafe;
113  "        use of the vim module **MUST** be restricted to the main thread.
114  command -nargs=0 Lrefresh python ctrl.doRefresh()
115  autocmd CursorMoved * :Lrefresh
116  autocmd CursorHold  * :Lrefresh
117  autocmd VimLeavePre * python ctrl.doExit()
118
119  execute 'pyfile ' . vim_lldb_pydir . '/plugin.py'
120endfunction()
121
122function! s:CompleteCommand(A, L, P)
123  python << EOF
124a = vim.eval("a:A")
125l = vim.eval("a:L")
126p = vim.eval("a:P")
127returnCompleteCommand(a, l, p)
128EOF
129endfunction()
130
131function! s:CompleteWindow(A, L, P)
132  python << EOF
133a = vim.eval("a:A")
134l = vim.eval("a:L")
135p = vim.eval("a:P")
136returnCompleteWindow(a, l, p)
137EOF
138endfunction()
139
140" Returns cword if search term is empty
141function! s:CursorWord(term) 
142  return empty(a:term) ? expand('<cword>') : a:term 
143endfunction()
144
145" Returns cleaned cWORD if search term is empty
146function! s:CursorWORD(term) 
147  " Will strip all non-alphabetic characters from both sides
148  return empty(a:term) ?  substitute(expand('<cWORD>'), '^\A*\(.\{-}\)\A*$', '\1', '') : a:term 
149endfunction()
150
151call s:InitLldbPlugin()
152