plugins: binary ugens - correct zero, firstarg and secondarg
[supercollider.git] / editors / scvim / scclasses / SCVim.sc
blobf2c0c17915ded4a849cca51bb208f9a5bbe834c4
1 //Copyright 2007 Alex Norman
2 //with modifications 2008 Dan Stowell
3 //
4 //This file is part of SCVIM.
5 //
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 SCVim {
21 classvar <scvim_dir, <scvim_cache_dir,
22         // autoFirstRun is whether we should attempt to create the caches if they're not found
23         <>autoFirstRun=true;
25 *initClass {
26         var scvim_cache_dir_env = getenv("SCVIM_CACHE_DIR");
27         if(scvim_cache_dir_env.isNil){
28                 scvim_cache_dir = "~/.scvim".standardizePath;
29                 setenv("SCVIM_CACHE_DIR", scvim_cache_dir);
30         }{
31                 scvim_cache_dir = scvim_cache_dir_env;
32    };
33    StartUp.add{
34       if(Platform.ideName=="scvim"){ 
35          if(autoFirstRun and:{ File.exists(scvim_cache_dir).not }){
36             Task{
37                "SCVim: generating help docs, it will take a few moments. (This only happens the first time you launch scvim. See SCVim help file for more info.)".inform;
38                this.updateCaches;
39                this.updateHelpCache;
40                "SCVim: finished generating help docs".inform;
41             }.play;
42          };
43       };
44    };
48 *updateCaches {
50         var object_list, object_dict;
51         var ob_vim_file, ob_comp_file, tags_file;
53         r{
54                 //if scvim_cache_dir doesn't exist, make it
55                 if(File.exists(scvim_cache_dir +/+ "doc").not){
56                         ("mkdir -p" + scvim_cache_dir +/+ "doc").systemCmd;
57                 };
59                 //open the files
60                 //for supercollider_objects.vim
61                 ob_vim_file = File(scvim_cache_dir +/+ "supercollider_objects.vim","w");
62                 //for TAGS_SCDEF (object definitions)
63                 tags_file = File(scvim_cache_dir +/+ "TAGS_SCDEF","w");
64                 //for object completion && object lookup in the SChelp function
65                 ob_comp_file = File(scvim_cache_dir +/+ "sc_object_completion","w");
67                 ob_vim_file.write("syn keyword\tscObject\t");
68                 object_list = SortedList.new(0);
69                 object_dict = Dictionary.new;
70                 //add Object itself
71                 object_list = object_list.add(Object.asString);
72                 object_dict.add(Object.asString -> Object);
73                 //sort the Objects (add to a sorted list)
74                 Object.allSubclasses.do(
75                         {|i|
76                                 object_list = object_list.add(i.asString);
77                                 object_dict.add(i.asString -> i);
78                         });
79                 //go through the Objects in order and write what needs to be written to the files
80                 object_list.do {|ob_string|
81                                 ob_vim_file.write(ob_string ++ " ");
82                                 /* disregard any Meta_ Classes */
83                                 if(ob_string.find("Meta_",false,0).isNil,
84                                         {ob_comp_file.write(ob_string ++ "\n")});
85                                 tags_file.write("SCdef:" ++
86                                                 ob_string ++
87                                                 "\t" ++ object_dict.at(ob_string).filenameSymbol ++
88                                                 "\tgo " ++
89                                                 (object_dict.at(ob_string).charPos + 1) ++ "\n");
90                         };
91                 //add some extra new lines
92                 ob_vim_file.write("\n\n");
93                 [ob_vim_file, tags_file, ob_comp_file].do(_.close);
94                 "SCVim files written".postln;
95         }.play;
96 } // end *updateCaches
98 *updateHelpCache { | helpPaths |
99     var getFiles, createHelp, objHelpPath, docDir, tagsDict, makeHelpFile, plain_text, new_path;
101     r{
102         //TODO currently ignoring helpPaths..
103         //if(helpPaths.isNil){ helpPaths = [Platform.helpDir]};
105         docDir = SCVim.scvim_cache_dir ++ if((SCVim.scvim_cache_dir.last == "/"), { "doc" }, { "/doc" });
106         tagsDict = Dictionary.new;
108         objHelpPath = { |obj|
109             if((obj == Object), { "Object" }, { objHelpPath.value(obj.superclass) ++ "/" ++ obj.asString; });
110         };
112         makeHelpFile = { |dest_file, dest_path, source_file|
113             if(File.exists(dest_path).not) {
114                 ("mkdir -p " ++ dest_path).systemCmd;
115             };
116             plain_text = File.use(source_file, "r") { |f| 
117                 switch(source_file.splitext[1],
118                         "html", { f.readAllStringHTML },
119                         "htm", { f.readAllStringHTML },
120                         "rtf", { f.readAllStringRTF },
121                         "scd", { f.readAllString },
122                         { Error("unsupported file format " ++ source_file).throw; }
123                       );
124             }.replace("&lt;", "<").replace("&gt;", ">").replace("&amp;", "&").replace("&nbsp;", " ");
125             dest_file = dest_path ++ "/" ++ dest_file;
126             try { File.use(dest_file, "w") { |out| out << plain_text }; }
127             { |error|
128                 ("could not write file " ++ dest_file).postln;
129             };
130             dest_file;
131         };
133         createHelp = { |subj, path|
134             if(File.exists(path)) {
135                 if((subj.class.asString.contains("Meta_")), {
136                         if((subj == Object), {new_path = docDir},
137                             {new_path = docDir ++ "/" ++ objHelpPath.value(subj.superclass)});
138                         tagsDict[subj.asString] = makeHelpFile.value(subj.asString ++ ".scd", new_path, path);
139                     },
140                     {
141                         new_path = docDir ++ "/other";
142                         subj = subj.asString.replace(" ", "_");
143                         tagsDict[subj.asString] = makeHelpFile.value(subj ++ ".scd", new_path, path);
144                     });
145             };
146         };
148         getFiles = { |collection|
149             collection.keysValuesDo { |key, value|
150                 case
151                 { value.class == String } { createHelp.value(key,value); }
152                 { value.class == Dictionary } { getFiles.value(value); }
153                 ;
154             };
155         };
157         postln("SCVim: processing help docs, this takes a little while....");
158         ("mkdir -p " ++ docDir).systemCmd;
159         getFiles.value(Help.tree);
161         //add the scvim doc if it doesn't already exist
162         if((File.exists(docDir ++ "/" ++ "SCVim.scd") && tagsDict.keys.asArray.includesAny([SCVim, "SCVim"]).not),
163                 { tagsDict["SCVim"] = (docDir ++ "/" ++ "SCVim.scd") }
164           );
166         //create the help completion and tags file
167         File.use(docDir ++ "/sc_help_completion", "w") { |completion_file|
168             File.use(docDir ++ "/TAGS_HELP", "w") { |tags_file|
169                 tagsDict.keys.asArray.sort.do { |t|
170                     tags_file << ("SC:" ++ t ++ "\t" ++ tagsDict[t] ++ "\t/^\n");
171                     completion_file << (t ++ "\n");
172                 };
173             };
174         };
175         postln("..done");
176     }.play;
179 } // end class