diff --git a/vimfiles.stefan/vimrc b/vimfiles.stefan/vimrc index 036c802..3cacb16 100644 --- a/vimfiles.stefan/vimrc +++ b/vimfiles.stefan/vimrc @@ -1,11 +1,11 @@ " Setzen des Runtimepath, in dem die Vimfiles gesucht werden: +let &runtimepath = &runtimepath . ',' . g:vimfiles let &runtimepath = &runtimepath . ',' . g:vimsuite . '/vimfiles' let &runtimepath = &runtimepath . ',' . g:vimsuite . '/vimfiles.latex' let &runtimepath = &runtimepath . ',' . g:vimsuite . '/HTML' let &runtimepath = &runtimepath . ',' . g:vimsuite . '/vimfiles.damos' let &runtimepath = &runtimepath . ',' . g:vimsuite . '/vimfiles.cvim' let &runtimepath = &runtimepath . ',' . g:vimsuite . '/vimfiles.vjde' -let &runtimepath = &runtimepath . ',' . g:vimfiles " Laden weiterer Einstellungen: if has("win32") diff --git a/vimfiles/GetLatest/GetLatestVimScripts.dat b/vimfiles/GetLatest/GetLatestVimScripts.dat index 15ff6c8..53b617c 100644 --- a/vimfiles/GetLatest/GetLatestVimScripts.dat +++ b/vimfiles/GetLatest/GetLatestVimScripts.dat @@ -1,7 +1,7 @@ ScriptID SourceID Filename -------------------------- 1075 8501 netrw.vim -1502 7078 vimball.vim +1502 8515 vimball.vim 1008 3118 srec.vim (ftplugin) 1009 3119 srec.vim (syntax file) 475 2535 latex-suite (install in vimfiles.latex) diff --git a/vimfiles/autoload/vimball.vim b/vimfiles/autoload/vimball.vim index 5ed34f2..d896163 100644 --- a/vimfiles/autoload/vimball.vim +++ b/vimfiles/autoload/vimball.vim @@ -1,9 +1,9 @@ " vimball.vim : construct a file containing both paths and files " Author: Charles E. Campbell, Jr. -" Date: May 07, 2007 -" Version: 22 +" Date: Apr 01, 2008 +" Version: 25 " GetLatestVimScripts: 1502 1 :AutoInstall: vimball.vim -" Copyright: (c) 2004-2006 by Charles E. Campbell, Jr. +" Copyright: (c) 2004-2007 by Charles E. Campbell, Jr. " The VIM LICENSE applies to Vimball.vim, and Vimball.txt " (see |copyright|) except use "Vimball" instead of "Vim". " No warranty, express or implied. @@ -15,8 +15,9 @@ if &cp || exists("g:loaded_vimball") || v:version < 700 finish endif let s:keepcpo = &cpo -let g:loaded_vimball = "v22" +let g:loaded_vimball = "v25" set cpo&vim +"DechoTabOn " ===================================================================== " Constants: {{{1 @@ -24,6 +25,37 @@ if !exists("s:USAGE") let s:USAGE = 0 let s:WARNING = 1 let s:ERROR = 2 + if exists("g:vimball_shq") && !exists("g:netrw_shq") + let g:netrw_shq= g:vimball_shq + endif + if !exists("g:netrw_cygwin") + if has("win32") || has("win95") || has("win64") || has("win16") + if &shell =~ '\%(\\|\\)\%(\.exe\)\=$' + let g:netrw_cygwin= 1 + else + let g:netrw_cygwin= 0 + endif + else + let g:netrw_cygwin= 0 + endif + endif + if !exists("g:netrw_shq") + if exists("&shq") && &shq != "" + let g:netrw_shq= &shq + elseif has("win32") || has("win95") || has("win64") || has("win16") + if g:netrw_cygwin + let g:netrw_shq= "'" + else + let g:netrw_shq= '"' + endif + else + let g:netrw_shq= "'" + endif +" call Decho("g:netrw_shq<".g:netrw_shq.">") + endif + if !exists("g:vimball_path_escape") + let g:vimball_path_escape= ' ;#%' + endif endif " ===================================================================== @@ -31,7 +63,12 @@ endif " --------------------------------------------------------------------- " vimball#MkVimball: creates a vimball given a list of paths to files {{{2 -" Vimball Format: +" Input: +" line1,line2: a range of lines containing paths to files to be included in the vimball +" writelevel : if true, force a write to filename.vba, even if it exists +" (usually accomplished with :MkVimball! ... +" filename : base name of file to be created (ie. filename.vba) +" Output: a filename.vba using vimball format: " path " filesize " [file] @@ -127,6 +164,7 @@ fun! vimball#MkVimball(line1,line2,writelevel,...) range " write the vimball exe "tabn ".vbtabnr call s:ChgDir(curdir) + setlocal ff=unix if a:writelevel let vbnamepath= s:Path(vbname,'') " call Decho("exe w! ".vbnamepath) @@ -152,6 +190,8 @@ endfun " --------------------------------------------------------------------- " vimball#Vimball: extract and distribute contents from a vimball {{{2 +" (invoked the the UseVimball command embedded in +" vimballs' prologue) fun! vimball#Vimball(really,...) " call Dfunc("vimball#Vimball(really=".a:really.") a:0=".a:0) @@ -163,7 +203,8 @@ fun! vimball#Vimball(really,...) " set up standard settings call s:SaveSettings() - let curtabnr = tabpagenr() + let curtabnr = tabpagenr() + let vimballfile = expand("%:tr") " set up vimball tab " call Decho("setting up vimball tab") @@ -186,16 +227,18 @@ fun! vimball#Vimball(really,...) " call Decho("curdir<".curdir.">") call s:ChgDir(home) - call vimball#RmVimball() + let s:ok_unablefind= 1 + call vimball#RmVimball(vimballfile) + unlet s:ok_unablefind let linenr = 4 let filecnt = 0 " give title to listing of (extracted) files from Vimball Archive if a:really - echohl Title | echomsg "Vimball Archive" | echohl None - else - echohl Title | echomsg "Vimball Archive Listing" | echohl None + echohl Title | echomsg "Vimball Archive" | echohl None + else + echohl Title | echomsg "Vimball Archive Listing" | echohl None echohl Statement | echomsg "files would be placed under: ".home | echohl None endif @@ -206,7 +249,7 @@ fun! vimball#Vimball(really,...) while 1 < linenr && linenr < line("$") let fname = substitute(getline(linenr),'\t\[\[\[1$','','') let fname = substitute(fname,'\\','/','g') - let fsize = getline(linenr+1) + let fsize = getline(linenr+1)+0 let filecnt = filecnt + 1 " call Decho("fname<".fname."> fsize=".fsize." filecnt=".filecnt) @@ -257,6 +300,7 @@ fun! vimball#Vimball(really,...) " copy "a" buffer into tab " call Decho('copy "a buffer into tab#'.vbtabnr) exe "tabn ".vbtabnr + setlocal ma silent! %d silent put a 1 @@ -277,21 +321,20 @@ fun! vimball#Vimball(really,...) " set up help if its a doc/*.txt file " call Decho("didhelp<".didhelp."> fname<".fname.">") - if a:really && didhelp == "" && fname =~ 'doc/[^/]\+\.txt$' - let didhelp= substitute(fname,'^\(.*\") endif " update for next file -" let oldlinenr = linenr " Decho - let linenr = linenr + fsize -" call Decho("update linenr= [linenr=".oldlinenr."] + [fsize=".fsize."] = ".linenr) +" call Decho("update linenr= [linenr=".linenr."] + [fsize=".fsize."] = ".(linenr+fsize)) + let linenr= linenr + fsize endwhile " set up help " call Decho("about to set up help: didhelp<".didhelp.">") if didhelp != "" - let htpath= escape(substitute(s:Path(home."/".didhelp,'"'),'"','','g'),' ') + let htpath= s:Path(home."/".didhelp,"") " call Decho("exe helptags ".htpath) exe "helptags ".htpath echo "did helptags" @@ -334,7 +377,8 @@ fun! vimball#RmVimball(...) " call Decho("turned off all events") if a:0 == 0 - let curfile= '^'.expand("%:tr") + let curfile= expand("%:tr") +" call Decho("case a:0=0: curfile<".curfile."> (used expand(%:tr))") else if a:1 =~ '[\/]' call vimball#ShowMesg(s:USAGE,"RmVimball vimballname [path]") @@ -342,11 +386,10 @@ fun! vimball#RmVimball(...) return endif let curfile= a:1 +" call Decho("case a:0=".a:0.": curfile<".curfile.">") endif - if curfile !~ '.vba$' - let curfile= curfile.".vba: " - else - let curfile= curfile.": " + if curfile =~ '\.vba$' + let curfile= substitute(curfile,'\.vba','','') endif if a:0 >= 2 let home= expand(a:2) @@ -365,13 +408,31 @@ fun! vimball#RmVimball(...) keepalt keepjumps 1split silent! keepalt keepjumps e .VimballRecord let keepsrch= @/ - if search(curfile,'cw') - let exestring= substitute(getline("."),curfile,'','') +" call Decho("search for ^".curfile.".vba:") +" call Decho("search for ^".curfile."[-0-9.]*.vba:") + if search('^'.curfile.": ".'cw') + let foundit= 1 + elseif search('^'.curfile.".vba: ",'cw') + let foundit= 1 + elseif search('^'.curfile.'[-0-9.]*.vba: ','cw') + let foundit= 1 + else + let foundit = 0 + endif + if foundit + let exestring= substitute(getline("."),'^'.curfile.'\S\{-}\.vba: ','','') " call Decho("exe ".exestring) silent! keepalt keepjumps exe exestring silent! keepalt keepjumps d + let exestring= strlen(substitute(exestring,'call delete(.\{-})|\=',"D","g")) +" call Decho("exestring<".exestring.">") + echomsg "removed ".exestring." files" else -" call Decho("unable to find <".curfile."> in .VimballRecord") + let curfile= substitute(curfile,'\.vba','','') +" call Decho("unable to find <".curfile."> in .VimballRecord") + if !exists("s:ok_unablefind") + call vimball#ShowMesg(s:WARNING,"(RmVimball) unable to find <".curfile."> in .VimballRecord") + endif endif silent! keepalt keepjumps g/^\s*$/d silent! keepalt keepjumps wq! @@ -393,17 +454,26 @@ fun! vimball#Decompress(fname) " decompression: if expand("%") =~ '.*\.gz' && executable("gunzip") - exe "!gunzip ".a:fname + silent exe "!gunzip ".s:Escape(a:fname) + if v:shell_error != 0 + call vimball#ShowMesg(s:WARNING,"(vimball#Decompress) gunzip may have failed with <".a:fname.">") + endif let fname= substitute(a:fname,'\.gz$','','') exe "e ".escape(fname,' \') call vimball#ShowMesg(s:USAGE,"Source this file to extract it! (:so %)") elseif expand("%") =~ '.*\.bz2' && executable("bunzip2") - exe "!bunzip2 ".a:fname + silent exe "!bunzip2 ".s:Escape(a:fname) + if v:shell_error != 0 + call vimball#ShowMesg(s:WARNING,"(vimball#Decompress) bunzip2 may have failed with <".a:fname.">") + endif let fname= substitute(a:fname,'\.bz2$','','') exe "e ".escape(fname,' \') call vimball#ShowMesg(s:USAGE,"Source this file to extract it! (:so %)") elseif expand("%") =~ '.*\.zip' && executable("unzip") - exe "!unzip ".a:fname + silent exe "!unzip ".s:Escape(a:fname) + if v:shell_error != 0 + call vimball#ShowMesg(s:WARNING,"(vimball#Decompress) unzip may have failed with <".a:fname.">") + endif let fname= substitute(a:fname,'\.zip$','','') exe "e ".escape(fname,' \') call vimball#ShowMesg(s:USAGE,"Source this file to extract it! (:so %)") @@ -443,10 +513,6 @@ fun! vimball#ShowMesg(level,msg) " call Dret("vimball#ShowMesg") endfun - -" --------------------------------------------------------------------- -let &cpo= s:keepcpo -unlet s:keepcpo " ===================================================================== " s:ChgDir: change directory (in spite of Windoze) {{{2 fun! s:ChgDir(newdir) @@ -456,21 +522,26 @@ fun! s:ChgDir(newdir) else exe 'silent cd '.escape(a:newdir,' ') endif -" call Dret("ChgDir") +" call Dret("ChgDir : curdir<".getcwd().">") endfun " --------------------------------------------------------------------- -" s:Path: prepend and append quotes, do escaping, as necessary {{{2 +" s:Path: prepend and append quotes and do escaping {{{2 fun! s:Path(cmd,quote) -" call Dfunc("Path(cmd<".a:cmd."> quote<".a:quote.">)") +" call Dfunc("Path(cmd<".a:cmd."> quote<".a:quote.">) vimball_path_escape<".g:vimball_path_escape.">") if (has("win32") || has("win95") || has("win64") || has("win16")) - let cmdpath= a:quote.substitute(a:cmd,'/','\\','g').a:quote +" let cmdpath= a:quote.substitute(a:cmd,'/','\\','g').a:quote + let cmdpath= a:quote.substitute(a:cmd,'\\','/','g').a:quote +" call Decho("cmdpath<".cmdpath."> (win32 mod)") else let cmdpath= a:quote.a:cmd.a:quote +" call Decho("cmdpath<".cmdpath."> (not-win32 mod)") endif - if a:quote == "" + if a:quote == "" && g:vimball_path_escape !~ ' ' let cmdpath= escape(cmdpath,' ') +" call Decho("cmdpath<".cmdpath."> (empty quote case)") endif + let cmdpath= escape(cmdpath,g:vimball_path_escape) " call Dret("Path <".cmdpath.">") return cmdpath endfun @@ -485,23 +556,20 @@ fun! s:RecordInVar(home,cmd) " else " let s:recorddir= s:recorddir."|".substitute(a:cmd,'^rmdir',"call s:Rmdir",'') " endif -" call Decho("recorddir=".s:recorddir) elseif !exists("s:recordfile") let s:recordfile= a:cmd -" call Decho("recordfile=".s:recordfile) else let s:recordfile= s:recordfile."|".a:cmd -" call Decho("recordfile=".s:recordfile) endif -" call Dret("RecordInVar") +" call Dret("RecordInVar : s:recordfile<".(exists("s:recordfile")? s:recordfile : "")."> s:recorddir<".(exists("s:recorddir")? s:recorddir : "").">") endfun " --------------------------------------------------------------------- " s:RecordInFile: {{{2 fun! s:RecordInFile(home) -" call Dfunc("RecordInFile()") +" call Dfunc("s:RecordInFile()") if exists("g:vimball_norecord") -" call Dret("RecordInFile : (g:vimball_norecord)") +" call Dret("s:RecordInFile : g:vimball_norecord") return endif @@ -509,8 +577,12 @@ fun! s:RecordInFile(home) let curdir= getcwd() call s:ChgDir(a:home) keepalt keepjumps 1split + let cmd= expand("%:tr").": " +" call Decho("cmd<".cmd.">") + silent! keepalt keepjumps e .VimballRecord + setlocal ma $ if exists("s:recordfile") && exists("s:recorddir") let cmd= cmd.s:recordfile."|".s:recorddir @@ -519,34 +591,32 @@ fun! s:RecordInFile(home) elseif exists("s:recordfile") let cmd= cmd.s:recordfile else -" call Dret("RecordInFile") +" call Dret("s:RecordInFile : neither recordfile nor recorddir exist") return endif +" call Decho("cmd<".cmd.">") + + " put command into buffer, write .VimballRecord `file keepalt keepjumps put=cmd silent! keepalt keepjumps g/^\s*$/d silent! keepalt keepjumps wq! call s:ChgDir(curdir) - if exists("s:recorddir") |unlet s:recorddir |endif - if exists("s:recordfile")|unlet s:recordfile|endif + + if exists("s:recorddir") +" call Decho("unlet s:recorddir<".s:recorddir.">") + unlet s:recorddir + endif + if exists("s:recordfile") +" call Decho("unlet s:recordfile<".s:recordfile.">") + unlet s:recordfile + endif else " call Decho("s:record[file|dir] doesn't exist") endif -" call Dret("RecordInFile") +" call Dret("s:RecordInFile") endfun -" --------------------------------------------------------------------- -" s:Rmdir: {{{2 -"fun! s:Rmdir(dirname) -"" call Dfunc("s:Rmdir(dirname<".a:dirname.">)") -" if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$' -" call system("del ".a:dirname) -" else -" call system("rmdir ".a:dirname) -" endif -"" call Dret("s:Rmdir") -"endfun - " --------------------------------------------------------------------- " s:VimballHome: determine/get home directory path (usually from rtp) {{{2 fun! s:VimballHome() @@ -587,11 +657,14 @@ fun! s:SaveSettings() let s:pmkeep = &pm let s:repkeep = &report let s:vekeep = &ve + let s:ffkeep = &ff if exists("&acd") - set ei=all ve=all noacd nofen noic report=999 nohid bt= ma lz pm= + setlocal ei=all ve=all noacd nofen noic report=999 nohid bt= ma lz pm= ff=unix else - set ei=all ve=all nofen noic report=999 nohid bt= ma lz pm= + setlocal ei=all ve=all nofen noic report=999 nohid bt= ma lz pm= ff=unix endif + " vimballs should be in unix format + setlocal ff=unix " call Dret("SaveSettings") endfun @@ -611,20 +684,34 @@ fun! s:RestoreSettings() let &report = s:repkeep let &ve = s:vekeep let &ei = s:eikeep + let &ff = s:ffkeep if s:makeep[0] != 0 " restore mark a " call Decho("restore mark-a: makeep=".string(makeep)) call setpos("'a",s:makeep) endif if exists("&acd") - unlet s:regakeep s:acdkeep s:eikeep s:fenkeep s:hidkeep s:ickeep s:repkeep s:vekeep s:makeep s:lzkeep s:pmkeep - else - unlet s:regakeep s:eikeep s:fenkeep s:hidkeep s:ickeep s:repkeep s:vekeep s:makeep s:lzkeep s:pmkeep + unlet s:acdkeep endif - set bt=nofile noma + unlet s:regakeep s:eikeep s:fenkeep s:hidkeep s:ickeep s:repkeep s:vekeep s:makeep s:lzkeep s:pmkeep s:ffkeep " call Dret("RestoreSettings") endfun +" --------------------------------------------------------------------- +" s:Escape: {{{2 +fun s:Escape(name) + " shellescape() was added by patch 7.0.111 + if exists("*shellescape") + return shellescape(a:name) + endif + return g:netrw_shq . a:name . g:netrw_shq +endfun + +" --------------------------------------------------------------------- +" Restore: +let &cpo= s:keepcpo +unlet s:keepcpo + " --------------------------------------------------------------------- " Modelines: {{{1 " vim: fdm=marker diff --git a/vimfiles/doc/VimPdb.txt b/vimfiles/doc/VimPdb.txt new file mode 100644 index 0000000..9275aad --- /dev/null +++ b/vimfiles/doc/VimPdb.txt @@ -0,0 +1,118 @@ +*VimPdb.txt* Vim Python Debugger + +VimPdb Beta +by Yaron Budowski + + +1. About +2. Features +3. Installation +4. Key Bindings +5. Customizing VimPdb +6. Known Issues + +============================ + +1. About +--------------- + +VimPdb allows you to debug Python programs like in a standard IDE (Step in/over, toggle breakpoint, etc). + + +2. Features +------------- + +- Highlighting of current debugged line. +- Opening the appropriate debugged file when needed. +- Highlighting of breakpoints. +- Save/Load current session breakpoints in files. +- IDE-Like debugging commands. + +3. Installation +---------------- + +Just drop VimPdb.py and VimPdb.vim into your plugin directory. Make sure the key bindings do not interfere with any existing ones. + +4. Key Bindings +----------------- + +- F5 - Start/continue debug session of current file. +- Ctrl-F5 - Start debugging and do not pause at first line +- Ctrl-Shift-F5 - Start debugging with a given list of parameters. +- Shift-F5 - Stop the current debug session. +- Ctrl-Alt-Shift-F5 - Restart the current debug session. + +- F2 - Toggle breakpoint. +- Ctrl-F2 - Toggle conditional breakpoint +- Shift-F2 - Toggle temporary breakpoint +- Ctrl-Shift-F2 - Clear all breakpoints in current file +- Ctrl-Alt-Shift-F2 - Clear all breakpoints in all files +- F11 - Print condition of conditional breakpoint under the cursor + +- F7 - Step into +- F8 - Step over +- Ctrl-F8 - Continue running until reaching a return from function + +- F6 - Move cursor to currently debugged line. +- Ctrl-F6 - Change current debugged line to where the cursor is currently placed. + +- F9 - Move up in stack frame. +- F10 - Move down in stack frame. + +- F12 - Print stack trace + +- F3 - Eval a given expression (in the current debug context) +- Ctrl-F3 - Exec a given statement (in the current debug context) + +- F4 - Eval the current word under the cursor (in the current debug context) +- Ctrl-F4 - Eval the current WORD under the cursor (in the current debug context) + +- s - Save current debug session breakpoints to a file. +- l - Load saved breakpoints from a file. + +5. Customizing VimPdb +----------------------- + +VimPdb.vim contains several options which allow the user to customize it: + +- stack_entry_format: the format used when printing the stack trace (using F12). Possible format keyword arguments: + * dir - the directory of the debugged file. + * filename - the filename of the debugged file. + * line - the current line number. + * function - the current function name. + * args - the arguments passed to the current function. + * return_value - the return value from the function. + * source_line - the source code of the current line. +- stack_entries_joiner: when there's more than one line of stack trace, this string is used to join the lines. +- stack_entry_prefix: each stack trace entry line has this as its prefix. +- current_stack_entry_prefix: the current stack trace entry line is prefixed with this string. + +- auto_load_breakpoints_file: when this is set to 1, VimPdb will look for a saved breakpoints + file (default_breakpoints_filename) in the current directory when loading a new debug session. +- auto_save_breakpoints_file: when this is set to 1, VimPdb will save all current session breakpoints into a + file (default_breakpoints_filename) when exiting Vim. +- default_breakpoints_filename: the filename used when auto_load_breakpoints_file/auto_saved_breakpoints_file are set. + +The following highlighting groups can be changed as well: +- PdbCurrentLine: the currently debugged line. +- PdbBreakpoint: a "regular" breakpoint. +- PdbConditionalBreakpoint: a conditional breakpoint. +- PdbTemporaryBreakpoint: a temporary breakpoint. + +And of course, default key bindings can be modified. + +6. Known Issues +---------------- + +- Breakpoint lines aren't highlighted properly (through out the line) when there are Python keywords at the beginning of the line. +e.g.: a breakpoint line that starts (with no whitespace) with a "print" will be highlighted only after the "print". +This is due to Vim's coloring precedence (keywords over any other type of match). +Curent line highlighting works fine (due to use of :match instead of :syn match command, which precedes any other +language highlighting). But the problem is that no more than one type of highlighting group can be used simultaneity +with with a :match command. + +- Instability of Vim has been reported (freezing/crashing). +This is probably due to the use of another Python thread within the Vim process. +I've tried to make it so that the main Vim process doesn't interact directly with the Python thread (only via a common +command queue). This improved stability, but not entirely. + diff --git a/vimfiles/doc/pi_vimball.txt b/vimfiles/doc/pi_vimball.txt index e62022b..7a2df7e 100644 --- a/vimfiles/doc/pi_vimball.txt +++ b/vimfiles/doc/pi_vimball.txt @@ -1,4 +1,4 @@ -*pi_vimball.txt* For Vim version 7.1a. Last change: 2007 May 07 +*pi_vimball.txt* For Vim version 7.1. Last change: 2008 Apr 01 ---------------- Vimball Archiver @@ -6,7 +6,7 @@ Author: Charles E. Campbell, Jr. (remove NOSPAM from Campbell's email first) -Copyright: (c) 2004-2006 by Charles E. Campbell, Jr. *Vimball-copyright* +Copyright: (c) 2004-2007 by Charles E. Campbell, Jr. *Vimball-copyright* The VIM LICENSE applies to Vimball.vim, and Vimball.txt (see |copyright|) except use "Vimball" instead of "Vim". No warranty, express or implied. @@ -30,7 +30,8 @@ Copyright: (c) 2004-2006 by Charles E. Campbell, Jr. *Vimball-copyright* :[range]MkVimball[!] filename [path] The range is composed of lines holding paths to files to be included - in your new vimball. As an example: > + in your new vimball, omitting the portion of the paths that is + normally specified by the runtimepath (|'rtp'|). As an example: > plugin/something.vim doc/something.txt < using > @@ -44,13 +45,20 @@ Copyright: (c) 2004-2006 by Charles E. Campbell, Jr. *Vimball-copyright* directory. The vimball plugin normally uses the first |'runtimepath'| directory that exists as a prefix; don't use absolute paths, unless the user has specified such a path. - *g:vimball_home* - You may override the use of the |'runtimepath'| by specifying a - variable, g:vimball_home. If you use the exclamation point (!), then MkVimball will create the "filename.vba" file, overwriting it if it already exists. This behavior resembles that for |:w|. + *g:vimball_home* + You may override the use of the |'runtimepath'| by specifying a + variable, g:vimball_home. + + Path Preprocessing *g:vimball_path_escape* + + Paths used in vimball are preprocessed by s:Path(); in addition, + certain characters are escaped (by prepending a backslash). The + characters are in g:vimball_path_escape, and may be overridden by + the user in his/her .vimrc initialization script. *vimball-extract* vim filename.vba @@ -90,6 +98,10 @@ Copyright: (c) 2004-2006 by Charles E. Campbell, Jr. *Vimball-copyright* ============================================================================== 3. Vimball History *vimball-history* {{{1 + 25 : Mar 24, 2008 * changed vimball#Vimball() to recognize doc/*.??x + files as help files, too. + 24 : Nov 15, 2007 * |g:vimball_path_escape| used by s:Path() to + prevent certain characters from causing trouble 22 : Mar 21, 2007 * uses setlocal instead of set during BufEnter 21 : Nov 27, 2006 * (tnx to Bill McCarthy) vimball had a header handling problem and it now changes \s to /s @@ -101,7 +113,7 @@ Copyright: (c) 2004-2006 by Charles E. Campbell, Jr. *Vimball-copyright* will extract plugin/somefile to the AsNeeded/ directory 17 : Jun 28, 2006 * changes all \s to /s internally for Windows - 16 : Jun 15, 2006 * A. Mechylynk's idea to allow users to specify + 16 : Jun 15, 2006 * A. Mechylynck's idea to allow users to specify installation root paths implemented for UseVimball, MkVimball, and RmVimball. * RmVimball implemented @@ -115,7 +127,7 @@ Copyright: (c) 2004-2006 by Charles E. Campbell, Jr. *Vimball-copyright* 10 : Apr 27, 2006 * moved all setting saving/restoration to a pair of functions. Included some more settings in them which frequently cause trouble. - 9 : Apr 26, 2006 * various changes to support Windows prediliction + 9 : Apr 26, 2006 * various changes to support Windows' predilection for backslashes and spaces in file and directory names. 7 : Apr 25, 2006 * bypasses foldenable diff --git a/vimfiles/doc/tags b/vimfiles/doc/tags index a415bda..9fec6f4 100644 --- a/vimfiles/doc/tags +++ b/vimfiles/doc/tags @@ -61,6 +61,7 @@ SRHiGrp SrchRplcHiGrp.txt /*SRHiGrp* SRSearch SrchRplcHiGrp.txt /*SRSearch* SrchRplcHiGrp.txt SrchRplcHiGrp.txt /*SrchRplcHiGrp.txt* TCommentDefineType() tComment.txt /*TCommentDefineType()* +VimPdb.txt VimPdb.txt /*VimPdb.txt* Vimball-copyright pi_vimball.txt /*Vimball-copyright* [% matchit.txt /*[%* ]% matchit.txt /*]%* diff --git a/vimfiles/plugin/VimPdb.py b/vimfiles/plugin/VimPdb.py new file mode 100644 index 0000000..0e172f4 --- /dev/null +++ b/vimfiles/plugin/VimPdb.py @@ -0,0 +1,1004 @@ +""" + VimPdb.py + + Pdb simulation within Vim (in an IDE like fashion). + + Author: + Yaron Budowski +""" +import bdb +import vim +import time +import sys +import os + + + +class PdbIDE(bdb.Bdb): + """Simulates a Python debugger in an IDE-like mode (unlike PDB, which acts as a command-line console debugger).""" + + # + # Constants + # + + + # The number of seconds to wait in the wait_in_debug() waiting loop. + PAUSE_DEBUG_WAIT_TIME = 0.2 + + # Various messages displayed to the user. + MESSAGE_NOT_IN_DEBUG_MODE = 'Error: Debugging not started yet' + MESSAGE_STARTING_DEBUG = 'Starting debugging...' + MESSAGE_PROGRAM_ENDED = 'Program ended. Restart debug to rerun program' + MESSAGE_ALREADY_AT_OLDEST_FRAME = 'Error: Already at oldest stack frame' + MESSAGE_ALREADY_AT_NEWEST_FRAME = 'Error: Already at newest stack frame' + MESSAGE_PROGRAM_ENDED_VIA_SYS_EXIT = 'Program ended via sys.exit(). Exit status: %d' + MESSAGE_PROGRAM_ENDED_UNCAUGHT_EXCEPTION = 'Program ended due to an uncaught exception.' + MESSAGE_NO_CONDITIONAL_BREAKPOINT = 'Error: No conditional breakpoint in current line' + MESSAGE_BREAKPOINT_CONDITION = 'Breakpoint Condition: %s' + MESSAGE_JUMP_ONLY_AT_BOTTOM_FRAME = 'Error: Can only jump to line within the bottom stack frame' + MESSAGE_JUMP_ONLY_IN_CURRENT_FILE = 'Error: Can only jump to line within the currently debugged file' + + # Breakpoint types (used when saving\loading breakpoints from files). + BREAKPOINT_TYPE_REGULAR = 'regular' + BREAKPOINT_TYPE_TEMPORARY = 'temporary' + BREAKPOINT_TYPE_CONDITIONAL = 'conditional' + BREAKPOINT_TYPES = [BREAKPOINT_TYPE_REGULAR, BREAKPOINT_TYPE_CONDITIONAL, BREAKPOINT_TYPE_TEMPORARY] + + + + def __init__(self): + # Initialize the parent Bdb class. + bdb.Bdb.__init__(self) + + # Used so we won't pause until the main script is loaded completely. + self.wait_for_script_start = False + self.main_filename = None + + # Used in wait_in_debug method (method doesn't return until pause_debug == False). + self.pause_debug = False + + # Current debugged filename & line. + self.current_filename = None + self.current_line = -1 + + # Current debugged frame. + self.current_frame = None + + self.current_stack_index = 0 + self.stack = [] + + + # A queue of Bdb methods to run. This is used when VimPdb methods (as opposed to Bdb methods) are called directly + # from the Vim file (VimPdb.vim) - these methods (such as do_toggle_breakpoint) use this queue to call Bdb methods + # (such as set_break) indirectly - it's done this way so the Bdb methods will be called from this instance's thread, + # and not from the Vim thread (which is the main thread). If the Bdb methods were called directly, it would screw up Python + # and Vim, and Vim will sometimes freeze\crash. + # The run_queued_methods method goes through this queue and executes the commands in it: each item is a list of + # function name and parameters. + self.methods_to_run = [] + + # The return value of the last method. + self.last_method_return_value = None + + + + + def start_debugging(self, filename, stop_immediately = True, args = []): + """Starts a debug session for a file. If stop_immediately is set, session is paused on the first line of program.""" + self.print_message(self.MESSAGE_STARTING_DEBUG) + new_globals = { '__name__': '__main__' } + new_locals = new_globals + + self.wait_for_script_start = True # So we won't break before we reach the first line of the script being debugged. + self.stop_immediately = stop_immediately + self.main_filename = self.canonic(filename) + + self.current_filename = self.main_filename + self.current_line = 1 + + + # Highlight the breakpoints. + self.highlight_breakpoints(self.main_filename, *self.get_breakpoints_for_file(self.main_filename)) + + # Replace main directory with running script's directory in front of module search path. + sys.path[0] = os.path.dirname(self.main_filename) + + try: + # Set command line arguments. + sys.argv = [self.main_filename] + args + # Run the script. + statement = 'execfile(r"%s")' % (self.main_filename) + self.run(statement, globals = new_globals, locals = new_locals) + + # Program ended. + self.print_message(self.MESSAGE_PROGRAM_ENDED) + self.clear_current_line_highlighting() + self.clear_breakpoints_highlighting() + except SystemExit: + self.print_message(self.MESSAGE_PROGRAM_ENDED_VIA_SYS_EXIT % (sys.exc_info()[1])) + self.clear_current_line_highlighting() + self.clear_breakpoints_highlighting() + except: + self.print_message(self.MESSAGE_PROGRAM_ENDED_UNCAUGHT_EXCEPTION) + raise + self.clear_current_line_highlighting() + self.clear_breakpoints_highlighting() + + + def stop_debugging(self): + """Stops the debugging session.""" + if (not self.is_debugged()): + self.print_message(self.MESSAGE_NOT_IN_DEBUG_MODE) + return + + self.quitting = True + + + # + # Debugging methods + # + + + def do_continue(self): + """Continues the deugging session until reaching a breakpoint, etc.""" + if (self.current_frame is None): + self.print_message(self.MESSAGE_NOT_IN_DEBUG_MODE) + return + + self.set_continue() + self.pause_debug = False + + def do_continue_until_return(self): + """Continues running until returning from the current frame.""" + if (self.current_frame is None): + self.print_message(self.MESSAGE_NOT_IN_DEBUG_MODE) + return + + self.set_return(self.current_frame) + self.pause_debug = False + + def do_step_into(self): + """Does step into.""" + if (self.current_frame is None): + self.print_message(self.MESSAGE_NOT_IN_DEBUG_MODE) + return + + self.set_step() + self.pause_debug = False + + def do_step_over(self): + """Does step over (doesn't enter any functions in between).""" + if (self.current_frame is None): + self.print_message(self.MESSAGE_NOT_IN_DEBUG_MODE) + return + + self.set_next(self.current_frame) + self.pause_debug = False + + def do_move_up_in_stack_frame(self): + """Moves up one level in the stack frame.""" + if (not self.is_debugged()): + self.print_message(self.MESSAGE_NOT_IN_DEBUG_MODE) + return + + if (self.current_stack_index <= 2): + self.print_message(self.MESSAGE_ALREADY_AT_OLDEST_FRAME) + return + + self.current_stack_index -= 1 + self.current_frame = self.stack[self.current_stack_index][0] + + self.goto_current_line(self.current_frame) + + def do_move_down_in_stack_frame(self): + """Moves down one level in the stack frame.""" + if (not self.is_debugged()): + self.print_message(self.MESSAGE_NOT_IN_DEBUG_MODE) + return + + if (self.current_stack_index + 1== len(self.stack)): + self.print_message(self.MESSAGE_ALREADY_AT_NEWEST_FRAME) + return + + self.current_stack_index += 1 + self.current_frame = self.stack[self.current_stack_index][0] + + self.goto_current_line(self.current_frame) + + + def do_toggle_breakpoint(self, filename, line_number, condition = None, temporary = False): + """Sets\unsets a breakpoint.""" + if (not self.is_debugged()): + self.print_message(self.MESSAGE_NOT_IN_DEBUG_MODE) + return + + if (not self.is_code_line(filename, line_number)): + # Not a code line. + return + + # First, prepare a list of all available breakpoints for this file. + breakpoints = self.get_file_breaks(filename)[:] # Make a copy so we won't be affected by changes. + + if (line_number in breakpoints): + # Unset breakpoint. + self.clear_break(filename, line_number) + else: + # Set the breakpoint. + self.set_break(filename, line_number, int(temporary), condition) + + # Re-Highlight the breakpoints. + self.highlight_breakpoints(filename, *self.get_breakpoints_for_file(filename)) + + def do_print_breakpoint_condition(self, filename, line_number): + """Prints the condition of a breakpoint at the specified line number.""" + if (not self.is_debugged()): + self.print_message(self.MESSAGE_NOT_IN_DEBUG_MODE) + return + + # First, prepare a list of all available breakpoints for this file. + conditional_breakpoints = self.get_conditional_breakpoints(filename) + + if (line_number not in conditional_breakpoints): + self.print_message(self.MESSAGE_NO_CONDITIONAL_BREAKPOINT) + return + + breakpoint_instances = self.get_breaks(filename, line_number) + + for breakpoint in breakpoint_instances: + if (breakpoint.cond): + self.print_message(self.MESSAGE_BREAKPOINT_CONDITION % (breakpoint.cond)) + return + + + def do_clear_all_breakpoints(self, filename = None): + """Clears all breakpoints. If filename is specified, only breakpoints for that filename are cleared.""" + + if (filename is None): + self.clear_all_breaks() + # Re-Highlight the breakpoints. + self.highlight_breakpoints(filename, *self.get_breakpoints_for_file(filename)) + return + + # Get all breakpoints for specified file. + file_breaks = self.get_file_breaks(filename) + + for line_number in file_breaks: + self.clear_break(filename, line_number) + + # Re-Highlight the breakpoints. + self.highlight_breakpoints(filename, *self.get_breakpoints_for_file(filename)) + + def do_clear(self, breakpoint_number): + """Clears a specified breakpoint by number.""" + self.clear_bpbynumber(breakpoint_number) + # Re-Highlight the breakpoints. + self.highlight_breakpoints(self.current_filename, *self.get_breakpoints_for_file(self.current_filename)) + + + def do_eval(self, expression): + """Evaluates an expression in the current debugging context.""" + if (self.current_frame is None): + self.print_message(self.MESSAGE_NOT_IN_DEBUG_MODE) + return + + try: + value = eval(expression, self.current_frame.f_globals, self.current_frame.f_locals) + self.print_message(value) + except: + (exc_type, value, traceback) = sys.exc_info() + + if (not isinstance(exc_type, str)): + exc_type_name = exc_type.__name__ + else: + exc_type_name = exc_type + + self.print_message('%s: %s' % (exc_type_name, value)) + + def do_exec(self, statement): + """Executes a statement in the current debugging context.""" + if (self.current_frame is None): + self.print_message(self.MESSAGE_NOT_IN_DEBUG_MODE) + return + + exec_locals = self.current_frame.f_locals + exec_globals = self.current_frame.f_locals + + try: + code = compile(statement + '\n', '', 'single') + exec code in exec_globals, exec_locals + except: + (exc_type, value, traceback) = sys.exc_info() + + if (not isinstance(exc_type, str)): + exc_type_name = exc_type.__name__ + else: + exc_type_name = exc_type + + self.print_message('%s: %s' % (exc_type_name, value)) + + + def do_jump(self, filename, line_number): + """Jumps to a specified line in the currently debugged file.""" + if (self.current_stack_index + 1 != len(self.stack)): + self.print_message(self.MESSAGE_JUMP_ONLY_AT_BOTTOM_FRAME) + return + + if (self.canonic(filename) != self.current_filename): + self.print_message(self.MESSAGE_JUMP_ONLY_IN_CURRENT_FILE) + return + + try: + self.current_frame.f_lineno = line_number + self.stack[self.current_stack_index] = (self.stack[self.current_stack_index][0], line_number) + + self.goto_current_line(self.current_frame) + except ValueError, exc: + self.print_message('Error: %s' % (exc)) + + + def do_print_stack_trace(self): + """Prints the stack trace.""" + + output_stack_traces = [] + + # Prepare the stack trace string. + for current_stack_frame in self.stack[2:]: # Skip the first two entries (which aren't really part of the debugged code) + (frame, line_number) = current_stack_frame + + if (frame is self.current_frame): + output_stack_traces.append(self.current_stack_entry_prefix + self.format_stack_entry(current_stack_frame)) + else: + output_stack_traces.append(self.stack_entry_prefix + self.format_stack_entry(current_stack_frame)) + + + final_stack_trace = self.stack_entries_joiner.join(output_stack_traces) + + self.print_message('Stack Trace:\n' + final_stack_trace) + + + def goto_current_line(self, frame, display = True): + """Moves the cursor to the currently debugged line, in the appropriate file. If display == False, don't highlight or move the cursor.""" + if (not self.is_debugged()): + return + + # Get the line number & filename. + line_number = frame.f_lineno + filename = self.canonic(frame.f_code.co_filename) + + self.current_filename = filename + self.current_line = line_number + + if (display): + # Load the file for editing (even if the file is not currently opened). + self.open_file(filename) + self.set_cursor_position(self.current_line, 0) + self.highlight_current_line(self.current_filename, self.current_line) + + + # + # Queue related methods + # + + + def add_queued_method(self, function_name, *parameters): + """Adds a method to the methods to run queue. It will be called indirectly by run_queued_methods""" + self.methods_to_run.append([function_name, parameters]) + + + def run_queued_methods(self): + """Executes any methods queued for execution. Used so that the methods will be executed from this instance's + thread context (and not from the main Vim thread).""" + + while (len(self.methods_to_run) > 0): + # Get the next method to run. + method_to_run = self.methods_to_run[0] + self.methods_to_run = self.methods_to_run[1:] + + (function_name, parameters) = method_to_run + + if (not hasattr(self, function_name)): + # Function doesn't exist. + raise + # TODO + #continue + + # Run the function. + function_pointer = getattr(self, function_name) + self.last_method_return_value = function_pointer(*parameters) + + def wait_in_debug(self, frame, traceback = None): + """Loops as long as self.pause_debug is True.""" + + # Save the current frame, etc. + (self.stack, self.current_stack_index) = self.get_stack(frame, traceback) + self.current_frame = self.stack[self.current_stack_index][0] + + self.goto_current_line(frame) + + while ((self.pause_debug) and (not self.quitting)): + time.sleep(self.PAUSE_DEBUG_WAIT_TIME) + + # Run any queued methods. + self.run_queued_methods() + + self.pause_debug = True + + + # + # Saving\Restoring breakpoints methods + # + + + def is_breakpoint_enabled(self, filename, line): + """Returns True if a breakpoint is enabled at the specified filename & line. False otherwise.""" + + if (self.get_breaks(filename, line)): + return True + else: + return False + + + def highlight_breakpoints_for_file(self, filename): + """Highlights breakpoints for a given filename.""" + + self.highlight_breakpoints(self.canonic(filename), *self.get_breakpoints_for_file(self.canonic(filename))) + + def highlight_current_line_for_file(self, filename): + """Highlights current line for a given filename.""" + + canonic_filename = self.canonic(filename) + if (self.current_filename != canonic_filename): + # The given filename is not the currently debugged file. + return + + self.highlight_current_line(canonic_filename, self.current_line) + + + + def get_breakpoints(self): + """Returns a list of active breakpoints.""" + file_breakpoints = self.get_all_breaks() + + returned_breakpoints = [] + for filename in file_breakpoints.keys(): + for line_number in file_breakpoints[filename]: + for breakpoint in self.get_breaks(filename, line_number): + new_breakpoint = {} + new_breakpoint['filename'] = filename + new_breakpoint['line'] = breakpoint.line + + if (breakpoint.cond): + new_breakpoint['type'] = self.BREAKPOINT_TYPE_CONDITIONAL + new_breakpoint['condition'] = breakpoint.cond + elif (breakpoint.temporary): + new_breakpoint['type'] = self.BREAKPOINT_TYPE_TEMPORARY + else: + new_breakpoint['type'] = self.BREAKPOINT_TYPE_REGULAR + + returned_breakpoints.append(new_breakpoint) + + return returned_breakpoints + + + def set_breakpoints(self, breakpoints): + """Sets\Adds breakpoints from a list of breakpoints.""" + + for breakpoint in breakpoints: + condition = None + temporary = False + + if (breakpoint['type'] == self.BREAKPOINT_TYPE_CONDITIONAL): + condition = breakpoint['condition'] + elif (breakpoint['type'] == self.BREAKPOINT_TYPE_TEMPORARY): + temporary = True + + # Set the breakpoint + self.set_break(breakpoint['filename'], breakpoint['line'], int(temporary), condition) + + # Re-highlight all of the breakpoints. + self.highlight_breakpoints(self.get_active_filename(), *self.get_breakpoints_for_file(self.get_active_filename())) + + def load_breakpoints_from_file(self, filename): + """Loads breakpoints from a file.""" + + if (not os.path.exists(filename)): + self.print_message('Error: File "%s" does not exist!' % (filename)) + return + + new_breakpoints = [] + + # First, clear all breakpoints. + #self.do_clear_all_breakpoints() + + breakpoints_file = open(filename, 'rb') + + # Load the breakpoints from the given file. + index = 0 + for line in breakpoints_file.xreadlines(): + line = line.strip() + index += 1 + + if (len(line) == 0): + continue + + breakpoint_properties = line.split('\t') + + if ((len(breakpoint_properties) < 3) or (len(breakpoint_properties) > 4)): + self.print_message('Error: Invalid line #%d at file "%s"' % (index, filename)) + return + + (breakpoint_filename, breakpoint_line, breakpoint_type) = breakpoint_properties[:3] + breakpoint_type = breakpoint_type.lower() + try: + breakpoint_line = int(breakpoint_line) + except ValueError: + self.print_message('Error: Invalid breakpoint line number in line #%d at file "%s"' % (index, filename)) + return + + if (breakpoint_type not in self.BREAKPOINT_TYPES): + self.print_message('Error: Invalid breakpoint type in line #%d at file "%s"' % (index, filename)) + return + + if ((breakpoint_type == self.BREAKPOINT_TYPE_CONDITIONAL) and (len(breakpoint_properties) != 4)): + self.print_message('Error: Missing/invalid breakpoint condition in line #%d at file "%s"' % (index, filename)) + return + + condition = None + temporary = False + + if (breakpoint_type == self.BREAKPOINT_TYPE_CONDITIONAL): + condition = breakpoint_properties[3] + elif (breakpoint_type == self.BREAKPOINT_TYPE_TEMPORARY): + temporary = True + + new_breakpoint = {} + new_breakpoint['filename'] = breakpoint_filename + new_breakpoint['line'] = breakpoint_line + new_breakpoint['type'] = breakpoint_type + new_breakpoint['condition'] = condition + new_breakpoint['temporary'] = temporary + + new_breakpoints.append(new_breakpoint) + + breakpoints_file.close() + + # Set the loaded breakpoints. + self.set_breakpoints(new_breakpoints) + + + def save_breakpoints_to_file(self, filename): + """Saves all active breakpoints to a file.""" + + breakpoints_file = open(filename, 'wb') + + breakpoints = self.get_breakpoints() + + for breakpoint in breakpoints: + line = '%s\t%s\t%s' % (breakpoint['filename'], breakpoint['line'], breakpoint['type']) + if (breakpoint['type'] == self.BREAKPOINT_TYPE_CONDITIONAL): + line += '\t' + breakpoint['condition'] + + breakpoints_file.write(line + '\n') + + breakpoints_file.close() + + + # + # Helper methods + # + + + def is_debugged(self): + """Checks whether or not there active debugging currently enabled.""" + #if ((not hasattr(self, 'quitting')) or (self.quitting) or (not self.current_frame)): + if ((not hasattr(self, 'quitting')) or (self.quitting)): + return False + else: + return True + + + def is_exit_frame(self, frame): + """Tests whether or not the current frame is of the exit frame.""" + + if (self.canonic(frame.f_code.co_filename) == ''): + return True + else: + return False + + + def get_conditional_breakpoints(self, filename): + """Returns a list of line numbers with conditional breakpoints for a given filename.""" + + conditional_breakpoints = [] + + # First, get the line numbers which have breakpoints set in them. + file_breaks = self.get_file_breaks(filename) + + for line_number in file_breaks: + breakpoint_instances = self.get_breaks(filename, line_number) + + for breakpoint in breakpoint_instances: + if (breakpoint.cond): + # Found a conditional breakpoint - add it to the list. + conditional_breakpoints.append(line_number) + + return conditional_breakpoints + + def get_temporary_breakpoints(self, filename): + """Returns a list of line numbers with temporary breakpoints for a given filename.""" + + temporary_breakpoints = [] + + # First, get the line numbers which have breakpoints set in them. + file_breaks = self.get_file_breaks(filename) + + for line_number in file_breaks: + breakpoint_instances = self.get_breaks(filename, line_number) + + for breakpoint in breakpoint_instances: + if (breakpoint.temporary): + # Found a temporary breakpoint - add it to the list. + temporary_breakpoints.append(line_number) + + return temporary_breakpoints + + + def get_breakpoints_for_file(self, filename): + """Returns a tuple of (regular_breakpoints, conditional_breakpoints, temporary_breakpoints) for + a given filename.""" + + regular_breakpoints = self.get_file_breaks(filename)[:] # Make a copy so we won't be affected by changes. + conditional_breakpoints = self.get_conditional_breakpoints(filename) + temporary_breakpoints = self.get_temporary_breakpoints(filename) + + # Remove any breakpoints which appear in the regular_breakpoints list, and are actually + # conditional or temporary breakpoints. + for breakpoint in regular_breakpoints: + if ((breakpoint in conditional_breakpoints) or (breakpoint in temporary_breakpoints)): + regular_breakpoints.remove(breakpoint) + + return (regular_breakpoints, conditional_breakpoints, temporary_breakpoints) + + + def is_code_line(self, filename, line): + """Returns True if the given line is a code line; False otherwise. + Warning: not comprehensive enough.""" + import linecache + + source_line = linecache.getline(self.canonic(filename), line) + + if (not source_line): + return False + + source_line = source_line.strip() + + if ((len(source_line) == 0) or (source_line[0] == '#') or + (source_line[:3] == '"""') or (source_line[:3] == "'''")): + return False + + return True + + + + + + # + # Overridden Bdb methods + # + + + def format_stack_entry(self, stack_frame): + """Formats the stack frame into a printable string.""" + import linecache + + (frame, line_number) = stack_frame + + filename = self.canonic(frame.f_code.co_filename) + (directory, filename) = os.path.split(filename) + + if (frame.f_code.co_name): + function_name = frame.f_code.co_name + else: + function_name = '' + + if ('__args__' in frame.f_locals.keys()): + args = frame.f_locals['__args__'] + else: + args = '' + + if ('__return__' in frame.f_locals.keys()): + return_value = '-> %s' % (frame.f_locals['__return__']) + else: + return_value = '' + + source_line = linecache.getline(filename, line_number) + if (not source_line): + source_line = '' + else: + source_line = source_line.strip() + + stack_entry_string = self.stack_entry_format % ( + {'filename': filename, 'dir': directory, 'line': line_number, 'function': function_name, + 'args': args, 'return_value': return_value, 'source_line': source_line}) + + return stack_entry_string + + + + def user_call(self, frame, args): + if ((self.wait_for_script_start) or (self.quitting)): + # Haven't reached the start of the script yet. + return + if (self.stop_here(frame)): + # Change the cursor position to the currently debugged line. + self.wait_in_debug(frame) + + + def user_line(self, frame): + """Called when we stop or break at this line.""" + + if (self.quitting): + return + if (self.wait_for_script_start): + if ((self.main_filename != self.canonic(frame.f_code.co_filename)) or (frame.f_lineno <= 0)): + # Haven't reached the start of the script yet. + return + + # Reached the start of the main script being debugged. + self.wait_for_script_start = False + + if (not self.stop_immediately): + # Debugging should start without pausing immediately. + self.set_continue() + self.pause_debug = False + else: + self.pause_debug = True + + # Move to the current line being debugged. + + self.wait_in_debug(frame) + + def user_return(self, frame, return_value): + """Called when a return trap is set here.""" + + if (self.quitting): + return + + if (self.is_exit_frame(frame)): + # It's the last frame. + self.print_message(self.MESSAGE_PROGRAM_ENDED) + self.clear_current_line_highlighting() + self.clear_breakpoints_highlighting() + return + + + frame.f_locals['__return__'] = return_value + + self.pause_debug = False + self.wait_in_debug(frame) + + def user_exception(self, frame, (exc_type, exc_value, exc_traceback)): + """Called if an exception occurs, but only if we are to stop at or just below this level.""" + if (self.quitting): + return + + frame.f_locals['__exception__'] = exc_type, exc_value + + if (type(exc_type) == type('')): + exc_type_name = exc_type + else: + exc_type_name = exc_type.__name__ + + if (self.is_exit_frame(frame)): + # It's the last frame. + self.print_message(self.MESSAGE_PROGRAM_ENDED) + self.clear_current_line_highlighting() + self.clear_breakpoints_highlighting() + return + + self.print_message("%s: %s" % (exc_type_name, exc_value)) + + self.wait_in_debug(frame) + + + # + # Methods to be overridden by the editor-specific child class. + # + + + + def print_message(self, message): + """Prints a message to the editor console""" + raise NotImplementedError() + + def set_cursor_position(self, row, column): + """Sets the cursor position for the current editor window.""" + raise NotImplementedError() + + def highlight_breakpoints(self, filename, regular_breakpoints, conditional_breakpoints, temporary_breakpoints): + """Highlights the active breakpoints in the given file.""" + raise NotImplementedError() + + def highlight_current_line(self, filename, line): + """Highlights the current debugged line.""" + raise NotImplementedError() + + def clear_current_line_highlighting(self): + """Clears the highlighting of the current debugged line.""" + raise NotImplementedError() + + def clear_breakpoints_highlighting(self): + """Clears the highlighting for the breakpoints.""" + raise NotImplementedError() + + def open_file(self, filename): + """Opens a file for editing.""" + raise NotImplementedError() + + def get_active_filename(self): + """Returns the filename of the active window.""" + raise NotImplementedError() + + +class VimPdb(PdbIDE): + """Integrates the Pdb IDE into Vim.""" + + # + # Constants + # + + + # The Vim group name used for highlighting the currently debugged line. + CURRENT_LINE_GROUP = 'PdbCurrentLineTemp' + USER_DEFINED_CURRENT_LINE_GROUP = 'PdbCurrentLine' + # The Vim group name used for highlighting the breakpoint line. + BREAKPOINT_GROUP = 'PdbBreakpoint' + # The Vim group name used for highlighting the conditional breakpoint line. + CONDITIONAL_BREAKPOINT_GROUP = 'PdbConditionalBreakpoint' + # The Vim group name used for highlighting the temporary breakpoint line. + TEMPORARY_BREAKPOINT_GROUP = 'PdbTemporaryBreakpoint' + + + + def __init__(self): + # Initialize the parent PdbIDE class. + PdbIDE.__init__(self) + + # The output buffer used when print_message() is called. + self.output_buffer = None + self.save_to_output_buffer = False + + + # + # Overridden methods, which implement the editor-specific functionalities. + # + + + def print_message(self, message): + """Prints a message to the Vim console.""" + if (self.save_to_output_buffer): + self.output_buffer = message + else: + print message + + def set_cursor_position(self, row, column): + """Sets the cursor position for the current Vim buffer.""" + # Move to the right line. + self.normal_command('%dG' % (row)) + # Move to the right column. + self.normal_command('0%dl' % (column)) + + def highlight_breakpoints(self, filename, regular_breakpoints, conditional_breakpoints, temporary_breakpoints): + """Highlights the active breakpoints in the given file.""" + self.clear_breakpoints_highlighting() + + self._set_lines_highlighting(regular_breakpoints, self.BREAKPOINT_GROUP) + self._set_lines_highlighting(conditional_breakpoints, self.CONDITIONAL_BREAKPOINT_GROUP) + self._set_lines_highlighting(temporary_breakpoints, self.TEMPORARY_BREAKPOINT_GROUP) + + + def highlight_current_line(self, filename, line): + """Highlights the current debugged line.""" + + if (self.canonic(vim.current.buffer.name) != filename): + # Current buffer isn't the last debugged filename. + return + + self.command(r'highlight link %s %s' % (self.CURRENT_LINE_GROUP, self.USER_DEFINED_CURRENT_LINE_GROUP)) + self.command(r'match %s "\%%%dl.\+"' % (self.CURRENT_LINE_GROUP, line)) + + def clear_current_line_highlighting(self): + """Clears the highlighting of the current debugged line.""" + + self.command(r'highlight link %s NONE' % (self.CURRENT_LINE_GROUP)) + + + def clear_breakpoints_highlighting(self): + """Clears the highlighting for the breakpoints.""" + + self.command(r'syntax clear %s' % (self.BREAKPOINT_GROUP)) + self.command(r'syntax clear %s' % (self.CONDITIONAL_BREAKPOINT_GROUP)) + self.command(r'syntax clear %s' % (self.TEMPORARY_BREAKPOINT_GROUP)) + + + def open_file(self, filename): + """Opens a file for editing.""" + + if (self.canonic(vim.current.buffer.name) != filename): + vim_filename = filename.replace(' ', r'\ ') + self.command('e ' + filename) + + def get_active_filename(self): + """Returns the filename of the active buffer.""" + return vim.current.buffer.name.replace(r'\ ', ' ') + + + def set_cursor_to_current_line(self): + """Moves the cursor to the current debugged line.""" + + self.open_file(self.current_filename) + self.set_cursor_position(self.current_line, 0) + + + + # + # Queue related methods + # + + + def run_method(self, function_name, *parameters): + """Runs a method (using add_queued_method) and waits for its output; then prints it onto the screen.""" + + self.output_buffer = None + self.save_to_output_buffer = True + self.add_queued_method(function_name, *parameters) + + while (self.output_buffer == None): + time.sleep(self.PAUSE_DEBUG_WAIT_TIME) + + self.save_to_output_buffer = False + self.print_message(self.output_buffer) + + def run_method_and_return_output(self, function_name, *parameters): + """Runs a method (using add_queued_method) and waits for it to finish running; + then returns its return value.""" + + self.save_to_output_buffer = False + self.last_method_return_value = None + self.add_queued_method(function_name, *parameters) + + while (self.last_method_return_value == None): + time.sleep(self.PAUSE_DEBUG_WAIT_TIME) + + return self.last_method_return_value + + + + # + # Helper methods + # + + + def normal_command(self, command): + """Runs a command in normal mode.""" + self.command('normal ' + command) + + def command(self, command): + """Runs a Vim (ex-mode) command""" + vim.command(command) + + + def _set_lines_highlighting(self, line_numbers, group_name): + """Sets highlighting for a group of line numbers (given a group name).""" + + for line_number in line_numbers: + self.command(r'syntax match %s "\%%%dl.\+"' % (group_name, line_number)) + + # Old method - doesn't work for line #1, and when the previous line ends with a quotation mark + # of the end of a string, for example. + + # Highlight each group of lines. + #for line_range in line_ranges: + # self.command(r'syntax region %s start="\%%%dl$" end="\%%%dl.\+"' % + # (group_name, line_range['start'] - 1, line_range['end'])) + diff --git a/vimfiles/plugin/VimPdb.vim b/vimfiles/plugin/VimPdb.vim new file mode 100644 index 0000000..8eb73d9 --- /dev/null +++ b/vimfiles/plugin/VimPdb.vim @@ -0,0 +1,592 @@ +" +" VimPdb.vim +" +" Intergrates a Python debugger into Vim in an IDE-like fashion. +" +" Author: +" Yaron Budowski +" + + + + +" +" Initialization code +" +" + +let current_dir = expand(":h") +python import sys +exe 'python sys.path.insert(0, r"' . current_dir . '")' +python import VimPdb + + +function! PdbInitialize() + " Initializes the VimPdb pluging. + + au BufLeave *.py :call PdbBuffLeave() + au BufEnter *.py :call PdbBuffEnter() + au BufEnter *.py :call PdbMapKeyboard() + au VimLeave *.py :call PdbStopDebug() + + call PdbMapKeyboard() + + let current_dir = expand(":h") + python import sys + exe 'python sys.path.insert(0, r"' . current_dir . '")' + python import VimPdb + + python << EOF +import vim +import threading +import time +import re + +reload(VimPdb) + + +# The VimPdb instance used for debugging. +vim_pdb = VimPdb.VimPdb() +vim_pdb.stack_entry_format = vim.eval('g:stack_entry_format') +vim_pdb.stack_entry_prefix = vim.eval('g:stack_entry_prefix') +vim_pdb.current_stack_entry_prefix = vim.eval('g:current_stack_entry_prefix') +vim_pdb.stack_entries_joiner = vim.eval('g:stack_entries_joiner') + + +def vim_pdb_start_debug(stop_immediately, args): + global vim_pdb + vim_pdb.start_debugging(vim.current.buffer.name, stop_immediately, args) + + +def parse_command_line(line): + """Parses command line.""" + args = [] + while (len(line) > 0): + if (line[0] == '"'): + next_quotation_mark = line.find('"', 1) + if (next_quotation_mark == -1): + # No ending quotation mark found. + line = line[1:] + continue + + # Treat anything between the two quotation marks as one argument. + args.append(line[1:next_quotation_mark]) + line = line[next_quotation_mark + 1:] + continue + + match = re.search('\s+', line) + if (not match): + # No whitespace found - save the argument until the end of the line. + args.append(line) + line = "" + continue + if (match.start() == 0): + # Whitespace in the beginning of the line - skip it. + line = line[match.end():] + continue + + args.append(line[:match.start()]) + line = line[match.end():] + + return args +EOF + +endfunction + + + +" +" Vim event related functions +" + +function! PdbBuffLeave() + " Used when leaving the current buffer - clear all highlighting. + + python < 0)): + vim_pdb.add_queued_method('do_toggle_breakpoint', vim.current.buffer.name, line_number, condition.strip()) + else: + condition = None + vim_pdb.add_queued_method('do_toggle_breakpoint', vim.current.buffer.name, line_number, condition) + +else: + print VimPdb.VimPdb.MESSAGE_NOT_IN_DEBUG_MODE +EOF +endfunction + +function! PdbToggleTemporaryBreakpointOnCurrentLine() + " Toggles a temporary breakpoint on the current line. + + python << EOF +if (vim_pdb.is_debugged()): + line_number = int(vim.eval('line(".")')) + vim_pdb.add_queued_method('do_toggle_breakpoint', vim.current.buffer.name, line_number, None, True) +else: + print VimPdb.VimPdb.MESSAGE_NOT_IN_DEBUG_MODE +EOF +endfunction + + + +function PdbClearAllBreakpointsInCurrentFile() + " Clears all breakpoints in the current file. + + python << EOF +if (vim_pdb.is_debugged()): + vim_pdb.add_queued_method('do_clear_all_breakpoints', vim.current.buffer.name) +else: + print VimPdb.VimPdb.MESSAGE_NOT_IN_DEBUG_MODE +EOF +endfunction + +function PdbClearAllBreakpoints() + " Clears all breakpoints in all files. + + python << EOF +if (vim_pdb.is_debugged()): + vim_pdb.add_queued_method('do_clear_all_breakpoints') +else: + print VimPdb.VimPdb.MESSAGE_NOT_IN_DEBUG_MODE +EOF +endfunction + + +function! PdbPrintBreakpointConditionOnCurrentLine() + " Prints the condition of the conditional breakpoint in the current line. + + python << EOF +if (vim_pdb.is_debugged()): + line_number = int(vim.eval('line(".")')) + + print vim_pdb.run_method('do_print_breakpoint_condition', vim.current.buffer.name, line_number) +else: + print VimPdb.VimPdb.MESSAGE_NOT_IN_DEBUG_MODE +EOF +endfunction + + + +function! PdbEvalCurrentWord() + " Evals the word currently under the cursor. + + python <")') + + if ((current_word is not None) and (len(current_word.strip()) > 0)): + vim_pdb.run_method('do_eval', current_word) +else: + print VimPdb.VimPdb.MESSAGE_NOT_IN_DEBUG_MODE +EOF +endfunction + +function! PdbEvalCurrentWORD() + " Evals the WORD currently under the cursor. + + python <")') + + if ((current_word is not None) and (len(current_word.strip()) > 0)): + vim_pdb.run_method('do_eval', current_word) +else: + print VimPdb.VimPdb.MESSAGE_NOT_IN_DEBUG_MODE +EOF +endfunction + +function! PdbEvalExpression() + " Evals an expression given by the user. + + python < :call PdbStartDebug(1, []) + " Start debug and don't pause immediately. + map :call PdbStartDebug(0, []) + map :call PdbStartDebugWithArguments() + map :call PdbStopDebug() + map :call PdbRestartDebug() + + map l :call PdbLoadSavedBreakpoints() + map s :call PdbSaveSavedBreakpoints() + + map :call PdbStepInto() + map :call PdbStepOver() + map :call PdbContinueUntilReturn() + + map :call PdbMoveUpInStackFrame() + map :call PdbMoveDownInStackFrame() + + map :call PdbSetFocusToCurrentDebugLine() + map :call PdbJumpToCurrentLine() + + map :call PdbToggleBreakpointOnCurrentLine() + map :call PdbToggleConditionalBreakpointOnCurrentLine() + map :call PdbToggleTemporaryBreakpointOnCurrentLine() + map :call PdbClearAllBreakpointsInCurrentFile() + map :call PdbClearAllBreakpoints() + + map :call PdbPrintBreakpointConditionOnCurrentLine() + + map :call PdbEvalCurrentWord() + map :call PdbEvalCurrentWORD() + + map :call PdbEvalExpression() + map :call PdbExecStatement() + + map :call PdbPrintStackTrace() +endfunction + + +" The format string for displaying a stack entry. +let g:stack_entry_format = "%(dir)s\\%(filename)s (%(line)d): %(function)s(%(args)s) %(return_value)s %(source_line)s" +" The string used to join stack entries together. +let g:stack_entries_joiner = " ==>\n" +" The prefix to each stack entry - 'regular' and current stack entry. +let g:stack_entry_prefix = " " +let g:current_stack_entry_prefix = "* " + +" Should VimPdb look for saved breakpoints file when starting a debug session? +let g:auto_load_breakpoints_file = 0 +" Should VimPdb save the breakpoints file when stopping the debug session? +let g:auto_save_breakpoints_file = 0 +" The name of the default saved breakpoints file (in the currently debugged directory). +" Used when auto_load_breakpoints_file/auto_save_breakpoints_file are turned on. +let g:default_breakpoints_filename = "bplist.vpb" + + + +" +" Main code +" + + +call PdbInitialize() + diff --git a/vimfiles/plugin/vimballPlugin.vim b/vimfiles/plugin/vimballPlugin.vim index 386e58f..128f0d2 100644 --- a/vimfiles/plugin/vimballPlugin.vim +++ b/vimfiles/plugin/vimballPlugin.vim @@ -1,6 +1,6 @@ " vimballPlugin : construct a file containing both paths and files " Author: Charles E. Campbell, Jr. -" Copyright: (c) 2004-2006 by Charles E. Campbell, Jr. +" Copyright: (c) 2004-2007 by Charles E. Campbell, Jr. " The VIM LICENSE applies to Vimball.vim, and Vimball.txt " (see |copyright|) except use "Vimball" instead of "Vim". " No warranty, express or implied. @@ -16,18 +16,18 @@ if &cp || exists("g:loaded_vimballPlugin") finish endif -let g:loaded_vimballPlugin = 1 +let g:loaded_vimballPlugin = "v25" let s:keepcpo = &cpo set cpo&vim " ------------------------------------------------------------------------------ " Public Interface: {{{1 -com! -ra -complete=dir -na=+ -bang MkVimball call vimball#MkVimball(,,0,) -com! -na=? -complete=dir UseVimball call vimball#Vimball(1,) -com! -na=0 VimballList call vimball#Vimball(0) -com! -na=* -complete=dir RmVimball call vimball#RmVimball() +com! -ra -complete=file -na=+ -bang MkVimball call vimball#MkVimball(,,0,) +com! -na=? -complete=dir UseVimball call vimball#Vimball(1,) +com! -na=0 VimballList call vimball#Vimball(0) +com! -na=* -complete=dir RmVimball call vimball#RmVimball() au BufEnter *.vba.gz,*.vba.bz2,*.vba.zip call vimball#Decompress(expand("")) -au BufEnter *.vba setlocal noma bt=nofile fmr=[[[,]]] fdm=marker|call vimball#ShowMesg(0,"Source this file to extract it! (:so %)") +au BufEnter *.vba setlocal ff=unix noma bt=nofile fmr=[[[,]]] fdm=marker|call vimball#ShowMesg(0,"Source this file to extract it! (:so %)") " ===================================================================== " Restoration And Modelines: {{{1