9b3979cd922171f145a6b0e433d0294c74183d3c
[roobuilder] / src / Builder4 / Editor.bjs
1 {
2  "build_module" : "builder",
3  "gen_extended" : false,
4  "items" : [
5   {
6    "# GtkSource.SearchContext searchcontext" : "null",
7    "# JsRender.JsRender? file" : "null",
8    "# JsRender.Node node" : "null",
9    "# JsRender.NodeProp? prop" : "null",
10    "# Xcls_MainWindow window" : "null",
11    "# bool dirty" : false,
12    "# bool pos" : false,
13    "# int pos_root_x" : "",
14    "# int pos_root_y" : "",
15    "# string activeEditor" : "\"\"",
16    "$ homogeneous" : false,
17    "$ xns" : "Gtk",
18    "@ void save" : "()",
19    "Gtk.Orientation orientation" : "Gtk.Orientation.VERTICAL",
20    "bool hexpand" : true,
21    "bool vexpand" : true,
22    "int last_search_end" : 0,
23    "items" : [
24     {
25      "$ homogeneous" : false,
26      "$ xns" : "Gtk",
27      "Gtk.Orientation orientation" : "Gtk.Orientation.HORIZONTAL",
28      "bool hexpand" : true,
29      "items" : [
30       {
31        "$ xns" : "Gtk",
32        "id" : "save_button",
33        "label" : "Save",
34        "listeners" : {
35         "clicked" : [
36          " () => { ",
37          "    _this.saveContents();",
38          "}",
39          "  "
40         ]
41        },
42        "xtype" : "Button"
43       },
44       {
45        "$ xns" : "Gtk",
46        "bool hexpand" : true,
47        "xtype" : "Label"
48       },
49       {
50        "$ xns" : "Gtk",
51        "* ctor" : "new Gtk.Scale.with_range (Gtk.Orientation.HORIZONTAL,6, 30, 1)",
52        "* init" : [
53         "{",
54         "\tthis.el.set_range(6,30);",
55         "\tthis.el.set_value(8);",
56         "}",
57         ""
58        ],
59        "bool draw_value" : false,
60        "bool has_origin" : true,
61        "bool sensitive" : true,
62        "int digits" : 0,
63        "int width_request" : 200,
64        "listeners" : {
65         "change_value" : [
66          "(st, val ) => {",
67          "\t ",
68          "\t   ",
69          "\t  _this.view.css.load_from_string(",
70          "\t  \t\t\"#editor-view { font: %dpx monospace; }\".printf((int)val)",
71          "\t   );",
72          "     ",
73          " \treturn false;",
74          "}"
75         ]
76        },
77        "xtype" : "Scale"
78       },
79       {
80        "$ xns" : "Gtk",
81        "id" : "close_btn",
82        "items" : [
83         {
84          "$ xns" : "Gtk",
85          "* prop" : "child",
86          "Gtk.IconSize icon_size" : "Gtk.IconSize.NORMAL",
87          "string icon_name" : "window-close",
88          "xtype" : "Image"
89         }
90        ],
91        "listeners" : {
92         "clicked" : [
93          " () => { ",
94          "    _this.saveContents();",
95          "    _this.window.windowstate.switchState(WindowState.State.PREVIEW);",
96          "}",
97          "  "
98         ]
99        },
100        "string icon_name" : "window-close",
101        "xtype" : "Button"
102       }
103      ],
104      "xtype" : "Box"
105     },
106     {
107      "$ xns" : "Gtk",
108      "Gtk.PolicyType hscrollbar_policy" : "Gtk.PolicyType.AUTOMATIC",
109      "Gtk.PolicyType vscrollbar_policy" : "Gtk.PolicyType.AUTOMATIC",
110      "bool overlay_scrolling" : false,
111      "bool vexpand" : true,
112      "id" : "RightEditor",
113      "items" : [
114       {
115        "# Gtk.CssProvider css" : "null",
116        "$ gboolean auto_indent" : true,
117        "$ xns" : "GtkSource",
118        "* init" : [
119         "",
120         "",
121         "this.css = new Gtk.CssProvider();",
122         "",
123         "this.css.load_from_string(",
124         "\t\"#editor-view { font:  12px monospace;}\"",
125         ");",
126         " ",
127         "Gtk.StyleContext.add_provider_for_display(",
128         "\tthis.el.get_display(),",
129         "\tthis.css,",
130         "\tGtk.STYLE_PROVIDER_PRIORITY_APPLICATION",
131         ");",
132         "\t",
133         " ",
134         "\t ",
135         "/*",
136         "this is pretty flakey - triggers Gtk with  < 0 d",
137         " var cp = new GtkSource.CompletionWords(\"test\"); ",
138         " cp.minimum_word_size  = 3;",
139         " //cp.priority = 100; //?? does this do anything",
140         " cp.proposals_batch_size  = 10;",
141         " cp.scan_batch_size = 1000;",
142         " ",
143         "cp.register(_this.buffer.el);",
144         "this.el.completion.add_provider(cp);",
145         "*/",
146         "this.el.completion.add_provider(new Palete.CompletionProvider(_this));",
147         "  ",
148         "//this.el.completion.unblock_interactive();",
149         "this.el.completion.select_on_show = true; // select",
150         "//this.el.completion.remember_info_visibility\t = true;",
151         "",
152         "",
153         "var attrs = new GtkSource.MarkAttributes();",
154         "var  pink =   Gdk.RGBA();",
155         "pink.parse ( \"pink\");",
156         "attrs.set_background ( pink);",
157         "attrs.set_icon_name ( \"process-stop\");    ",
158         "attrs.query_tooltip_text.connect(( mark) => {",
159         "     GLib.debug(\"tooltip query? %s\", mark.name);",
160         "    return strdup( mark.name);",
161         "});",
162         " attrs.query_tooltip_markup.connect(( mark) => {",
163         "     GLib.debug(\"tooltip query? %s\", mark.name);",
164         "    return strdup( mark.name);",
165         "});",
166         "this.el.set_mark_attributes (\"ERR\", attrs, 1);",
167         "attrs.ref();",
168         " var wattrs = new GtkSource.MarkAttributes();",
169         "var  blue =   Gdk.RGBA();",
170         "blue.parse ( \"#ABF4EB\");",
171         "wattrs.set_background ( blue);",
172         "wattrs.set_icon_name ( \"process-stop\");    ",
173         "wattrs.query_tooltip_text.connect(( mark) => {",
174         "     GLib.debug(\"tooltip query? %s\", mark.name);",
175         "    return strdup(mark.name);",
176         "});",
177         "wattrs.query_tooltip_markup.connect(( mark) => {",
178         "     GLib.debug(\"tooltip query? %s\", mark.name);",
179         "    return strdup(mark.name);",
180         "});",
181         "this.el.set_mark_attributes (\"WARN\", wattrs, 1);",
182         "wattrs.ref();",
183         "",
184         "",
185         " var dattrs = new GtkSource.MarkAttributes();",
186         "var  purple =   Gdk.RGBA();",
187         "purple.parse ( \"#EEA9FF\");",
188         "dattrs.set_background ( purple);",
189         "dattrs.set_icon_name ( \"process-stop\");    ",
190         "dattrs.query_tooltip_text.connect(( mark) => {",
191         "\tGLib.debug(\"tooltip query? %s\", mark.name);",
192         "    return strdup(mark.name);",
193         "});",
194         "dattrs.query_tooltip_markup.connect(( mark) => {",
195         "\tGLib.debug(\"tooltip query? %s\", mark.name);",
196         "    return strdup(mark.name);",
197         "});",
198         "this.el.set_mark_attributes (\"DEPR\", dattrs, 1);",
199         "dattrs.ref();    ",
200         "",
201         " this.el.get_space_drawer().set_matrix(null);",
202         " this.el.get_space_drawer().set_types_for_locations( ",
203         "\tGtkSource.SpaceLocationFlags.ALL,",
204         "\tGtkSource.SpaceTypeFlags.ALL",
205         ");",
206         "this.el.get_space_drawer().set_enable_matrix(true);",
207         ""
208        ],
209        "* prop" : "child",
210        "bool has_tooltip" : true,
211        "bool hexpand" : true,
212        "bool insert_spaces_instead_of_tabs" : true,
213        "bool vexpand" : true,
214        "boolean show_line_marks" : true,
215        "boolean show_line_numbers" : true,
216        "gboolean highlight_current_line" : true,
217        "id" : "view",
218        "indent_width" : 4,
219        "items" : [
220         {
221          "$ Gee.HashMap<int,string>? xmarks" : "null",
222          "$ xns" : "GtkSource",
223          "$ xtype" : "Buffer",
224          "* init" : [
225           "{",
226           "\tvar buf = this.el;",
227           "\tbuf.create_tag (\"bold\", \"weight\", Pango.Weight.BOLD);",
228           "    buf.create_tag (\"type\", \"weight\", Pango.Weight.BOLD, \"foreground\", \"#204a87\");",
229           "    buf.create_tag (\"keyword\", \"weight\", Pango.Weight.BOLD, \"foreground\", \"#a40000\");",
230           "    buf.create_tag (\"text\", \"weight\", Pango.Weight.NORMAL, \"foreground\", \"#729fcf\");",
231           "    buf.create_tag (\"number\", \"weight\", Pango.Weight.BOLD, \"foreground\", \"#ad7fa8\");",
232           "    buf.create_tag (\"method\", \"weight\", Pango.Weight.BOLD, \"foreground\", \"#729fcf\");",
233           "    buf.create_tag (\"property\", \"weight\", Pango.Weight.BOLD, \"foreground\", \"#BC1F51\");",
234           "    buf.create_tag (\"variable\", \"weight\", Pango.Weight.BOLD, \"foreground\", \"#A518B5\");",
235           "",
236           "}",
237           ""
238          ],
239          "* prop" : "buffer",
240          "bool check_queued" : false,
241          "bool enable_undo" : true,
242          "bool highlight_matching_brackets" : true,
243          "bool highlight_syntax" : true,
244          "id" : "buffer",
245          "int error_line" : "-1",
246          "listeners" : {
247           "changed" : [
248            " () => {",
249            "    // check syntax??",
250            "    // ??needed..??",
251            "    _this.save_button.el.sensitive = true;",
252            "    print(\"EDITOR CHANGED\");",
253            "    this.checkSyntax();",
254            "   ",
255            "    _this.dirty = true;",
256            "",
257            "    // this.get('/LeftPanel.model').changed(  str , false);",
258            "    return ;",
259            "}",
260            ""
261           ]
262          },
263          "| bool checkSyntax" : [
264           " () {",
265           " ",
266           "    ",
267           "    var str = this.toString();",
268           "    ",
269           "    // needed???",
270           "    if (this.error_line > 0) {",
271           "         Gtk.TextIter start;",
272           "         Gtk.TextIter end;     ",
273           "        this.el.get_bounds (out start, out end);",
274           "",
275           "        this.el.remove_source_marks (start, end, null);",
276           "    }",
277           "    if (str.length < 1) {",
278           "        print(\"checkSyntax - empty string?\\n\");",
279           "        return true;",
280           "    }",
281           "    ",
282           "    // bit presumptiona",
283           "    if (_this.file.xtype == \"PlainFile\") {",
284           "    ",
285           "        // assume it's gtk...",
286           "         var  oldcode =_this.file.toSource();",
287           "        _this.file.setSource(str);",
288           "\t    BuilderApplication.showSpinner(\"appointment soon\",\"document change pending\");",
289           "    \t_this.file.getLanguageServer().document_change(_this.file);",
290           "",
291           "        _this.file.setSource(oldcode);",
292           "        ",
293           "\t\t ",
294           "        return true;",
295           "    ",
296           "    }",
297           "   if (_this.file == null) {",
298           "       return true;",
299           "   }",
300           " ",
301           "    ",
302           "",
303           "      ",
304           "     ",
305           "    GLib.debug(\"calling validate\");    ",
306           "    // clear the buttons.",
307           " \tif (_this.prop.name == \"xns\" || _this.prop.name == \"xtype\") {",
308           "\t\treturn true ;",
309           "\t}",
310           "\tvar oldcode  = _this.prop.val;",
311           "\t",
312           "\t_this.prop.val = str;",
313           "\t_this.node.updated_count++;",
314           "    _this.file.getLanguageServer().document_change(_this.file);",
315           "    _this.node.updated_count++;",
316           "    _this.prop.val = oldcode;",
317           "    ",
318           "    ",
319           "    //print(\"done mark line\\n\");",
320           "     ",
321           "    return true; // at present allow saving - even if it's invalid..",
322           "}",
323           ""
324          ],
325          "| bool highlightErrors" : [
326           "( Gee.HashMap<int,string> validate_res) {",
327           "         ",
328           "\tthis.error_line = validate_res.size;",
329           "",
330           "\tif (this.error_line < 1) {",
331           "\t\treturn true;",
332           "\t}",
333           "\tvar tlines = this.el.get_line_count ();",
334           "\tGtk.TextIter iter;",
335           "\tvar valiter = validate_res.map_iterator();",
336           "\twhile (valiter.next()) {",
337           "",
338           "\t//        print(\"get inter\\n\");",
339           "\t\tvar eline = valiter.get_key();",
340           "\t\tif (eline > tlines) {",
341           "\t\t\tcontinue;",
342           "\t\t}",
343           "\t\tthis.el.get_iter_at_line( out iter, eline);",
344           "\t\t//print(\"mark line\\n\");",
345           "\t\tthis.el.create_source_mark(valiter.get_value(), \"ERR\", iter);",
346           "\t}   ",
347           "\treturn false;",
348           "}"
349          ],
350          "| bool highlightErrorsJson" : [
351           "(string type, Json.Object obj) {",
352           "\tGtk.TextIter start;",
353           "\tGtk.TextIter end;     ",
354           "\tthis.el.get_bounds (out start, out end);",
355           "",
356           "\tthis.el.remove_source_marks (start, end, type);",
357           "\tGLib.debug(\"highlight errors\");\t\t ",
358           "",
359           "\t // we should highlight other types of errors..",
360           "",
361           "\tif (!obj.has_member(type)) {",
362           "\t\tGLib.debug(\"Return has no errors\\n\");",
363           "\t\treturn true;",
364           "\t}",
365           "",
366           "\tif (_this.window.windowstate.state != WindowState.State.CODEONLY ",
367           "\t\t&&",
368           "\t\t_this.window.windowstate.state != WindowState.State.CODE",
369           "\t\t) {",
370           "\t\tGLib.debug(\"windowstate != CODEONLY?\");",
371           "\t\t",
372           "\t\treturn true;",
373           "\t} ",
374           "",
375           "\t//this.marks = new Gee.HashMap<int,string>();",
376           "\tvar err = obj.get_object_member(type);",
377           " ",
378           "\tif (_this.file == null) {",
379           "\t\tGLib.debug(\"file is null?\");",
380           "\t\treturn true;",
381           "",
382           "\t}",
383           "\tvar valafn = _this.file.path;",
384           "",
385           "\tif (_this.file.xtype != \"PlainFile\") {",
386           "",
387           "\t\tvalafn = \"\";",
388           "\t\ttry {             ",
389           "\t\t\tvar  regex = new Regex(\"\\\\.bjs$\");",
390           "\t\t\t// should not happen",
391           "\t      \t\tvalafn = regex.replace(_this.file.path,_this.file.path.length , 0 , \".vala\");",
392           "\t\t} catch (GLib.RegexError e) {",
393           "\t\t\treturn true;",
394           "\t\t}   ",
395           "",
396           "",
397           "",
398           "\t}",
399           "\tif (!err.has_member(valafn)) {",
400           "\t\tGLib.debug(\"File path has no errors\");",
401           "\t\treturn  true;",
402           "\t}",
403           "",
404           "\tvar lines = err.get_object_member(valafn);",
405           "\t",
406           "\tvar offset = 1;",
407           "\tif (obj.has_member(\"line_offset\")) { // ?? why??",
408           "\t\toffset = (int)obj.get_int_member(\"line_offset\") + 1;",
409           "\t}",
410           "",
411           "",
412           "\tvar tlines = this.el.get_line_count () +1;",
413           "\t",
414           "\tif (_this.prop != null) {",
415           "\t",
416           "\t\ttlines = _this.prop.end_line + 1;",
417           "\t\toffset = _this.prop.start_line + 1;",
418           "\t",
419           "\t}",
420           "\t",
421           "",
422           "",
423           "\tlines.foreach_member((obj, line, node) => {",
424           "\t\t",
425           "\t     Gtk.TextIter iter;",
426           "//        print(\"get inter\\n\");",
427           "\t    var eline = int.parse(line) - offset;",
428           "\t    GLib.debug(\"GOT ERROR on line %s -- converted to %d  (offset = %d)\\n\", line,eline, offset);",
429           "\t    ",
430           "\t    ",
431           "\t    if (eline > tlines || eline < 0) {",
432           "\t        return;",
433           "\t    }",
434           "\t   ",
435           "\t    ",
436           "\t    this.el.get_iter_at_line( out iter, eline);",
437           "\t    //print(\"mark line\\n\");",
438           "\t    var msg  = \"\";",
439           "\t    var ar = lines.get_array_member(line);",
440           "\t    for (var i = 0 ; i < ar.get_length(); i++) {",
441           "\t    \tif (ar.get_string_element(i) == \"Success\") {",
442           "\t    \t\tcontinue;",
443           "    \t\t}",
444           "\t\t\tmsg += (msg.length > 0) ? \"\\n\" : \"\";",
445           "\t\t\tmsg += ar.get_string_element(i);",
446           "\t\t}",
447           "\t\tif (msg == \"\") {",
448           "\t\t\treturn;",
449           "\t\t}",
450           "\t\tmsg = \"Line: %d\".printf(eline+1) +  \" \" + msg;",
451           "\t    this.el.create_source_mark(msg, type, iter);",
452           "\t    GLib.debug(\"set line %d to %m\", eline, msg);",
453           "\t   // this.marks.set(eline, msg);",
454           "\t} );",
455           "\treturn false;",
456           "",
457           "",
458           "",
459           "",
460           "",
461           "\t}",
462           ""
463          ],
464          "| string toString" : [
465           "  () {",
466           "    ",
467           "    Gtk.TextIter s;",
468           "    Gtk.TextIter e;",
469           "    this.el.get_start_iter(out s);",
470           "    this.el.get_end_iter(out e);",
471           "    var ret = this.el.get_text(s,e,true);",
472           "    //print(\"TO STRING? \" + ret);",
473           "    return ret;",
474           "}",
475           " "
476          ]
477         },
478         {
479          "$ xns" : "Gtk",
480          "listeners" : {
481           "key_released" : [
482            "(keyval, keycode, state) => {",
483            "",
484            "  ",
485            "    if (keyval == Gdk.Key.s && (state & Gdk.ModifierType.CONTROL_MASK ) > 0 ) {",
486            "        GLib.debug(\"SAVE: ctrl-S  pressed\");",
487            "        _this.saveContents();",
488            "        return;",
489            "    }",
490            "    ",
491            "    if (keyval == Gdk.Key.g && (state & Gdk.ModifierType.CONTROL_MASK ) > 0 ) {",
492            "\t    GLib.debug(\"SAVE: ctrl-g  pressed\");",
493            "\t\t_this.forwardSearch(true);",
494            "\t    return;",
495            "\t}",
496            "\tif (keyval == Gdk.Key.f && (state & Gdk.ModifierType.CONTROL_MASK ) > 0 ) {",
497            "\t    GLib.debug(\"SAVE: ctrl-f  pressed\");",
498            "\t\t_this.search_entry.el.grab_focus();",
499            "\t\t_this.search_entry.el.select_region(0,-1);",
500            "\t    return;",
501            "\t}",
502            "\tif (keyval == Gdk.Key.space && (state & Gdk.ModifierType.CONTROL_MASK ) > 0 ) {",
503            "\t\t_this.view.el.show_completion();",
504            "\t}",
505            "\t",
506            "\tGtk.TextIter iter;",
507            "\t_this.buffer.el.get_iter_at_offset( out iter, _this.buffer.el.cursor_position);  ",
508            "\tvar line  = iter.get_line();",
509            "\tvar offset = iter.get_line_offset();",
510            "\tGLib.debug(\"line  %d  off %d\", line ,offset);",
511            "\tif (_this.prop != null) {",
512            "\t\tline += _this.prop.start_line + 1; // i think..",
513            "\t\toffset += 12; // should probably be 8 without namespaced ",
514            "\t\tGLib.debug(\"guess line  %d  off %d\", line ,offset);",
515            "\t} ",
516            "    //_this.view.el.show_completion();",
517            "   // print(event.key.keyval)",
518            "   ",
519            "   ",
520            "   ",
521            "    ",
522            "    return;",
523            " ",
524            " ",
525            "}",
526            ""
527           ]
528          },
529          "xtype" : "EventControllerKey"
530         }
531        ],
532        "listeners" : {
533         "query_tooltip" : [
534          "(x, y, keyboard_tooltip, tooltip) => {",
535          "\t",
536          "\t//GLib.debug(\"query tooltip\");",
537          "\tGtk.TextIter iter;",
538          "\tint trailing;",
539          "\t",
540          "\tvar yoff = (int) _this.RightEditor.el.vadjustment.value;",
541          "\t",
542          "\t// I think this is problematic - if it's compliing  / updating at same time as query.",
543          "\t",
544          "\t//if (_this.window.statusbar_compile_spinner.el.spinning) {",
545          "\t//\treturn false;",
546          "\t//}",
547          "\t",
548          "\tthis.el.get_iter_at_position (out iter, out trailing,  x,  y + yoff);",
549          "\t ",
550          "\tvar l = iter.get_line();",
551          "",
552          "\t",
553          "\t ",
554          "\t// GLib.debug(\"query tooltip line %d\", (int) l);",
555          "\tif (l < 0) {",
556          "",
557          "\t\treturn false;",
558          "\t}",
559          "\t/*",
560          "\tif (_this.buffer.marks != null && _this.buffer.marks.has_key(l)) {",
561          "\t\tGLib.debug(\"line %d setting tip to %s\", l,  _this.buffer.marks.get(l));",
562          "\t\ttooltip.set_text(_this.buffer.marks.get(l).dup());",
563          "\t\treturn true;",
564          "\t}",
565          " ",
566          "\treturn false;",
567          "\t*/",
568          "\t",
569          "\t  ",
570          "\t// this crashes?? - not sure why.",
571          "\tvar marks = _this.buffer.el.get_source_marks_at_line(l, \"ERR\");",
572          "\tif (marks.is_empty()) {",
573          "\t\tmarks = _this.buffer.el.get_source_marks_at_line(l, \"WARN\");",
574          "\t}",
575          "\tif (marks.is_empty()) {",
576          "\t\tmarks = _this.buffer.el.get_source_marks_at_line(l, \"DEPR\");",
577          "\t}",
578          "\t",
579          "\t// GLib.debug(\"query tooltip line %d marks %d\", (int)l, (int) marks.length());",
580          "\tvar str = \"\";",
581          "\tmarks.@foreach((m) => { ",
582          "\t\t//GLib.debug(\"got mark %s\", m.name);",
583          "\t\tstr += (str.length > 0 ? \"\\n\" : \"\") + m.category + \": \" + m.name;",
584          "\t});",
585          "\t// true if there is a mark..",
586          "\tif (str.length > 0 ) {",
587          "\t\ttooltip.set_text( str );",
588          "\t}",
589          "\treturn str.length > 0 ? true : false;",
590          "\t ",
591          "}",
592          ""
593         ]
594        },
595        "string name" : "editor-view",
596        "uint tab_width" : 4,
597        "xtype" : "View",
598        "| void load" : [
599         " (string str) {",
600         "",
601         "// show the help page for the active node..",
602         "   //this.get('/Help').show();",
603         " ",
604         "  // this.get('/BottomPane').el.set_current_page(0);",
605         "  \tGLib.debug(\"load called - Reset undo buffer\");",
606         "  \t",
607         "    var buf = (GtkSource.Buffer)this.el.get_buffer();",
608         "    buf.begin_irreversible_action();",
609         "    buf.set_text(str, str.length);",
610         "    buf.end_irreversible_action();",
611         "    ",
612         "    var lm = GtkSource.LanguageManager.get_default();",
613         "    var lang = \"vala\";",
614         "    if (_this.file != null) {",
615         "         lang = _this.file.language;",
616         "    }",
617         "    print(\"lang=%s, content_type = %s\\n\", lang, _this.file.content_type);",
618         "    var lg = _this.file.content_type.length > 0  ?",
619         "            lm.guess_language(_this.file.path, _this.file.content_type) :",
620         "            lm.get_language(lang);",
621         "     ",
622         "   ",
623         "    ((GtkSource.Buffer)(this.el.get_buffer())) .set_language(lg); ",
624         "",
625         "    this.el.insert_spaces_instead_of_tabs = true;",
626         "    if (lg != null) {",
627         "\t\tprint(\"sourcelanguage  = %s\\n\", lg.name);",
628         "\t\tif (lg.name == \"Vala\") {",
629         "\t\t    this.el.insert_spaces_instead_of_tabs = false;",
630         "\t\t}",
631         "     }",
632         "    _this.dirty = false;",
633         "    this.el.grab_focus();",
634         "    _this.save_button.el.sensitive = false;",
635         "}"
636        ]
637       }
638      ],
639      "xtype" : "ScrolledWindow"
640     },
641     {
642      "$ xns" : "Gtk",
643      "* pack" : "append",
644      "Gtk.Orientation orientation" : "Gtk.Orientation.HORIZONTAL",
645      "bool homogeneous" : false,
646      "bool vexpand" : false,
647      "int spacing" : 0,
648      "items" : [
649       {
650        "$ xns" : "Gtk",
651        "Gtk.CssProvider css" : "",
652        "bool hexpand" : true,
653        "id" : "search_entry",
654        "items" : [
655         {
656          "$ xns" : "Gtk",
657          "listeners" : {
658           "key_pressed" : [
659            "(keyval, keycode, state) => {",
660            "",
661            "\tif (keyval == Gdk.Key.g && (state & Gdk.ModifierType.CONTROL_MASK ) > 0 ) {",
662            "\t    GLib.debug(\"SAVE: ctrl-g  pressed\");",
663            "\t\t_this.forwardSearch(true);",
664            "\t    return true;",
665            "\t}",
666            "    ",
667            "  ",
668            " \tif (keyval == Gdk.Key.Return && _this.search_entry.el.text.length > 0) {",
669            "\t\t_this.forwardSearch(true);",
670            "\t\t",
671            "\t\t",
672            "\t    return true;",
673            "",
674            "\t}    ",
675            "   // print(event.key.keyval)",
676            "   ",
677            "    return false;",
678            "}",
679            ""
680           ]
681          },
682          "xtype" : "EventControllerKey"
683         }
684        ],
685        "listeners" : {
686         "search_changed" : [
687          "( ) => {",
688          "",
689          "_this.search(_this.search_entry.el.text);",
690          "\t _this.search_results.updateResults();",
691          "",
692          "\tGLib.Timeout.add_seconds(1,() => {",
693          "\t\t _this.search_results.updateResults();",
694          "\t\t return false;",
695          "\t });",
696          "}",
697          ""
698         ]
699        },
700        "string name" : "editor-search-entry",
701        "string placeholder_text" : "Press enter to search",
702        "uint search_delay" : 3,
703        "xtype" : "SearchEntry",
704        "| void forwardSearch" : [
705         "(bool change_focus) {",
706         "",
707         "",
708         "\t_this.forwardSearch(change_focus);",
709         "",
710         "/*",
711         "",
712         "\tswitch(_this.windowstate.state) {",
713         "\t\tcase WindowState.State.CODEONLY:",
714         "\t\t//case WindowState.State.CODE:",
715         "\t\t\t// search the code being edited..",
716         "\t\t\t_this.windowstate.code_editor_tab.forwardSearch(change_focus);",
717         "\t\t\t ",
718         "\t\t\tbreak;",
719         "\t\tcase WindowState.State.PREVIEW:",
720         "\t\t\tif (_this.windowstate.file.xtype == \"Gtk\") {",
721         "\t\t\t\t_this.windowstate.window_gladeview.forwardSearch(change_focus);",
722         "\t\t\t} else { ",
723         "\t\t\t\t _this.windowstate.window_rooview.forwardSearch(change_focus);",
724         "\t\t\t}",
725         "\t\t",
726         "\t\t\tbreak;",
727         "\t}",
728         "\t*/",
729         "\t",
730         "}",
731         ""
732        ]
733       },
734       {
735        "$ xns" : "Gtk",
736        "id" : "search_results",
737        "int margin_end" : 4,
738        "int margin_start" : 4,
739        "string label" : "No Results",
740        "xtype" : "Label",
741        "| void updateResults" : [
742         "() {",
743         "\tthis.el.visible = true;",
744         "\t",
745         "\tvar res = _this.searchcontext.get_occurrences_count();",
746         "\tif (res < 0) {",
747         "\t\t_this.search_results.el.label = \"??? Matches\";\t\t",
748         "\t\treturn;",
749         "\t}",
750         "",
751         "\t_this.nextBtn.el.sensitive = false;",
752         "\t_this.backBtn.el.sensitive = false;\t",
753         "",
754         "\tif (res > 0) {",
755         "\t\t_this.search_results.el.label = \"%d Matches\".printf(res);",
756         "\t\t_this.nextBtn.el.sensitive = true;",
757         "\t\t_this.backBtn.el.sensitive = true;",
758         "\t\treturn;",
759         "\t} ",
760         "\t_this.search_results.el.label = \"No Matches\";",
761         "\t",
762         "}"
763        ]
764       },
765       {
766        "$ xns" : "Gtk",
767        "bool always_show_image" : true,
768        "bool sensitive" : false,
769        "id" : "nextBtn",
770        "listeners" : {
771         "clicked" : [
772          "(event) => {",
773          "",
774          "\t_this.forwardSearch(true);",
775          "\t",
776          "\t ",
777          "}",
778          ""
779         ]
780        },
781        "string icon_name" : "go-down",
782        "xtype" : "Button"
783       },
784       {
785        "$ xns" : "Gtk",
786        "bool always_show_image" : true,
787        "bool sensitive" : false,
788        "id" : "backBtn",
789        "listeners" : {
790         "clicked" : [
791          "(event) => {",
792          "",
793          "\t_this.backSearch(true);",
794          "\t ",
795          "}",
796          ""
797         ]
798        },
799        "string icon_name" : "go-up",
800        "xtype" : "Button"
801       },
802       {
803        "$ xns" : "Gtk",
804        "bool always_show_arrow" : true,
805        "bool always_show_image" : true,
806        "items" : [
807         {
808          "$ xns" : "Gtk",
809          "* prop" : "popover",
810          "id" : "search_settings",
811          "items" : [
812           {
813            "$ xns" : "Gtk",
814            "* prop" : "child",
815            "Gtk.Orientation orientation" : "Gtk.Orientation.VERTICAL",
816            "int spacing" : 0,
817            "items" : [
818             {
819              "$ xns" : "Gtk",
820              "* init" : [
821               "{",
822               "\tthis.el.show();",
823               "}",
824               ""
825              ],
826              "id" : "case_sensitive",
827              "string label" : "Case Sensitive",
828              "xtype" : "CheckButton"
829             },
830             {
831              "$ xns" : "Gtk",
832              "* init" : [
833               "{",
834               "\tthis.el.show();",
835               "}",
836               ""
837              ],
838              "id" : "regex",
839              "string label" : "Regex",
840              "xtype" : "CheckButton"
841             },
842             {
843              "$ xns" : "Gtk",
844              "id" : "multiline",
845              "string label" : "Multi-line (add \\n)",
846              "xtype" : "CheckButton"
847             }
848            ],
849            "xtype" : "Box"
850           }
851          ],
852          "xtype" : "Popover"
853         }
854        ],
855        "string icon_name" : "emblem-system",
856        "xtype" : "MenuButton"
857       }
858      ],
859      "xtype" : "Box"
860     }
861    ],
862    "xtype" : "Box",
863    "| bool saveContents" : [
864     "  ()  {",
865     "    ",
866     "    ",
867     "    if (_this.file == null) {",
868     "        return true;",
869     "    }",
870     "    ",
871     "     ",
872     "     ",
873     "     var str = _this.buffer.toString();",
874     "     ",
875     "     _this.buffer.checkSyntax();",
876     "     ",
877     "     ",
878     "     ",
879     "     // LeftPanel.model.changed(  str , false);",
880     "     _this.dirty = false;",
881     "     _this.save_button.el.sensitive = false;",
882     "     ",
883     "    // find the text for the node..",
884     "    if (_this.file.xtype != \"PlainFile\") {",
885     "       // in theory these properties have to exist!?!",
886     "    \tthis.prop.val = str;",
887     "        //this.window.windowstate.left_props.reload();",
888     "    } else {",
889     "        _this.file.setSource(  str );",
890     "     }",
891     "    ",
892     "    // call the signal..",
893     "    this.save();",
894     "    ",
895     "    return true;",
896     "",
897     "} "
898    ],
899    "| int search" : [
900     "(string in_txt) {",
901     "",
902     "\tvar s = new GtkSource.SearchSettings();",
903     "\ts.case_sensitive = _this.case_sensitive.el.active;",
904     "\ts.regex_enabled = _this.regex.el.active;\t",
905     "\ts.wrap_around = false;",
906     "\t",
907     "\tthis.searchcontext = new GtkSource.SearchContext(this.buffer.el,s);",
908     "\tthis.searchcontext.set_highlight(true);",
909     "\tvar txt = in_txt;",
910     "\t",
911     "\tif (_this.multiline.el.active) {",
912     "\t\ttxt = in_txt.replace(\"\\\\n\", \"\\n\");",
913     "\t}",
914     "\t",
915     "\ts.set_search_text(txt);",
916     "\tGtk.TextIter beg, st,en;",
917     "\t ",
918     "\tthis.buffer.el.get_start_iter(out beg);",
919     "\tbool has_wrapped_around;",
920     "\tthis.searchcontext.forward(beg, out st, out en, out has_wrapped_around);",
921     "\tthis.last_search_end = 0;",
922     "\t",
923     "\treturn this.searchcontext.get_occurrences_count();",
924     "",
925     " ",
926     "   ",
927     "",
928     "}",
929     ""
930    ],
931    "| string tempFileContents" : [
932     "() {",
933     "   ",
934     "   ",
935     "   if (_this.file == null) {",
936     "       return \"\";",
937     "   }",
938     "\tvar str= this.buffer.toString();",
939     "\tif (_this.file.xtype == \"PlainFile\") {",
940     "    ",
941     "     \treturn str;",
942     "    ",
943     "    }",
944     "  ",
945     "      ",
946     "     ",
947     "    GLib.debug(\"calling validate\");    ",
948     "    // clear the buttons.",
949     " \tif (_this.prop.name == \"xns\" || _this.prop.name == \"xtype\") {",
950     "\t\treturn this.file.toSource(); ;",
951     "\t}",
952     "\t",
953     "\tvar oldcode  = _this.prop.val;",
954     "\t_this.prop.val = str;",
955     "    var ret = _this.file.toSource();",
956     "    _this.prop.val = oldcode;",
957     "    return ret;",
958     "    ",
959     "}"
960    ],
961    "| void backSearch" : [
962     "(bool change_focus) {",
963     "",
964     "\tif (this.searchcontext == null) {",
965     "\t\treturn;",
966     "\t} ",
967     "\t",
968     "\tGtk.TextIter beg, st,en;",
969     "\tbool has_wrapped_around;",
970     "\tthis.buffer.el.get_iter_at_offset(out beg, this.last_search_end -1 );",
971     "\t",
972     "\tif (!this.searchcontext.backward(beg, out st, out en, out has_wrapped_around)) {",
973     "\t\tthis.last_search_end = 0;",
974     "\t} else {",
975     "\t\tthis.last_search_end = en.get_offset();",
976     "\t\tif (change_focus) {",
977     "\t\t\tthis.view.el.grab_focus();",
978     "\t\t}",
979     "\t\tthis.buffer.el.place_cursor(st);",
980     "\t\tthis.view.el.scroll_to_iter(st,  0.1f, true, 0.0f, 0.5f);",
981     "\t}",
982     "",
983     "}",
984     ""
985    ],
986    "| void forwardSearch" : [
987     "(bool change_focus) {",
988     "",
989     "\tif (this.searchcontext == null) {",
990     "\t\treturn;",
991     "\t} ",
992     "",
993     "\tGtk.TextIter beg, st,en;",
994     "\t bool has_wrapped_around;",
995     "\tthis.buffer.el.get_iter_at_offset(out beg, this.last_search_end);",
996     "\tif (!this.searchcontext.forward(beg, out st, out en, out has_wrapped_around)) {",
997     "\t",
998     "\t\tthis.last_search_end = 0; // not sure if this should happen",
999     "\t} else {",
1000     "\t\tif (has_wrapped_around) {",
1001     "\t\t\treturn;",
1002     "\t\t}",
1003     "\t",
1004     "\t\tthis.last_search_end = en.get_offset();",
1005     "\t\tif (change_focus) {",
1006     "\t\t\tthis.view.el.grab_focus();",
1007     "\t\t}",
1008     "\t\tthis.buffer.el.place_cursor(st);",
1009     "\t\tthis.view.el.scroll_to_iter(st,  0.1f, true, 0.0f, 0.5f);",
1010     "\t}",
1011     " ",
1012     "}",
1013     ""
1014    ],
1015    "| void reset" : [
1016     "() {",
1017     "\t this.file = null;    ",
1018     "     ",
1019     "    this.node = null;",
1020     "    this.prop = null;",
1021     "\tthis.searchcontext = null;",
1022     "  ",
1023     "}",
1024     ""
1025    ],
1026    "| void scroll_to_line" : [
1027     "(int line) {",
1028     "",
1029     "\tGLib.Timeout.add(500, () => {",
1030     "   ",
1031     "\t\tvar buf = this.view.el.get_buffer();",
1032     "",
1033     "\t\tvar sbuf = (GtkSource.Buffer) buf;",
1034     "",
1035     "",
1036     "\t\tGtk.TextIter iter;   ",
1037     "\t\tsbuf.get_iter_at_line(out iter,  line);",
1038     "\t\tthis.view.el.scroll_to_iter(iter,  0.1f, true, 0.0f, 0.5f);",
1039     "\t\treturn false;",
1040     "\t});   ",
1041     "}",
1042     ""
1043    ],
1044    "| void show" : [
1045     "(JsRender.JsRender file, JsRender.Node? node, JsRender.NodeProp? prop)",
1046     "{",
1047     "    this.reset();",
1048     "    this.file = file;    ",
1049     "    ",
1050     "    if (file.xtype != \"PlainFile\") {",
1051     "    \tthis.prop = prop;",
1052     "        this.node = node;",
1053     "",
1054     "        // find the text for the node..",
1055     "        this.view.load( prop.val );",
1056     "        ",
1057     "        ",
1058     "        this.close_btn.el.show();       ",
1059     "    ",
1060     "    } else {",
1061     "        this.view.load(        file.toSource() );",
1062     "        this.close_btn.el.hide();",
1063     "    }",
1064     " ",
1065     "}"
1066    ],
1067    "| void updateErrorMarks" : [
1068     "(string category) {",
1069     "\t",
1070     " ",
1071     "",
1072     "\tvar buf = _this.buffer.el;",
1073     "\tGtk.TextIter start;",
1074     "\tGtk.TextIter end;     ",
1075     "\tbuf.get_bounds (out start, out end);",
1076     "",
1077     "\tbuf.remove_source_marks (start, end, category);",
1078     " ",
1079     "\t//GLib.debug(\"highlight errors\");\t\t ",
1080     "",
1081     "\t // we should highlight other types of errors..",
1082     "",
1083     "\tif (_this.window.windowstate.state != WindowState.State.CODEONLY ",
1084     "\t\t&&",
1085     "\t\t_this.window.windowstate.state != WindowState.State.CODE",
1086     "\t\t) {",
1087     "\t\t//GLib.debug(\"windowstate != CODEONLY?\");",
1088     "\t\t",
1089     "\t\treturn;",
1090     "\t} ",
1091     "",
1092     "\t ",
1093     "\tif (_this.file == null) {",
1094     "\t\tGLib.debug(\"file is null?\");",
1095     "\t\treturn;",
1096     "",
1097     "\t}",
1098     "\tvar ar = this.file.getErrors(category);",
1099     "\tif (ar == null || ar.get_n_items() < 1) {",
1100     "\t\t//GLib.debug(\"highlight %s :  %s has no errors\", this.file.relpath, category);",
1101     "\t\treturn;",
1102     "\t}",
1103     " ",
1104     "",
1105     " ",
1106     "\t",
1107     "\tvar offset = 0;",
1108     "\t ",
1109     "",
1110     "\tvar tlines = buf.get_line_count () +1;",
1111     "\t",
1112     "\tif (_this.prop != null) {",
1113     "\t\t// this still seems flaky...",
1114     "\t\t",
1115     "\t\ttlines = _this.prop.end_line;",
1116     "\t\toffset = _this.prop.start_line;",
1117     "\t\t ",
1118     "\t}",
1119     "\t ",
1120     "\tfor (var i = 0; i < ar.get_n_items();i++) {",
1121     "\t\tvar err = (Palete.CompileError) ar.get_item(i);",
1122     "\t\t",
1123     "\t     Gtk.TextIter iter;",
1124     "//        print(\"get inter\\n\");",
1125     "\t    var eline = err.line - offset;",
1126     "\t    //GLib.debug(\"GOT ERROR on line %d -- converted to %d  (offset = %d)\",",
1127     "\t    //\terr.line ,eline, offset);",
1128     "\t    ",
1129     "\t    ",
1130     "\t    if (eline > tlines || eline < 0) {",
1131     "\t        return;",
1132     "\t    }",
1133     "\t   ",
1134     "\t    ",
1135     "\t    buf.get_iter_at_line( out iter, eline);",
1136     "\t   ",
1137     "\t   ",
1138     "\t\tvar msg = \"Line: %d %s : %s\".printf(eline+1, err.category, err.msg);",
1139     "\t    buf.create_source_mark( msg, err.category, iter);",
1140     "\t   // GLib.debug(\"set line %d to %s\", eline, msg);",
1141     "\t    //this.marks.set(eline, msg);",
1142     "\t}",
1143     "\treturn ;",
1144     "",
1145     "",
1146     "",
1147     " ",
1148     "",
1149     "}"
1150    ]
1151   }
1152  ],
1153  "name" : "Editor"
1154 }