class library: Spawner - don't access PriorityQueue-array
[supercollider.git] / editors / scvim / ftplugin / supercollider.vim
blobf282822c4f02a1a28cd1d60456cef9a6d4446842
1 "SuperCollider/Vim interaction scripts
2 "Copyright 2007 Alex Norman
4 "This file is part of SCVIM.
6 "SCVIM is free software: you can redistribute it and/or modify
7 "it under the terms of the GNU General Public License as published by
8 "the Free Software Foundation, either version 3 of the License, or
9 "(at your option) any later version.
11 "SCVIM is distributed in the hope that it will be useful,
12 "but WITHOUT ANY WARRANTY; without even the implied warranty of
13 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 "GNU General Public License for more details.
16 "You should have received a copy of the GNU General Public License
17 "along with SCVIM.  If not, see <http://www.gnu.org/licenses/>.
19 "au VimLeave
21 "if exists("$SCVIM_DIR") == 0
22 "       echo "$SCVIM_DIR must be defined for SCVIM to work"
23 "       finish
24 "endif
27 "source the syntax file as it can change
28 "so $SCVIM_DIR/syntax/supercollider.vim
29 runtime! syntax/supercollider.vim
31 if exists("loaded_scvim") || &cp
32   finish
33 endif
34 let loaded_scvim = 1
36 "first if SCVIM_CACHE_DIR is defined, use that,
37 "otherwise use ~/.scvim
38 if exists("$SCVIM_CACHE_DIR") 
39         let s:scvim_cache_dir = $SCVIM_CACHE_DIR
40 else
41         let s:scvim_cache_dir = $HOME . "/.scvim"
42         let $SCVIM_CACHE_DIR = s:scvim_cache_dir
43 endif
45 "source the scvimrc file if it exists
46 "if filereadable($HOME . "/.scvimrc")
47 "       source $HOME/.scvimrc
48 "end
50 "add the cache dir to 
51 set runtimepath+=$SCVIM_CACHE_DIR
53 if exists("g:sclangKillOnExit")
54         let s:sclangKillOnExit = g:sclangKillOnExit
55 else
56         let s:sclangKillOnExit = 1
57 endif
59 if exists("g:sclangPipeLoc")
60         let s:sclangPipeLoc = g:sclangPipeLoc
61 else
62         let s:sclangPipeLoc = "/tmp/sclang-pipe"
63 endif
64 let $SCVIM_PIPE_LOC = s:sclangPipeLoc
66 if exists("g:sclangPipeAppPidLoc")
67         let s:sclangPipeAppPidLoc = g:sclangPipeAppPidLoc
68 else
69         let s:sclangPipeAppPidLoc = "/tmp/sclangpipe_app-pid"
70 endif
71 let $SCVIM_PIPE_PID_LOC = s:sclangPipeAppPidLoc
73 if exists("g:sclangTerm")
74         let s:sclangTerm = g:sclangTerm
75 else
76         let s:sclangTerm = "xterm -e"
77 endif
79 if exists("g:sclangPipeApp")
80         let s:sclangPipeApp     = g:sclangPipeApp
81 else
82         let s:sclangPipeApp     = "sclangpipe_app"
83 endif
85 "function SClangRunning()
86 "       if s:sclang_pid != 0 && `pidof "#{$sclangsclangPipeApp_no_quotes}"`.chomp != ""
87 "               return true
88 "       else
89 "               $sclang_pid = 0
90 "               return false
91 "       end
92 "end
95 function! FindOuterMostBlock()
96         "search backwards for parens dont wrap
97         let l:search_expression_up = "call searchpair('(', '', ')', 'bW'," .
98                 \"'synIDattr(synID(line(\".\"), col(\".\"), 0), \"name\") =~? \"scComment\" || " .
99                 \"synIDattr(synID(line(\".\"), col(\".\"), 0), \"name\") =~? \"scString\" || " .
100                 \"synIDattr(synID(line(\".\"), col(\".\"), 0), \"name\") =~? \"scSymbol\"')"
101         "search forward for parens, don't wrap
102         let l:search_expression_down = "call searchpair('(', '', ')', 'W'," .
103                 \"'synIDattr(synID(line(\".\"), col(\".\"), 0), \"name\") =~? \"scComment\" || " .
104                 \"synIDattr(synID(line(\".\"), col(\".\"), 0), \"name\") =~? \"scString\" || " .
105                 \"synIDattr(synID(line(\".\"), col(\".\"), 0), \"name\") =~? \"scSymbol\"')"
107         "save our current cursor position
108         let l:returnline = line(".")
109         let l:returncol = col(".")
110         
111         "if we're on an opening paren then we should actually go to the closing one to start the search
112         "if buf[l:returnline][l:returncol-1,1] == "("
113         if strpart(getline(line(".")),col(".") - 1,1) == "("
114                 exe l:search_expression_down
115         endif
117         let l:origline = line(".")
118         let l:origcol = col(".")
120         "these numbers will define our range, first init them to illegal values
121         let l:range_e = [-1, -1]
122         let l:range_s = [-1, -1]
124         "this is the last line in our search
125         let l:lastline = line(".")
126         let l:lastcol = col(".")
128         exe l:search_expression_up
130         while line(".") != l:lastline || (line(".") == l:lastline && col(".") != l:lastcol)
131                 "keep track of the last line/col we were on
132                 let l:lastline = line(".")
133                 let l:lastcol = col(".")
134                 "go to the matching paren
135                 exe l:search_expression_down
137                 "if there isn't a match print an error
138                 if l:lastline == line(".") && l:lastcol == col(".")
139                         call cursor(l:returnline,l:returncol)
140                         throw "UnmachedParen at line:" . l:lastline . ", col: " . l:lastcol
141                 endif
143                 "if this is equal to or later than our original cursor position
144                 if line(".") > l:origline || (line(".") == l:origline && col(".") >= l:origcol)
145                         let l:range_e = [line("."), col(".")]
146                         "go back to opening paren
147                         exe l:search_expression_up
148                         let l:range_s = [line("."), col(".")]
149                 else
150                         "go back to opening paren
151                         exe l:search_expression_up
152                 endif
153                 "find next paren (if there is one)
154                 exe l:search_expression_up
155         endwhile
157         "restore the settings
158         call cursor(l:returnline,l:returncol)
160         if l:range_s[0] == -1 || l:range_s[1] == -1
161                 throw "OutsideOfParens"
162         endif
163         
164         "return the ranges
165          return [l:range_s, l:range_e]
166 endfunction
169 "this causes the sclang pipe / terminal app to be killed when you exit vim, if you don't
170 "want that to happen then just comment this out
171 if !exists("loaded_kill_sclang")
172         if s:sclangKillOnExit
173                 au VimLeave * call SClangKill()
174         endif
175         let loaded_kill_sclang = 1
176 endif
178 "the vim version of SendToSC
179 function SendToSC(text)
180         let l:text = substitute(a:text, '\', '\\\\', 'g')
181         let l:text = substitute(l:text, '"', '\\"', 'g')
182         let l:cmd = system('echo "' . l:text . '" >> ' . s:sclangPipeLoc)
183         "let l:cmd = system('echo "' . l:text . '" >> /tmp/test')
184 endfunction
186 function SendLineToSC(linenum)
187         let cmd = a:linenum . "w! >> " . s:sclangPipeLoc
188         silent exe cmd
189         "let cmd = a:linenum . "w! >> /tmp/test" 
190         "silent exe cmd
191 endfunction
193 function! SClang_send()
194         let cmd = ".w! >> " . s:sclangPipeLoc
195         exe cmd
196         if line(".") == a:lastline
197                 call SendToSC('\f')
198                 "redraw!
199         endif
200 endfunction
202 function SClangStart()
203         if !filewritable(s:sclangPipeAppPidLoc)
204                 if $TERM[0:5] == "screen"
205                         call system("screen -D -R -X split; screen -D -R -X focus; screen -D -R -X screen " . s:sclangPipeApp . "; screen -D -R -X focus")
206                 else
207                         call system(s:sclangTerm . " " . s:sclangPipeApp . "&")
208                 endif
209         else
210                 throw s:sclangPipeAppPidLoc . " exists, is " . s:sclangPipeApp . " running?  If not try deleting " . s:sclangPipeAppPidLoc
211         endif
212 endfunction
214 function SClangKill()
215         if filewritable(s:sclangPipeAppPidLoc)
216                 call SendToSC("Server.quitAll;\f")
217                 :sleep 10m
218                 call system("kill `cat " . s:sclangPipeAppPidLoc . "` && rm " . s:sclangPipeAppPidLoc . " && rm " . s:sclangPipeLoc)
219         end
220 endfunction
222 function SClangRestart()
223         if filewritable(s:sclangPipeAppPidLoc)
224                 call system("kill -HUP `cat " . s:sclangPipeAppPidLoc . "`")
225         else
226                 call SClangStart()
227         end
228 endfunction
230 function SClang_free(server)
231         call SendToSC('s.freeAll;\f')
232         redraw!
233 endfunction
235 function SClang_thisProcess_stop()
236         call SendToSC('thisProcess.stop;\f')
237         redraw!
238 endfunction
240 function SClang_TempoClock_clear()
241         call SendToSC('TempoClock.default.clear;\f')
242         redraw!
243 endfunction
245 function! SClang_block()
246         let [blkstart,blkend] = FindOuterMostBlock()
247         "blkstart[0],blkend[0] call SClang_send()
248         "these next lines are just a hack, how can i do the above??
249         let cmd = blkstart[0] . "," . blkend[0] . " call SClang_send()"
250         let l:origline = line(".")
251         let l:origcol = col(".")
252         exe cmd
253         call cursor(l:origline,l:origcol)
254         
255         ""if the range is just one line
256         "if blkstart[0] == blkend[0]
257         "       "XXX call SendToSC(strpart(getline(blkstart[0]),blkstart[1] - 1, (blkend[1] - blkstart[1] + 1)))
258         "       call SendLineToSC(blkstart[0])
259         "else
260         "       let linen = blkstart[0] - 1
261         "       "send the first line as it might not be a full line
262         "       "XXX let line = getline(linen)
263         "       "XXX call SendToSC(strpart(line, blkstart[1] - 1))
264         "       call SendLineToSC(linen)
265         "       let linen += 1
266         "       let endlinen = blkend[0]
267         "       while linen < endlinen
268         "               "XXX call SendToSC(getline(linen))
269         "               call SendLineToSC(linen)
270         "               let linen += 1
271         "       endwhile
272         "       "send the last line as it might not be a full line
273         "       "XXX let line = getline(endlinen)
274         "       "XXX call SendToSC(strpart(line,0,blkend[1]))
275         "       call SendLineToSC(endlinen)
276         "endif
277         "call SendToSC('\f')
278 endfunction
280 function SCdef(subject)
281         let l:tagfile = s:scvim_cache_dir . "/TAGS_SCDEF"
282         let l:tagdest = s:scvim_cache_dir . "/doc/tags"
284         if !filereadable(l:tagfile)
285                 echo "definition tag cache does not exist, you must run SCVim.updateCaches in supercollider"
286                 let l:dontcare = system("echo 'SC:SCVim SCVim.scd       /^' > " . l:tagdest)
287                 exe "help SC:SCVim"
288         else
289                 let l:dontcare = system("grep SCdef:" . a:subject . " " . l:tagfile . " > " . l:tagdest)
290                 exe "help SCdef:" . a:subject
291         end
292 endfun
294 function SChelp(subject)
295         let l:tagfile = s:scvim_cache_dir . "/doc/TAGS_HELP"
296         let l:tagdest = s:scvim_cache_dir . "/doc/tags"
297         if !filereadable(l:tagfile)
298                 echo "help tag cache does not exist, you must run SCVim.updateHelpCache in supercollider in order have help docs"
299                 let l:dontcare = system("echo 'SC:SCVim SCVim.scd       /^' > $SCVIM_CACHE_DIR/doc/tags")
300                 exe "help SC:SCVim"
301                 return
302         end
304         "the keybindings won't find * but will find ** for some reason
305         if a:subject == ""
306                 let l:dontcare = system("grep \"SC:Help\" " . l:tagfile . " > " . l:tagdest)
307                 exe "help SC:Help"
308         elseif a:subject == "*"
309                 let l:dontcare = system("grep \"SC:\\*\" " . l:tagfile . " > " . l:tagdest)
310                 exe "help SC:\*" . a:subject
311         elseif a:subject == "**"
312                 let l:dontcare = system("grep \"SC:\\*\\*\" " . l:tagfile . " > " . l:tagdest)
313                 exe "help SC:\*\*" . a:subject
314         else
315                 let l:dontcare = system("grep SC:\"" . a:subject . "\" " . l:tagfile . " > " . l:tagdest)
316                 exe "help SC:" . a:subject
317         endif
318 endfun
320 "--open HelpBrowser
321 function HelpBrowser()
322         call SendToSC('Help.gui;\f')
323 endfunction
325 "--open help by class name
326 function HelpBrowser_find(subject)
327     let string= "HelpBrowser.openHelpFor"
328     let format= "(\"" . a:subject . "\");\f"
329     let string= string . format
330     call SendToSC(string)
331 endfunction
333 function ListSCObjects(A,L,P)
334         return system("cat $SCVIM_CACHE_DIR/sc_object_completion")
335 endfun
337 function ListSCHelpItems(A,L,P)
338         return system("cat $SCVIM_CACHE_DIR/doc/sc_help_completion")
339 endfun
342 "custom commands (SChelp,SCdef,SClangfree)
343 com -complete=custom,ListSCHelpItems -nargs=? SChelp call SChelp("<args>")
344 com -complete=custom,ListSCObjects -nargs=1 SCdef call SCdef("<args>")
345 com -nargs=1 SClangfree call SClang_free("<args>")
346 com -nargs=0 SClangStart call SClangStart()
347 com -nargs=0 SClangKill call SClangKill()
348 com -nargs=0 SClangRestart call SClangRestart()
350 " end supercollider.vim