1 #include "ide.h"
2
MacroEditor()3 EscValue Ide::MacroEditor()
4 {
5 EscValue out;
6 out.Escape("GetLength()", THISBACK(MacroGetLength));
7 out.Escape("GetLineCount()", THISBACK(MacroGetLineCount));
8 out.Escape("GetLinePos(line)", THISBACK(MacroGetLinePos));
9 out.Escape("GetLineLength(line)", THISBACK(MacroGetLineLength));
10 out.Escape("GetCursor()", THISBACK(MacroGetCursor));
11 out.Escape("GetLine(pos)", THISBACK(MacroGetLine));
12 out.Escape("GetColumn(pos)", THISBACK(MacroGetColumn));
13 out.Escape("GetSelBegin()", THISBACK(MacroGetSelBegin));
14 out.Escape("GetSelCount()", THISBACK(MacroGetSelCount));
15 out.Escape("SetCursor(pos)", THISBACK(MacroSetCursor));
16 out.Escape("SetSelection(begin, count)", THISBACK(MacroSetSelection));
17 out.Escape("ClearSelection()", THISBACK(MacroClearSelection));
18 out.Escape("Get(...)", THISBACK(MacroGet));
19 out.Escape("Remove(...)", THISBACK(MacroRemove));
20 out.Escape("Insert(...)", THISBACK(MacroInsert));
21 out.Escape("Find(...)", THISBACK(MacroFind));
22 out.Escape("FindMatchingBrace(pos)", THISBACK(MacroFindMatchingBrace));
23 out.Escape("FindClosingBrace(pos)", THISBACK(MacroFindClosingBrace));
24 out.Escape("FindOpeningBrace(pos)", THISBACK(MacroFindOpeningBrace));
25 out.Escape("Replace(...)", THISBACK(MacroReplace));
26 out.Escape("MoveLeft(...)", THISBACK(MacroMoveLeft));
27 out.Escape("MoveRight(...)", THISBACK(MacroMoveRight));
28 out.Escape("MoveWordLeft(...)", THISBACK(MacroMoveWordLeft));
29 out.Escape("MoveWordRight(...)", THISBACK(MacroMoveWordRight));
30 out.Escape("MoveUp(...)", THISBACK(MacroMoveUp));
31 out.Escape("MoveDown(...)", THISBACK(MacroMoveDown));
32 out.Escape("MoveHome(...)", THISBACK(MacroMoveHome));
33 out.Escape("MoveEnd(...)", THISBACK(MacroMoveEnd));
34 out.Escape("MovePageUp(...)", THISBACK(MacroMovePageUp));
35 out.Escape("MovePageDown(...)", THISBACK(MacroMovePageDown));
36 out.Escape("MoveTextBegin(...)", THISBACK(MacroMoveTextBegin));
37 out.Escape("MoveTextEnd(...)", THISBACK(MacroMoveTextEnd));
38
39 out.Escape("EditFile(...)", THISBACK(MacroEditFile));
40 out.Escape("SaveCurrentFile()", THISBACK(MacroSaveCurrentFile));
41 out.Escape("CloseFile()",THISBACK(MacroCloseFile));
42 out.Escape("FileName()", THISBACK(MacroFileName));
43
44 out.Escape("Input(...)", THISBACK(MacroInput));
45 out.Escape("ClearConsole()", THISBACK(MacroClearConsole));
46 out.Escape("Echo(...)", THISBACK(MacroEcho));
47
48 out.Escape("Build(...)", THISBACK(MacroBuild));
49 out.Escape("BuildProject(...)", THISBACK(MacroBuildProject));
50 out.Escape("Execute(cmdline)", THISBACK(MacroExecute));
51 out.Escape("Launch(cmdline)", THISBACK(MacroLaunch));
52
53 out.Escape("MainPackage()",THISBACK(MacroMainPackage));
54 out.Escape("ActivePackage()",THISBACK(MacroActivePackage));
55 out.Escape("PackageDir(...)",THISBACK(MacroPackageDir));
56 out.Escape("ProjectDir()", THISBACK(MacroPackageDir)); // BW compatibility
57 out.Escape("Assembly()",THISBACK(MacroAssembly));
58 out.Escape("BuildMethod()",THISBACK(MacroBuildMethod));
59 out.Escape("BuildMode()",THISBACK(MacroBuildMode));
60 out.Escape("Flags()",THISBACK(MacroFlags));
61 out.Escape("PackageFiles(...)",THISBACK(MacroPackageFiles));
62 out.Escape("AllPackages()",THISBACK(MacroAllPackages));
63 out.Escape("Target()", THISBACK(MacroTarget));
64
65 return out;
66 }
67
MacroGetLength(EscEscape & e)68 void Ide::MacroGetLength(EscEscape& e)
69 {
70 e = editor.GetLength();
71 }
72
MacroGetLineCount(EscEscape & e)73 void Ide::MacroGetLineCount(EscEscape& e)
74 {
75 e = editor.GetLineCount();
76 }
77
MacroGetLinePos(EscEscape & e)78 void Ide::MacroGetLinePos(EscEscape& e)
79 {
80 e = editor.GetPos(e.Int(0));
81 }
82
MacroGetLineLength(EscEscape & e)83 void Ide::MacroGetLineLength(EscEscape& e)
84 {
85 e = editor.GetLineLength(e.Int(0));
86 }
87
MacroGetCursor(EscEscape & e)88 void Ide::MacroGetCursor(EscEscape& e)
89 {
90 e = editor.GetCursor();
91 }
92
MacroGetLine(EscEscape & e)93 void Ide::MacroGetLine(EscEscape& e)
94 {
95 e = editor.GetLine(e.Int(0));
96 }
97
MacroGetColumn(EscEscape & e)98 void Ide::MacroGetColumn(EscEscape& e)
99 {
100 int pos = e.Int(0);
101 editor.GetLinePos(pos);
102 e = pos;
103 }
104
MacroGetSelBegin(EscEscape & e)105 void Ide::MacroGetSelBegin(EscEscape& e)
106 {
107 int l, h;
108 if(editor.GetSelection(l, h))
109 e = l;
110 else
111 e = editor.GetCursor();
112 }
113
MacroGetSelEnd(EscEscape & e)114 void Ide::MacroGetSelEnd(EscEscape& e)
115 {
116 int l, h;
117 if(editor.GetSelection(l, h))
118 e = h;
119 else
120 e = editor.GetCursor();
121 }
122
MacroGetSelCount(EscEscape & e)123 void Ide::MacroGetSelCount(EscEscape& e)
124 {
125 int l, h;
126 if(editor.GetSelection(l, h))
127 e = h - l;
128 else
129 e = 0.0;
130 }
131
MacroSetCursor(EscEscape & e)132 void Ide::MacroSetCursor(EscEscape& e)
133 {
134 editor.SetCursor(e.Int(0));
135 }
136
MacroSetSelection(EscEscape & e)137 void Ide::MacroSetSelection(EscEscape& e)
138 {
139 int b = e.Int(0), c = e.Int(1);
140 if(b < 0 || b > editor.GetLength() || c < 0 || c > editor.GetLength() || b + c > editor.GetLength())
141 e.ThrowError(Format("invalid selection: begin = %d, count = %d (text length = %d)",
142 b, c, editor.GetLength()));
143 editor.SetSelection(b, b + c);
144 }
145
MacroClearSelection(EscEscape & e)146 void Ide::MacroClearSelection(EscEscape& e)
147 {
148 editor.ClearSelection();
149 }
150
MacroGet(EscEscape & e)151 void Ide::MacroGet(EscEscape& e)
152 {
153 if(e.GetCount() < 1 || e.GetCount() > 2)
154 e.ThrowError("wrong number of arguments in call to Get (1 or 2 expected)");
155 int pos = e.Int(0);
156 int count = e.GetCount() > 1 ? e.Int(1) : 1;
157 if(pos < 0 || pos > editor.GetLength() || count <= 0 || pos + count > editor.GetLength())
158 e.ThrowError(Format("error in Get(%d, %d), text length = %d", pos, count, editor.GetLength()));
159 e = editor.GetW(pos, count);
160 }
161
MacroRemove(EscEscape & e)162 void Ide::MacroRemove(EscEscape& e)
163 {
164 int c = e.GetCount();
165 if(c > 2)
166 e.ThrowError("wrong number of arguments in call to Remove (0 to 2 expected)");
167 int len = editor.GetLength();
168 int cur = editor.GetCursor();
169 if(c == 0) {
170 int l, h;
171 if(editor.GetSelection(l, h))
172 editor.Remove(l, h - l);
173 else if(cur < len)
174 editor.Remove(cur, 1);
175 }
176 else {
177 int start = (c > 1 ? e.Int(0) : cur);
178 int count = e.Int(c - 1);
179 if(count < 0 || count > len || start < 0 || start + count > len)
180 e.ThrowError(Format("cannot remove %d character(s) at position %d, text length is only %d",
181 count, start, len));
182 editor.Remove(start, count);
183 }
184 }
185
MacroInsert(EscEscape & e)186 void Ide::MacroInsert(EscEscape& e)
187 {
188 int c = e.GetCount();
189 if(c < 1 || c > 2)
190 e.ThrowError("wrong number of arguments in call to Insert (1 or 2 expected)");
191 WString text = e[c - 1];
192 editor.Insert(c > 1 ? e.Int(0) : editor.GetCursor(), text);
193 }
194
MacroFind(EscEscape & e)195 void Ide::MacroFind(EscEscape& e)
196 {
197 int n = e.GetCount();
198 if(n < 1 || n > 6)
199 e.ThrowError("wrong number of arguments in call to Find (1 to 5 expected)");
200 CodeEditor::FindReplaceData d = editor.GetFindReplaceData();
201 bool down = (n <= 1 || e.Int(1) > 0);
202 d.wholeword = (n > 2 && e.Int(2) > 0);
203 d.ignorecase = (n > 3 && e.Int(3) > 0);
204 d.wildcards = (n > 4 && e.Int(4) > 0);
205 d.find = e[0];
206 editor.SetFindReplaceData(d);
207 e = editor.Find(!down, false);
208 }
209
MacroReplace(EscEscape & e)210 void Ide::MacroReplace(EscEscape& e)
211 {
212 int n = e.GetCount();
213 if(n < 2 || n > 5)
214 e.ThrowError("wrong number of arguments in call to Find (2 to 6 expected)");
215 CodeEditor::FindReplaceData d = editor.GetFindReplaceData();
216 d.find = e[0];
217 d.replace = e[1];
218 d.wholeword = (n > 2 && e.Int(2) > 0);
219 d.ignorecase = (n > 3 && e.Int(3) > 0);
220 d.wildcards = (n > 4 && e.Int(4) > 0);
221 d.samecase = (n > 5 && e.Int(5) > 0);
222 editor.SetFindReplaceData(d);
223 e = editor.BlockReplace();
224 }
225
MacroFindMatchingBrace(EscEscape & e)226 void Ide::MacroFindMatchingBrace(EscEscape& e)
227 {
228 int FindMatchingBrace(int pos);
229 }
230
MacroFindClosingBrace(EscEscape & e)231 void Ide::MacroFindClosingBrace(EscEscape& e)
232 {
233 int FindClosingBrace(int pos);
234 }
235
MacroFindOpeningBrace(EscEscape & e)236 void Ide::MacroFindOpeningBrace(EscEscape& e)
237 {
238 int FindOpeningBrace(int pos);
239 }
240
MacroMoveLeft(EscEscape & e)241 void Ide::MacroMoveLeft(EscEscape& e)
242 {
243 if(e.GetCount() > 1) e.ThrowError("MoveLeft(sel = false) takes at most 1 parameter");
244 editor.MoveLeft(e.GetCount() > 0 && e.Int(0) > 0);
245 }
246
MacroMoveRight(EscEscape & e)247 void Ide::MacroMoveRight(EscEscape& e)
248 {
249 if(e.GetCount() > 1) e.ThrowError("MoveRight(sel = false) takes at most 1 parameter");
250 editor.MoveRight(e.GetCount() > 0 && e.Int(0) > 0);
251 }
252
MacroMoveUp(EscEscape & e)253 void Ide::MacroMoveUp(EscEscape& e)
254 {
255 if(e.GetCount() > 1) e.ThrowError("MoveUp(sel = false) takes at most 1 parameter");
256 editor.MoveUp(e.GetCount() > 0 && e.Int(0) > 0);
257 }
258
MacroMoveDown(EscEscape & e)259 void Ide::MacroMoveDown(EscEscape& e)
260 {
261 if(e.GetCount() > 1) e.ThrowError("MoveDown(sel = false) takes at most 1 parameter");
262 editor.MoveDown(e.GetCount() > 0 && e.Int(0) > 0);
263 }
264
MacroMoveHome(EscEscape & e)265 void Ide::MacroMoveHome(EscEscape& e)
266 {
267 if(e.GetCount() > 1) e.ThrowError("MoveHome(sel = false) takes at most 1 parameter");
268 editor.MoveHome(e.GetCount() > 0 && e.Int(0) > 0);
269 }
270
MacroMoveEnd(EscEscape & e)271 void Ide::MacroMoveEnd(EscEscape& e)
272 {
273 if(e.GetCount() > 1) e.ThrowError("MoveEnd(sel = false) takes at most 1 parameter");
274 editor.MoveEnd(e.GetCount() > 0 && e.Int(0) > 0);
275 }
276
MacroMovePageUp(EscEscape & e)277 void Ide::MacroMovePageUp(EscEscape& e)
278 {
279 if(e.GetCount() > 1) e.ThrowError("MovePageUp(sel = false) takes at most 1 parameter");
280 editor.MovePageUp(e.GetCount() > 0 && e.Int(0) > 0);
281 }
282
MacroMovePageDown(EscEscape & e)283 void Ide::MacroMovePageDown(EscEscape& e)
284 {
285 if(e.GetCount() > 1) e.ThrowError("MovePageDown(sel = false) takes at most 1 parameter");
286 editor.MovePageDown(e.GetCount() > 0 && e.Int(0) > 0);
287 }
288
MacroMoveTextBegin(EscEscape & e)289 void Ide::MacroMoveTextBegin(EscEscape& e)
290 {
291 if(e.GetCount() > 1) e.ThrowError("MoveTextBegin(sel = false) takes at most 1 parameter");
292 editor.MoveTextBegin(e.GetCount() > 0 && e.Int(0) > 0);
293 }
294
MacroMoveTextEnd(EscEscape & e)295 void Ide::MacroMoveTextEnd(EscEscape& e)
296 {
297 if(e.GetCount() > 1) e.ThrowError("MoveTextEnd(sel = false) takes at most 1 parameter");
298 editor.MoveTextEnd(e.GetCount() > 0 && e.Int(0) > 0);
299 }
300
MacroMoveWordRight(EscEscape & e)301 void Ide::MacroMoveWordRight(EscEscape& e)
302 {
303 if(e.GetCount() > 1) e.ThrowError("MoveWordRight(sel = false) takes at most 1 parameter");
304 int p = editor.GetCursor();
305 int b = p;
306 int l = editor.GetLength();
307 if(iscid(editor.GetChar(p)))
308 while(p < l && iscid(editor.GetChar(p))) p++;
309 else
310 while(p < l && !iscid(editor.GetChar(p))) p++;
311 if(e.GetCount() > 0 && e.Int(0) > 0)
312 editor.SetSelection(b, p);
313 else
314 editor.SetCursor(p);
315 }
316
MacroMoveWordLeft(EscEscape & e)317 void Ide::MacroMoveWordLeft(EscEscape& e)
318 {
319 if(e.GetCount() > 1) e.ThrowError("MoveWordLeft(sel = false) takes at most 1 parameter");
320 int p = editor.GetCursor();
321 if(p == 0) return;
322 int b = p;
323 if(iscid(editor.GetChar(p - 1)))
324 while(p > 0 && iscid(editor.GetChar(p - 1))) p--;
325 else
326 while(p > 0 && !iscid(editor.GetChar(p - 1))) p--;
327 if(e.GetCount() > 0 && e.Int(0) > 0)
328 editor.SetSelection(p, b);
329 else
330 editor.SetCursor(p);
331 }
332
MacroInput(EscEscape & e)333 void Ide::MacroInput(EscEscape& e)
334 {
335 TopWindow dialog;
336 Vector<String> tags;
337 tags.SetCount(max(e.GetCount(), 1));
338 int xdim = 0;
339 enum {
340 SIDE_GAP = 4,
341 LINE_DIST = 22,
342 LINE_HEIGHT = 19,
343 BUTTON_HEIGHT = 22,
344 BUTTON_WIDTH = 80,
345 };
346 for(int i = 0; i < e.GetCount(); i++)
347 xdim = max(xdim, GetTextSize(tags[i] = e[i], StdFont()).cx + 10);
348 dialog.HCenterPos(xdim + 200, 0).VCenterPos(LINE_DIST * tags.GetCount() + 2 * SIDE_GAP + BUTTON_HEIGHT, 0);
349 Array<Label> label;
350 Array<EditField> editors;
351 for(int i = 0; i < tags.GetCount(); i++) {
352 Label& lbl = label.Add();
353 lbl.SetLabel(tags[i]);
354 lbl.LeftPos(SIDE_GAP, xdim).TopPos(SIDE_GAP + LINE_DIST * i, LINE_HEIGHT);
355 dialog << lbl;
356 EditField& fld = editors.Add();
357 fld.HSizePos(SIDE_GAP + xdim, SIDE_GAP).TopPos(SIDE_GAP + LINE_DIST * i, LINE_HEIGHT);
358 dialog << fld;
359 }
360 Button ok, cancel;
361 ok.SetLabel("OK") <<= dialog.Acceptor(IDOK);
362 cancel.SetLabel("Cancel") <<= dialog.Rejector(IDCANCEL);
363 dialog << ok.Ok().BottomPos(SIDE_GAP, BUTTON_HEIGHT).RightPos(2 * SIDE_GAP + BUTTON_WIDTH, BUTTON_WIDTH)
364 << cancel.Cancel().BottomPos(SIDE_GAP, BUTTON_HEIGHT).RightPos(SIDE_GAP, BUTTON_WIDTH);
365 dialog.Title("Macro input box");
366 if(dialog.Run() != IDOK) {
367 e = EscValue();
368 return;
369 }
370 if(tags.GetCount() == 1)
371 e = (WString)~editors[0];
372 else {
373 EscValue out;
374 for(int i = 0; i < tags.GetCount(); i++)
375 out.MapSet(i, (WString)~editors[i]);
376 e = out;
377 }
378 }
379
MacroBuild(EscEscape & e)380 void Ide::MacroBuild(EscEscape& e)
381 {
382 String outfile;
383 String maincfg = mainconfigparam;
384 switch(e.GetCount()) {
385 case 2: outfile = e[1]; break;
386 case 1: maincfg = e[0]; break;
387 case 0: break;
388 default: e.ThrowError("Build: 0 to 2 arguments expected ([maincfg[, outfile]])");
389 }
390 e = Build(IdeWorkspace(), maincfg, outfile, false);
391 }
392
MacroBuildProject(EscEscape & e)393 void Ide::MacroBuildProject(EscEscape& e)
394 {
395 String outfile;
396 switch(e.GetCount()) {
397 case 3: outfile = e[2];
398 case 2: break;
399 default: e.ThrowError("BuildProject: 2 or 3 arguments expected (uppfile, maincfg[, outfile])");
400 }
401 String uppfile = e[0];
402 String maincfg = e[1];
403 Workspace wspc;
404 wspc.Scan(uppfile);
405 e = Build(wspc, maincfg, outfile, false);
406 }
407
MacroExecute(EscEscape & e)408 void Ide::MacroExecute(EscEscape& e)
409 {
410 int time = msecs();
411 String cmdline = e[0];
412 One<Host> h = CreateHostRunDir();
413 h->ChDir(Nvl(rundir, GetFileFolder(target)));
414 ShowConsole();
415 PutConsole(String().Cat() << "MacroExecute: " << cmdline);
416 console.Sync();
417 e = h->Execute(cmdline);
418 PutVerbose("Finished in " + GetPrintTime(time));
419 }
420
MacroLaunch(EscEscape & e)421 void Ide::MacroLaunch(EscEscape& e)
422 {
423 String cmdline = e[0];
424 One<Host> h = CreateHostRunDir();
425 h->ChDir(Nvl(rundir, GetFileFolder(target)));
426 h->Launch(cmdline);
427 }
428
MacroClearConsole(EscEscape & e)429 void Ide::MacroClearConsole(EscEscape& e)
430 {
431 console.Clear();
432 }
433
MacroEditFile(EscEscape & e)434 void Ide::MacroEditFile(EscEscape& e)
435 {
436 String filename;
437 if(e.GetCount() == 1)
438 filename = e[0];
439 else if(e.GetCount() == 2)
440 filename = SourcePath(e[0], e[1]);
441 EditFile(filename);
442 }
443
MacroSaveCurrentFile(EscEscape & e)444 void Ide::MacroSaveCurrentFile(EscEscape& e)
445 {
446 SaveFile();
447 }
448
MacroFileName(EscEscape & e)449 void Ide::MacroFileName(EscEscape& e)
450 {
451 e = editfile;
452 }
453
MacroMainPackage(EscEscape & e)454 void Ide::MacroMainPackage(EscEscape& e)
455 {
456 e = GetMain();
457 }
458
MacroActivePackage(EscEscape & e)459 void Ide::MacroActivePackage(EscEscape& e)
460 {
461 e = GetActivePackage();
462 }
463
MacroPackageDir(EscEscape & e)464 void Ide::MacroPackageDir(EscEscape& e)
465 {
466 String pkg;
467 if(e.GetCount() == 0)
468 pkg = GetActivePackage();
469 else
470 pkg = e[0];
471 String pp = PackagePathA(pkg);
472 if(!FileExists(pp))
473 e.ThrowError("PackageDir: Package not found.");
474 e = GetFileFolder(pp);
475 }
476
MacroAssembly(EscEscape & e)477 void Ide::MacroAssembly(EscEscape& e)
478 {
479 e = GetVarsName();
480 }
481
MacroBuildMethod(EscEscape & e)482 void Ide::MacroBuildMethod(EscEscape& e)
483 {
484 e = method;
485 }
486
MacroBuildMode(EscEscape & e)487 void Ide::MacroBuildMode(EscEscape& e)
488 {
489 e = double(targetmode);
490 }
491
MacroFlags(EscEscape & e)492 void Ide::MacroFlags(EscEscape& e)
493 {
494 Vector<String> v = Split(mainconfigparam," ");
495 EscValue ret;
496 for(int i = 0; i < v.GetCount(); i++){
497 ret.ArrayAdd(v[i]);
498 }
499 e = ret;
500 }
501
MacroEcho(EscEscape & e)502 void Ide::MacroEcho(EscEscape& e)
503 {
504 ShowConsole();
505 for(int i = 0; i < e.GetCount(); i++){
506 PutConsole(String(e[i]));
507 }
508 }
509
MacroCloseFile(EscEscape & e)510 void Ide::MacroCloseFile(EscEscape& e)
511 {
512 int n = tabs.GetCursor();
513 if(n>=0)
514 tabs.Close(n,true);
515 }
516
MacroPackageFiles(EscEscape & e)517 void Ide::MacroPackageFiles(EscEscape& e)
518 {
519 String pp;
520 Package pkg;
521 if(e.GetCount()==0)
522 pp = GetActivePackagePath();
523 else
524 pp = PackagePathA(String(e[0]));
525 if(!FileExists(pp))
526 e.ThrowError("PackageFiles: Package not found.");
527 pkg.Load(pp);
528 EscValue ret;
529 for(int i = 0; i < pkg.file.GetCount(); i++){
530 ret.ArrayAdd(pkg.file[i]);
531 }
532 e = ret;
533 }
534
MacroAllPackages(EscEscape & e)535 void Ide::MacroAllPackages(EscEscape& e)
536 {
537 EscValue ret;
538 for(int i = 0; i < package.GetCount(); i++) {
539 String p = package.Get(i).name;
540 if(!IsAux(p))
541 ret.ArrayAdd(p);
542 }
543 e = ret;
544 }
545
MacroTarget(EscEscape & e)546 void Ide::MacroTarget(EscEscape& e)
547 {
548 e = target;
549 }
550