[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/vim-vdebug/vdebug/master/plugin/vdebug.vim [Back]  [Original]

" Vdebug: Powerful, fast, multi-language debugger client for Vim.
"
" Script Info  {{{
"=============================================================================
"    Copyright: Copyright (C) 2012 Jon Cairns
"      Licence: The MIT Licence (see LICENCE file)
" Name Of File: vdebug.vim
"  Description: Multi-language debugger client for Vim (PHP, Ruby, Python,
"               Perl, NodeJS)
"   Maintainer: Jon Cairns 
"      Version: 2.0.0
"               Inspired by the Xdebug plugin, which was originally written by
"               Seung Woo Shin  and extended by many
"               others.
"        Usage: Use :help Vdebug for information on how to configure and use
"               this script, or visit the Github page
"               https://github.com/vim-vdebug/vdebug.
"
"=============================================================================
" }}}

" avoid double loading of vdebug
if exists('g:is_vdebug_loaded')
    finish
endif

" Set a special flag used only by this plugin for preventing doubly
" loading the script.
let g:is_vdebug_loaded = 1

" Do not source this script when python is not compiled in.
if !has('python3')
    echomsg ':python3 is not available, vdebug will not be loaded.'
    finish
endif

if !exists('g:vdebug_force_ascii')
    " Nice characters get screwed up on windows
    if has('win32') || has('win64')
        let g:vdebug_force_ascii = 1
    elseif has('multi_byte') == 0
        let g:vdebug_force_ascii = 1
    else
        let g:vdebug_force_ascii = 0
    end
endif

if !exists('g:vdebug_options')
    let g:vdebug_options = {}
endif

if !exists('g:vdebug_keymap')
    let g:vdebug_keymap = {}
endif

if !exists('g:vdebug_features')
    let g:vdebug_features = {}
endif

if !exists('g:vdebug_leader_key')
    let g:vdebug_leader_key = ''
endif

let g:vdebug_keymap_defaults = {
\    'run' : '',
\    'run_to_cursor' : '',
\    'step_over' : '',
\    'step_into' : '',
\    'step_out' : '',
\    'close' : '',
\    'detach' : '',
\    'set_breakpoint' : '',
\    'get_context' : '',
\    'eval_under_cursor' : '',
\    'eval_visual' : 'e'
\}

let g:vdebug_options_defaults = {
\    'port' : 9000,
\    'timeout' : 20,
\    'server' : '',
\    "proxy_host" : '',
\    "proxy_port" : 9001,
\    'on_close' : 'stop',
\    'break_on_open' : 1,
\    'ide_key' : '',
\    'debug_window_level' : 0,
\    'debug_file_level' : 0,
\    'debug_file' : '',
\    'path_maps' : {},
\    'watch_window_style' : 'expanded',
\    'marker_default' : '',
\    'marker_closed_tree' : '',
\    'marker_open_tree' : '',
\    'sign_breakpoint' : '',
\    'sign_current' : '',
\    'sign_current_stack_position' : '',
\    'sign_disabled': '',
\    'continuous_mode'  : 1,
\    'background_listener' : 1,
\    'auto_start' : 1,
\    'simplified_status': 1,
\    'layout': 'vertical',
\}

" Different symbols for non unicode Vims
if g:vdebug_force_ascii == 1
    let g:vdebug_options_defaults['marker_default'] = '*'
    let g:vdebug_options_defaults['marker_closed_tree'] = '+'
    let g:vdebug_options_defaults['marker_open_tree'] = '-'
    let g:vdebug_options_defaults['sign_breakpoint'] = 'B>'
    let g:vdebug_options_defaults['sign_current'] = '->'
    let g:vdebug_options_defaults['sign_current_stack_position'] = '->'
    let g:vdebug_options_defaults['sign_disabled'] = 'B|'
endif

" Create the top dog
python3 import vdebug.debugger_interface
python3 debugger = vdebug.debugger_interface.DebuggerInterface()

" Commands
command! -nargs=? VdebugChangeStack python3 debugger.change_stack()
command! -nargs=? -complete=customlist,s:BreakpointTypes Breakpoint python3 debugger.cycle_breakpoint()
command! -nargs=? -complete=customlist,s:BreakpointTypes SetBreakpoint python3 debugger.set_breakpoint()
command! VdebugStart python3 debugger.run()
command! -nargs=? BreakpointRemove python3 debugger.remove_breakpoint()
command! -nargs=? BreakpointToggle python3 debugger.toggle_breakpoint()
command! BreakpointWindow python3 debugger.toggle_breakpoint_window()
command! -nargs=? -bang VdebugEval python3 debugger.handle_eval('', )
command! -nargs=+ -complete=customlist,s:OptionNames VdebugOpt :call Vdebug_set_option()
command! -nargs=+ VdebugPathMap :call Vdebug_path_map()
command! -nargs=+ VdebugAddPathMap :call Vdebug_add_path_map()
command! -nargs=? VdebugTrace python3 debugger.handle_trace()
command! -nargs=? BreakpointStatus python3 debugger.breakpoint_status()

if hlexists('DbgCurrentLine') == 0
    hi default DbgCurrentLine term=reverse ctermfg=White ctermbg=Red guifg=#ffffff guibg=#ff0000
end
if hlexists('DbgCurrentSign') == 0
    hi default DbgCurrentSign term=reverse ctermfg=White ctermbg=Red guifg=#ffffff guibg=#ff0000
end
if hlexists('DbgBreakptLine') == 0
    hi default DbgBreakptLine term=reverse ctermfg=White ctermbg=Green guifg=#ffffff guibg=#00ff00
end
if hlexists('DbgBreakptSign') == 0
    hi default DbgBreakptSign term=reverse ctermfg=White ctermbg=Green guifg=#ffffff guibg=#00ff00
end
if hlexists('DbgDisabledLine') == 0
  highlight DbgDisabledLine term=reverse ctermbg=White ctermfg=Cyan guibg=#b4ee9a guifg=#888888
endif
if hlexists('DbgDisabledSign') == 0
  highlight DbgDisabledSign term=reverse ctermbg=White ctermfg=Cyan guibg=#b4ee9a guifg=#888888
endif
if hlexists('DbgCurrentStackPositionSign') == 0
  highlight DbgCurrentStackPositionSign term=reverse ctermbg=White ctermfg=Cyan guibg=#e17e67 guifg=#888888
endif
if hlexists('DbgCurrentStackPositionLine') == 0
  highlight DbgCurrentStackPositionLine term=reverse ctermbg=White ctermfg=Cyan guibg=#e17e67 guifg=#888888
endif

" Signs and highlighted lines for breakpoints, etc.
function! s:DefineSigns()
    exe 'sign define breakpt text=' . g:vdebug_options['sign_breakpoint'] . ' texthl=DbgBreakptSign linehl=DbgBreakptLine'
    exe 'sign define current text=' . g:vdebug_options['sign_current'] . ' texthl=DbgCurrentSign linehl=DbgCurrentLine'
    exe 'sign define breakpt_dis text=' . g:vdebug_options['sign_disabled'] . ' texthl=DbgDisabledSign linehl=DbgDisabledLine'
    exe 'sign define current_stack_position text=' . g:vdebug_options['sign_current_stack_position'] . ' texthl=DbgCurrentStackPositionSign linehl=DbgCurrentStackPositionLine'
endfunction

function! s:BreakpointTypes(A,L,P)
    let arg_to_cursor = strpart(a:L,11,a:P)
    let space_idx = stridx(arg_to_cursor,' ')
    if space_idx == -1
        return filter(['conditional ','exception ','return ','call ','watch '],'v:val =~ "^".a:A.".*"')
    else
        return []
    endif
endfunction

function! s:HandleEval(bang,code)
    let code = escape(a:code,'"')
    if strlen(a:bang)
        execute 'python3 debugger.save_eval("'.code.'")'
    endif
    if strlen(a:code)
        execute 'python3 debugger.handle_eval("'.code.'")'
    endif
endfunction

" Reload options dictionary, by merging with default options.
"
" This should be called if you want to update the options after vdebug has
" been loaded.
function! Vdebug_load_options(options)
    " Merge options with defaults
    let g:vdebug_options = extend(g:vdebug_options_defaults, a:options)

    " Override with single defined params ie. g:vdebug_options_port
    let single_defined_params = s:Vdebug_get_options()
    let g:vdebug_options = extend(g:vdebug_options, single_defined_params)

    call s:DefineSigns()
    python3 debugger.reload_options()
endfunction

" Get options defined outside of the vdebug_options dictionary
"
" This helps for when users might want to define a single option by itself
" without needing the dictionary ie. vdebug_options_port = 9000
function! s:Vdebug_get_options()
    let param_namespace = 'g:vdebug_options_'
    let param_namespace_len = strlen(param_namespace)

    " Get the paramter names and concat the g:vdebug_options namespace
    let parameters = map(keys(g:vdebug_options_defaults), 'param_namespace.v:val')

    " Only use the defined parameters
    let existing_params = filter(parameters, 'exists(v:val)')

    " put into a dictionary for use with extend()
    let params = {}
    for name in existing_params
      let val = eval(name)

      " Remove g:vdebug_options namespace from param
      let name = strpart(name, param_namespace_len)
      let params[name] = val
    endfor
    if !empty(params)
      echoerr 'Deprication Warning: The options g:vdebug_options_* are depricated.  Please use the g:vdebug_options dictionary.'
    endif
    return params
endfunction

" Assign keymappings, and merge with defaults.
"
" This should be called if you want to update the keymappings after vdebug has
" been loaded.
function! Vdebug_load_keymaps(keymaps)
    " Unmap existing keys, if needed
    " the keys should in theory exist because they are part of the defaults
    if has_key(g:vdebug_keymap, 'run')
        exe 'silent! nunmap '.g:vdebug_keymap['run']
    endif
    if has_key(g:vdebug_keymap, 'close')
        exe 'silent! nunmap '.g:vdebug_keymap['close']
    endif
    if has_key(g:vdebug_keymap, 'set_breakpoint')
        exe 'silent! nunmap '.g:vdebug_keymap['set_breakpoint']
    endif
    if has_key(g:vdebug_keymap, 'eval_visual')
        exe 'silent! vunmap '.g:vdebug_keymap['eval_visual']
    endif

    " Merge keymaps with defaults
    let g:vdebug_keymap = extend(g:vdebug_keymap_defaults, a:keymaps)

    " Mappings allowed in non-debug mode
    " XXX: don't use keymaps not found in g:vdebug_keymap_defaults
    exe 'noremap '.g:vdebug_keymap['run'].' :python3 debugger.run()'
    exe 'noremap '.g:vdebug_keymap['close'].' :python3 debugger.close()'
    exe 'noremap '.g:vdebug_keymap['set_breakpoint'].' :python3 debugger.set_breakpoint()'

    " Exceptional case for visual evaluation
    exe 'vnoremap '.g:vdebug_keymap['eval_visual'].' :python3 debugger.handle_visual_eval()'
    python3 debugger.reload_keymappings()
endfunction

function! s:OptionNames(A,L,P)
    let arg_to_cursor = strpart(a:L,10,a:P)
    let space_idx = stridx(arg_to_cursor,' ')
    if space_idx == -1
        return filter(keys(g:vdebug_options_defaults),'v:val =~ a:A')
    else
        let opt_name = strpart(arg_to_cursor,0,space_idx)
        if has_key(g:vdebug_options,opt_name)
            return [g:vdebug_options[opt_name]]
        else
            return []
        endif
    endif
endfunction

function! Vdebug_set_option(option, ...)
    if ! a:0
        let g:vdebug_options[a:option]
        return
    endif
    if a:option == 'path_maps'
        echomsg 'use :VdebugAddPathMap to add extra or :VdebugPathMap to set new'
        return
    elseif a:option == 'window_commands'
        echomsg 'update window_commands in your vimrc please'
        return
    elseif a:option == 'window_arrangement'
        echomsg 'update window_arrangement in your vimrc please'
        return
    endif
    echomsg 'Setting vdebug option "' . a:option . '" to: ' . a:1
    let g:vdebug_options[a:option] = a:1
    call s:DefineSigns()
    python3 debugger.reload_options()
endfunction

function! Vdebug_add_path_map(from, to)
    echomsg 'Adding vdebug path map "{' . a:from . ':' . a:to . '}"'
    let g:vdebug_options['path_maps'] = extend(g:vdebug_options['path_maps'], {a:from: a:to})
    python3 debugger.reload_options()
endfunction

function! Vdebug_path_map(from, to)
    echomsg 'Setting vdebug path maps to "{' . a:from . ':' . a:to . '}"'
    let g:vdebug_options['path_maps'] = {a:from: a:to}
    python3 debugger.reload_options()
endfunction

function! Vdebug_get_visual_selection()
  let [lnum1, col1] = getpos("'

Web Proxy Viewer  |  New URL  |  Original Page