"SuperCollider/Vim interaction scripts "Copyright 2007 Alex Norman " "This file is part of SCVIM. " "SCVIM is free software: you can redistribute it and/or modify "it under the terms of the GNU General Public License as published by "the Free Software Foundation, either version 3 of the License, or "(at your option) any later version. " "SCVIM is distributed in the hope that it will be useful, "but WITHOUT ANY WARRANTY; without even the implied warranty of "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the "GNU General Public License for more details. " "You should have received a copy of the GNU General Public License "along with SCVIM. If not, see . "au VimLeave "if exists("$SCVIM_DIR") == 0 " echo "$SCVIM_DIR must be defined for SCVIM to work" " finish "endif "source the syntax file as it can change "so $SCVIM_DIR/syntax/supercollider.vim runtime! syntax/supercollider.vim if exists("loaded_scvim") || &cp finish endif let loaded_scvim = 1 "first if SCVIM_CACHE_DIR is defined, use that, "otherwise use ~/.scvim if exists("$SCVIM_CACHE_DIR") let s:scvim_cache_dir = $SCVIM_CACHE_DIR else let s:scvim_cache_dir = $HOME . "/.scvim" let $SCVIM_CACHE_DIR = s:scvim_cache_dir endif "source the scvimrc file if it exists if filereadable($HOME . "/.scvimrc") source $HOME/.scvimrc end "add the cache dir to set runtimepath+=$SCVIM_CACHE_DIR if exists("g:sclangKillOnExit") let s:sclangKillOnExit = g:sclangKillOnExit else let s:sclangKillOnExit = 1 endif if exists("g:sclangPipeLoc") let s:sclangPipeLoc = g:sclangPipeLoc else let s:sclangPipeLoc = "/tmp/sclang-pipe" endif let $SCVIM_PIPE_LOC = s:sclangPipeLoc if exists("g:sclangPipeAppPidLoc") let s:sclangPipeAppPidLoc = g:sclangPipeAppPidLoc else let s:sclangPipeAppPidLoc = "/tmp/sclangpipe_app-pid" endif let $SCVIM_PIPE_PID_LOC = s:sclangPipeAppPidLoc if exists("g:sclangTerm") let s:sclangTerm = g:sclangTerm else let s:sclangTerm = "xterm -e" endif if exists("g:sclangPipeApp") let s:sclangPipeApp = g:sclangPipeApp else let s:sclangPipeApp = "sclangpipe_app" endif "function SClangRunning() " if s:sclang_pid != 0 && `pidof "#{$sclangsclangPipeApp_no_quotes}"`.chomp != "" " return true " else " $sclang_pid = 0 " return false " end "end function! FindOuterMostBlock() "search backwards for parens dont wrap let l:search_expression_up = "call searchpair('(', '', ')', 'bW'," . \"'synIDattr(synID(line(\".\"), col(\".\"), 0), \"name\") =~? \"scComment\" || " . \"synIDattr(synID(line(\".\"), col(\".\"), 0), \"name\") =~? \"scString\" || " . \"synIDattr(synID(line(\".\"), col(\".\"), 0), \"name\") =~? \"scSymbol\"')" "search forward for parens, don't wrap let l:search_expression_down = "call searchpair('(', '', ')', 'W'," . \"'synIDattr(synID(line(\".\"), col(\".\"), 0), \"name\") =~? \"scComment\" || " . \"synIDattr(synID(line(\".\"), col(\".\"), 0), \"name\") =~? \"scString\" || " . \"synIDattr(synID(line(\".\"), col(\".\"), 0), \"name\") =~? \"scSymbol\"')" "save our current cursor position let l:returnline = line(".") let l:returncol = col(".") "if we're on an opening paren then we should actually go to the closing one to start the search "if buf[l:returnline][l:returncol-1,1] == "(" if strpart(getline(line(".")),col(".") - 1,1) == "(" exe l:search_expression_down endif let l:origline = line(".") let l:origcol = col(".") "these numbers will define our range, first init them to illegal values let l:range_e = [-1, -1] let l:range_s = [-1, -1] "this is the last line in our search let l:lastline = line(".") let l:lastcol = col(".") exe l:search_expression_up while line(".") != l:lastline || (line(".") == l:lastline && col(".") != l:lastcol) "keep track of the last line/col we were on let l:lastline = line(".") let l:lastcol = col(".") "go to the matching paren exe l:search_expression_down "if there isn't a match print an error if l:lastline == line(".") && l:lastcol == col(".") call cursor(l:returnline,l:returncol) throw "UnmachedParen at line:" . l:lastline . ", col: " . l:lastcol endif "if this is equal to or later than our original cursor position if line(".") > l:origline || (line(".") == l:origline && col(".") >= l:origcol) let l:range_e = [line("."), col(".")] "go back to opening paren exe l:search_expression_up let l:range_s = [line("."), col(".")] else "go back to opening paren exe l:search_expression_up endif "find next paren (if there is one) exe l:search_expression_up endwhile "restore the settings call cursor(l:returnline,l:returncol) if l:range_s[0] == -1 || l:range_s[1] == -1 throw "OutsideOfParens" endif "return the ranges return [l:range_s, l:range_e] endfunction "this causes the sclang pipe / terminal app to be killed when you exit vim, if you don't "want that to happen then just comment this out if !exists("loaded_kill_sclang") if s:sclangKillOnExit au VimLeave * call SClangKill() endif let loaded_kill_sclang = 1 endif "the vim version of SendToSC function SendToSC(text) let l:text = substitute(a:text, '\', '\\\\', 'g') let l:text = substitute(l:text, '"', '\\"', 'g') let l:cmd = system('echo "' . l:text . '" >> ' . s:sclangPipeLoc) "let l:cmd = system('echo "' . l:text . '" >> /tmp/test') endfunction function SendLineToSC(linenum) let cmd = a:linenum . "w! >> " . s:sclangPipeLoc silent exe cmd "let cmd = a:linenum . "w! >> /tmp/test" "silent exe cmd endfunction function! SClang_send() let cmd = ".w! >> " . s:sclangPipeLoc exe cmd if line(".") == a:lastline call SendToSC(' ') "redraw! endif endfunction function SClangStart() if !filewritable(s:sclangPipeAppPidLoc) call system("tmux splitw -h -p 25; tmux send-keys " . s:sclangPipeApp . " C-m; tmux selectp -L; sleep 1; tmux renamew scvim") else throw s:sclangPipeAppPidLoc . " exists, is " . s:sclangPipeApp . " running? If not try deleting " . s:sclangPipeAppPidLoc endif endfunction function SClangKill() if filewritable(s:sclangPipeAppPidLoc) call system("tmux selectp -R; tmux send-keys C-c; tmux killp -t scvim.1") call SendToSC("Server.quitAll; ") :sleep 10m call system("kill `cat " . s:sclangPipeAppPidLoc . "` && rm " . s:sclangPipeAppPidLoc . " && rm " . s:sclangPipeLoc) end endfunction function SClangRestart() if filewritable(s:sclangPipeAppPidLoc) call system("kill -HUP `cat " . s:sclangPipeAppPidLoc . "`") else call SClangStart() end endfunction function SClang_free(server) call SendToSC('s.freeAll; ') redraw! endfunction function SClang_thisProcess_stop() call SendToSC('thisProcess.stop; ') redraw! endfunction function SClang_TempoClock_clear() call SendToSC('TempoClock.default.clear; ') redraw! endfunction function! SClang_block() let [blkstart,blkend] = FindOuterMostBlock() "blkstart[0],blkend[0] call SClang_send() "these next lines are just a hack, how can i do the above?? let cmd = blkstart[0] . "," . blkend[0] . " call SClang_send()" let l:origline = line(".") let l:origcol = col(".") exe cmd call cursor(l:origline,l:origcol) ""if the range is just one line "if blkstart[0] == blkend[0] " "XXX call SendToSC(strpart(getline(blkstart[0]),blkstart[1] - 1, (blkend[1] - blkstart[1] + 1))) " call SendLineToSC(blkstart[0]) "else " let linen = blkstart[0] - 1 " "send the first line as it might not be a full line " "XXX let line = getline(linen) " "XXX call SendToSC(strpart(line, blkstart[1] - 1)) " call SendLineToSC(linen) " let linen += 1 " let endlinen = blkend[0] " while linen < endlinen " "XXX call SendToSC(getline(linen)) " call SendLineToSC(linen) " let linen += 1 " endwhile " "send the last line as it might not be a full line " "XXX let line = getline(endlinen) " "XXX call SendToSC(strpart(line,0,blkend[1])) " call SendLineToSC(endlinen) "endif "call SendToSC(' ') endfunction function SCdef(subject) let l:tagfile = s:scvim_cache_dir . "/TAGS_SCDEF" let l:tagdest = s:scvim_cache_dir . "/doc/tags" if !filereadable(l:tagfile) echo "definition tag cache does not exist, you must run SCVim.updateCaches in supercollider" let l:dontcare = system("echo 'SC:SCVim SCVim.scd /^' > " . l:tagdest) exe "help SC:SCVim" else let l:dontcare = system("grep SCdef:" . a:subject . " " . l:tagfile . " > " . l:tagdest) exe "help SCdef:" . a:subject end endfun function SChelp(subject) let l:tagfile = s:scvim_cache_dir . "/doc/TAGS_HELP" let l:tagdest = s:scvim_cache_dir . "/doc/tags" if !filereadable(l:tagfile) echo "help tag cache does not exist, you must run SCVim.updateHelpCache in supercollider in order have help docs" let l:dontcare = system("echo 'SC:SCVim SCVim.scd /^' > $SCVIM_CACHE_DIR/doc/tags") exe "help SC:SCVim" return end "the keybindings won't find * but will find ** for some reason if a:subject == "" let l:dontcare = system("grep \"SC:Help\" " . l:tagfile . " > " . l:tagdest) exe "help SC:Help" elseif a:subject == "*" let l:dontcare = system("grep \"SC:\\*\" " . l:tagfile . " > " . l:tagdest) exe "help SC:\*" . a:subject elseif a:subject == "**" let l:dontcare = system("grep \"SC:\\*\\*\" " . l:tagfile . " > " . l:tagdest) exe "help SC:\*\*" . a:subject else let l:dontcare = system("grep SC:\"" . a:subject . "\" " . l:tagfile . " > " . l:tagdest) exe "help SC:" . a:subject endif endfun " search help files for word under the cursor " or open the HelpBrowser front page function! HelpBrowser(subject) if strlen(a:subject) > 0 && a:subject!~" " && a:subject!~"\t" let string= "HelpBrowser.openHelpFor" let format= "(\"" . a:subject . "\"); " let string= string . format call SendToSC(string) else call SendToSC('Help.gui; ') endif endfunction function ListSCObjects(A,L,P) return system("cat $SCVIM_CACHE_DIR/sc_object_completion") endfun function ListSCHelpItems(A,L,P) return system("cat $SCVIM_CACHE_DIR/doc/sc_help_completion") endfun "custom commands (SChelp,SCdef,SClangfree) com -complete=custom,ListSCHelpItems -nargs=? SChelp call SChelp("") com -complete=custom,ListSCObjects -nargs=1 SCdef call SCdef("") com -nargs=1 SClangfree call SClang_free("") com -nargs=0 SClangStart call SClangStart() com -nargs=0 SClangKill call SClangKill() com -nargs=0 SClangRestart call SClangRestart() " end supercollider.vim