forked from bobmagicii/vscode-auto-fold
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathextension.js
438 lines (339 loc) · 10.3 KB
/
extension.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
/*//
//// Auto Fold
//// Bob Majdak Jr @bobmagicii <[email protected]>
//// Released under BSD 3-Clause
////
//// This extension will check files for the magic string:
//// vscode-fold=# and if found, will automatically fold that file to the
//// specified level when it is opened.
////
//// vscode-fold=2
//*/
let vscode = require('vscode');
/*//
microsoft in their infinite fucking wisdom made the "open" event fire every time
you switch tabs. what the fuck, people. so here is this retarded overengineered
thing designed to do what the events should be describing.
it gets better, the close event also fires on tab switch. and when you close
a tab there is no way to ask the TextDocument if it is really still open so
don't forget to check out the hillarious clusterfuck in the OnFileClose method.
Known Issues:
vscode loads extensions lazy, which happens after files open. files that are
already open will be folded the first time you switch to that tab. if a file
was already open in the active tab before the plugin loaded then you may need
to switch tabs forth and back, or use the command autofold.
//*/
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
var AutoFoldTracker = {
/*//
this is the main api instance that contains all the tracking and actions
to make this thing go.
//*/
Version: 106,
/*//
@type Int
current api version.
//*/
Debug: false,
/*//
@type Bool
supress debugging messages. i think console.log is slow so maybe we can
get moar by skipping them.
//*/
Files: [],
/*//
@type Array
holds a list of filenames we currently have open so that it can remember
if it has already attempted a file fold this session or not.
//*/
Interval: 0,
/*//
@type Int
the little timeout system uses this to remember the last active interval.
//*/
Has:
function(File) {
/*//
@argv TextDocument
@return Bool
check if we have seen this file before or not. we have to do this because
code is stupid and fires the damn open event every time you switch
regardless of if that was the first time it was opened or not.
//*/
let Iter = 0;
for(Iter = 0; Iter < AutoFoldTracker.Files.length; Iter++)
if(AutoFoldTracker.Files[Iter] == File.uri.fsPath)
return true;
return false;
},
Fold:
function(File) {
/*//
@argv TextDocument
@return Void
attempt to perform a folding operation.
//*/
// figure out what level we want.
let Config = vscode.workspace.getConfiguration("autofold");
let Level = AutoFoldTracker.GetLevel(File);
let Pack = 0;
// check if it makes sense.
if((Level <= 0 || Level > 9) && Level != 0) {
vscode.window.showInformationMessage('Auto Fold: Valid range is 1 to 9.');
return;
}
// commit.
if(Config.unfold) {
// this unfold is out here as the intented behaviour is to
// always unfold a document before folding it, and, if for
// example it was asked to be folded to level 3, but only
// contains 2 levels, then you will see the full source.
AutoFoldTracker.PrintDebug('>> unfold(): ' + File.uri.fsPath);
vscode.commands.executeCommand('editor.unfoldAll');
}
if(Level > 0) {
// then we apply the folding to the level that was asked.
AutoFoldTracker.PrintDebug('>> fold(' + Level + '): ' + File.uri.fsPath);
vscode.commands.executeCommand('editor.foldLevel' + Level);
if(Config.pack) {
// once the requested level is folded we can fold all
// the subtrees super fast, because they are no longer
// being rendered - if microsoft did it right - else
// this is a placebo speed boost. the technically
// correct way to computer science it, but without any
// backup implementation to support it lololol. honestly
// if it doesnt help the speed i'd almost rather see
// my code pack up as though its an intended animation.
Pack = Level;
while(10 > Pack++) {
AutoFoldTracker.PrintDebug(">> pack(" + Pack + ")")
vscode.commands.executeCommand('editor.foldLevel' + Pack);
}
}
}
// get specific lines to fold
let SpecificFolds = AutoFoldTracker.GetSpecificFolds(File)
AutoFoldTracker.PrintDebug('>> foldLines(' + SpecificFolds.join(', ') + '): ' + File.uri.fsPath);
vscode.commands.executeCommand('editor.fold', {selectionLines: SpecificFolds});
vscode.window.setStatusBarMessage("Auto Fold: " + Level,2000);
// and remember we did this file.
AutoFoldTracker.Files.push(File.uri.fsPath);
return;
},
CommandFold:
function() {
/*//
handler for when fold is requested by the pallete command.
//*/
let Current = AutoFoldTracker.GetCurrentDocument();
if(Current)
AutoFoldTracker.Fold(vscode.window.activeTextEditor.document);
return;
},
OnFileOpen:
function(File) {
/*//
@argv TextDocument
@return Void
when a file is opened, fold it.
//*/
// so this has to be on a delay apparently, because we are able to
// start processing the file before vscode.
let Config = vscode.workspace.getConfiguration("autofold");
AutoFoldTracker.PrintDebug("file opened: " + File.uri.fsPath);
if(AutoFoldTracker.Interval) {
clearInterval(AutoFoldTracker.Interval);
AutoFoldTracker.Interval = 0;
}
AutoFoldTracker.Interval = setTimeout(function(){
if(AutoFoldTracker.Has(File))
return;
AutoFoldTracker.Fold(File);
return;
},Config.delay);
},
OnFileClose:
function(File) {
/*//
@argv TextDocument
@return Void
when a file is closed, forget about it.
//*/
// this has been put on a delay to give the editor time to actually
// notice that a file was closed...
setTimeout(function(){
let Iter = 0
let Files = new Array;
// fix for vscode 1.11.0 insiders adding .git to the end of files...
// https://github.com/Microsoft/vscode/issues/22561
let Filename = File.uri.fsPath.replace(/\.git$/,'');
// if the file is still open do nothing.
for(Iter = 0; Iter < vscode.workspace.textDocuments.length; Iter++) {
//AutoFoldTracker.PrintDebug("file to check: " + Filename);
//AutoFoldTracker.PrintDebug("currently open: " + vscode.workspace.textDocuments[Iter].uri.fsPath);
if(vscode.workspace.textDocuments[Iter].uri.fsPath == Filename)
return;
}
// AutoFoldTracker.PrintDebug("file closed: " + Filename);
// pull it out.
for(Iter = 0; Iter < AutoFoldTracker.Files.length; Iter++)
if(File.uri.fsPath != AutoFoldTracker.Files[Iter])
Files.push(AutoFoldTracker.Files[Iter]);
AutoFoldTracker.Files = Files;
},1000);
return;
},
GetSpecificFolds:
function(File) {
/*//
@argv TextDocument
@return Int[]
finds any "specific" folds the user's created
a specific fold will totally fold the line immediately below it
//*/
let SpecificFolds = []
// attempt to find instances of vscode-fold$ in the file
for (let i = 0; i < File.lineCount; i++) {
if (/vscode-fold-next$/.test(File.lineAt(i).text)) {
SpecificFolds.push(i + 1)
}
}
////////
return SpecificFolds;
},
GetLevel:
function(File) {
/*//
@argv TextDocument
@return Int
try and find the magic comment within the file. returns the int value of
that comment for the fold levels.
//*/
// attempt to find vscode-fold=# in the file, keeping it at the end
// of the line to avoid triggering it when just talking about it in
// a comment which more or less will only ever even happen in this
// code lol.
let Result = File.getText().match(/vscode-fold=(\d+)/m);
let Level = 0;
////////
// did the file specify the magic comment?
if(Result && Result.length == 2 && parseInt(Result[1]) > 0)
Level = Result[1];
////////
// fallback to configured values.
if(Level == 0)
Level = AutoFoldTracker.GetDefaultLevel(AutoFoldTracker.GetCurrentDocument());
else
AutoFoldTracker.PrintDebug("## using file vscode-fold: " + Level);
////////
return Level;
},
GetDefaultLevel:
function(File) {
/*//
@argv TextDocument
@return Int
try and find a folding level based on the extension of this file. if none
is found then return the default default.
//*/
let Config = vscode.workspace.getConfiguration("autofold");
let Iter = 0;
let Output = 0;
let ExtConf;
let ExtCurr;
if (Config.Types) {
for(Iter = 0; Iter < Config.types.length; Iter++) {
if(!AutoFoldTracker.IsTypeConfigValid(Config.types[Iter]))
continue;
ExtConf = Config.types[Iter].ext.toLowerCase();
ExtCurr = File.uri.fsPath.toLowerCase();
if(ExtCurr.indexOf(ExtConf) == (ExtCurr.length - ExtConf.length)) {
AutoFoldTracker.PrintDebug(
"## using autofold.types[" + Config.types[Iter].ext + "]: " +
Config.types[Iter].level
);
Output = Config.types[Iter].level;
break;
}
}
}
// if we still have not found one then default to the default.
if(Output == 0) {
AutoFoldTracker.PrintDebug("## using autofold.default: " + Config.default);
Output = Config.default;
}
return Output;
},
GetCurrentDocument:
function() {
/*//
@argv Void
@return ?TextDocument
get the currently active document.
//*/
if(vscode.window.activeTextEditor)
if(vscode.window.activeTextEditor.document)
return vscode.window.activeTextEditor.document;
return null;
},
IsTypeConfigValid:
function(TypeObject) {
/*//
@argv Object
@return Bool
make sure that the configuration object given for default types appears to
be a usable format.
//*/
if(typeof TypeObject != "object")
return false;
if(typeof TypeObject.ext != "string")
return false;
if(typeof TypeObject.level != "number")
return false;
return true;
},
PrintDebug:
function(Msg) {
/*//
@argv String
@return Void
prints prefixed debug messages.
//*/
if(AutoFoldTracker.Debug)
console.log("[AF] " + Msg);
return;
}
};
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
exports.activate
=function(context) {
/*//
hello moto
//*/
context.subscriptions.push(vscode.commands.registerCommand(
'extension.autofold',
AutoFoldTracker.CommandFold
));
vscode.workspace.onDidOpenTextDocument(
AutoFoldTracker.OnFileOpen,
null,
context
);
vscode.workspace.onDidCloseTextDocument(
AutoFoldTracker.OnFileClose,
null,
context
);
AutoFoldTracker.PrintDebug('Auto Fold has loaded.');
AutoFoldTracker.CommandFold();
return AutoFoldTracker;
};
exports.deactivate
=function() {
/*//
otom olleh
//*/
return;
};