Merge branch 'master' of http://git.roojs.com/roobuilder
[roobuilder] / src / Builder4 / Editor.bjs
index dd0a0c2..ed341c2 100644 (file)
     {
      "$ xns" : "Gtk",
      "Gtk.Orientation orientation" : "Gtk.Orientation.HORIZONTAL",
+     "bool resize_end_child" : false,
+     "bool resize_start_child" : false,
+     "bool shrink_end_child" : false,
+     "bool shrink_start_child" : false,
+     "id" : "paned",
      "items" : [
       {
        "$ xns" : "Gtk",
        "* prop" : "start_child",
        "Gtk.Orientation orientation" : "Gtk.Orientation.VERTICAL",
+       "bool hexpand" : true,
        "int spacing" : 0,
        "items" : [
         {
          "$ homogeneous" : false,
          "$ xns" : "Gtk",
          "Gtk.Orientation orientation" : "Gtk.Orientation.HORIZONTAL",
-         "bool hexpand" : true,
+         "bool hexpand" : false,
+         "bool vexpand" : false,
          "items" : [
           {
            "$ xns" : "Gtk",
+           "bool vexpand" : true,
            "id" : "save_button",
            "label" : "Save",
            "listeners" : {
           },
           {
            "$ xns" : "Gtk",
+           "Gtk.Justification justify" : "Gtk.Justification.LEFT",
            "bool hexpand" : true,
-           "xtype" : "Label"
+           "float xalign" : 0,
+           "id" : "helper",
+           "int margin_end" : 4,
+           "int margin_start" : 4,
+           "listeners" : {
+            "activate_link" : [
+             "(uri) => {",
+             "\tGLib.debug(\"got uri %s\", uri);",
+             "\tvar ls = _this.file.getLanguageServer();",
+             "\tls.symbol.begin(uri, (a,b) => {",
+             "\t\tls.symbol.end(b);",
+             "\t});",
+             "\t",
+             "\treturn true;",
+             "}",
+             ""
+            ],
+            "query_tooltip" : [
+             "(x, y, keyboard_tooltip, tooltip) => {",
+             "\tGLib.debug(\"using quiery tooltip?\");",
+             "\tvar lbl = new Gtk.Label(this.el.tooltip_markup);",
+             "\tlbl.width_request = 500;",
+             "\ttooltip.set_custom(lbl);",
+             "",
+             "\treturn true;",
+             "}",
+             ""
+            ]
+           },
+           "xtype" : "Label",
+           "| void setHelp" : [
+            "(Lsp.Hover? help) {",
+            "\tif (help == null || help.contents == null",
+            "\t\t|| help.contents.size < 1) {",
+            "\t\tthis.el.set_text(\"\");",
+            "\t\treturn;",
+            "\t}",
+            "\tvar sig = help.contents.get(0).value.split(\" \");",
+            "\tstring[] str = {};",
+            "\tfor(var i =0; i < sig.length; i++) {",
+            "\t",
+            "\t\tswitch(sig[i]) {",
+            "\t\t\tcase \"public\":",
+            "\t\t\tcase \"private\":",
+            "\t\t\tcase \"protected\":",
+            "\t\t\tcase \"async\":",
+            "\t\t\tcase \"class\":",
+            "\t\t\tcase \"{\":",
+            "\t\t\tcase \"}\":",
+            "\t\t\tcase \"(\":",
+            "\t\t\tcase \")\":",
+            "\t\t\t",
+            "\t\t\t\tstr += sig[i];",
+            "\t\t\t\tcontinue;",
+            "\t\t\t\t",
+            "\t\t\t\t",
+            "\t\t\tdefault:",
+            "\t",
+            "\t\t\t\tstr += (\"<a href=\\\"\" + GLib.Markup.escape_text(sig[i]) + \"\\\">\" + ",
+            "\t\t\t\t\tGLib.Markup.escape_text(sig[i])",
+            "\t\t\t\t\t+\"</a>\");",
+            "\t\t\tcontinue;",
+            "\t\t}",
+            "\t}",
+            "\tif (help.contents.size > 1) {",
+            "\t\tthis.el.tooltip_markup =  GLib.Markup.escape_text(help.contents.get(1).value);",
+            "\t} else {",
+            "\t\tthis.el.tooltip_markup = GLib.Markup.escape_text(help.contents.get(0).value);",
+            "\t}",
+            "\tthis.el.set_markup(string.joinv(\" \",str));",
+            "\t",
+            "}"
+           ]
           },
           {
            "$ xns" : "Gtk",
             "}",
             ""
            ],
+           "Gtk.Align halign" : "Gtk.Align.END",
            "bool draw_value" : false,
            "bool has_origin" : true,
            "bool sensitive" : true,
            "int digits" : 0,
-           "int width_request" : 200,
+           "int width_request" : 150,
            "listeners" : {
             "change_value" : [
              "(st, val ) => {",
           },
           {
            "$ xns" : "Gtk",
+           "Gtk.Align halign" : "Gtk.Align.END",
            "id" : "close_btn",
            "items" : [
             {
                "    return ;",
                "}",
                ""
+              ],
+              "cursor_moved" : [
+               "( ) => {",
+               "",
+               "\tGtk.TextIter iter;",
+               "\tthis.el.get_iter_at_offset (",
+               "\t\t\tout iter, this.el.cursor_position);",
+               "",
+               "\t_this.navigation.updateSelectedLine(",
+               "\t\t\t(uint)iter.get_line(),",
+               "\t\t\t(uint)iter.get_line_offset()",
+               "\t\t);",
+               "\tthis.showHelp(iter);",
+               "",
+               "}",
+               ""
               ]
              },
              "| bool OLDhighlightErrorsJson" : [
               "        _this.file.setSource(str);",
               "\t    BuilderApplication.showSpinner(\"appointment soon\",\"document change pending\");",
               "    \t_this.file.getLanguageServer().document_change(_this.file);",
-              "",
+              "\t\t_this.file.getLanguageServer().queueDocumentSymbols(_this.file);",
               "        _this.file.setSource(oldcode);",
               "        ",
               "\t\t ",
               "    return ret;",
               "}",
               " "
+             ],
+             "| void showHelp" : [
+              "(Gtk.TextIter iter) {",
+              "\tvar back = iter.copy();",
+              "\tback.backward_char();",
+              "\t",
+              "\tvar forward = iter.copy();",
+              "\tforward.forward_char();",
+              "\t",
+              "\t// what's the character at the iter?",
+              "\tvar str = back.get_text(iter);",
+              "\tstr += iter.get_text(forward);",
+              "\tif (str.strip().length < 1) {",
+              "\t\treturn;",
+              "\t}",
+              "\tvar offset = iter.get_line_offset();",
+              "\tvar line = iter.get_line();",
+              "\tif (_this.prop != null) {",
+              "\t\t\t\t// ",
+              "\t\tline += _this.prop.start_line ; ",
+              "\t\t\t\t\t// this is based on Gtk using tabs (hence 1/2 chars);",
+              "\t\toffset += _this.node.node_pad.length;",
+              "\t\t\t\t\t// javascript listeners are indented 2 more spaces.",
+              "\t\tif (_this.prop.ptype == JsRender.NodePropType.LISTENER) {",
+              "\t\t\toffset += 2;",
+              "\t\t}",
+              "\t} ",
+              "\t",
+              "\tvar ls = _this.file.getLanguageServer();",
+              "\tls.hover.begin(",
+              "\t\t_this.file, line, offset,",
+              "\t\t( a, o)  => {",
+              "\t\t\ttry {",
+              "\t\t\t\tvar res = ls.hover.end(o );",
+              "\t\t\t",
+              "\t\t\t\t_this.helper.setHelp(res);",
+              "\t\t\t} catch (GLib.Error e) {",
+              "\t\t\t\t// noop..",
+              "\t\t\t}",
+              "\t\t});",
+              "}\t",
+              "\t\t ",
+              ""
              ]
             },
             {
                "\t} ",
                "    //_this.view.el.show_completion();",
                "   // print(event.key.keyval)",
-               "   ",
-               "   ",
-               "   ",
+               "    ",
                "    ",
                "    return;",
                " ",
             },
             {
              "$ xns" : "Gtk",
+             "listeners" : {
+              "pressed" : [
+               "(n_press, x, y) => {",
+               "\tGtk.TextIter iter;",
+               "\tint  buffer_x, buffer_y;",
+               "\tvar gut = _this.view.el.get_gutter(Gtk.TextWindowType.LEFT);",
+               "\t",
+               "\t _this.view.el.window_to_buffer_coords (Gtk.TextWindowType.TEXT,",
+               "\t\t(int)x - gut.get_width(),  (int)y,",
+               "  \t\tout  buffer_x, out  buffer_y);",
+               "\t_this.view.el.get_iter_at_location (out  iter,  ",
+               "\t\t\tbuffer_x,  buffer_y);;",
+               "\t",
+               "\t",
+               "\tif (_this.buffer.el.iter_has_context_class(iter, \"comment\") ||",
+               "\t\t_this.buffer.el.iter_has_context_class(iter, \"string\")",
+               "\t) { ",
+               "\t\treturn ;",
+               "\t}",
+               "\t_this.buffer.showHelp(iter);",
+               "\t ",
+               "\t\t ",
+               " ",
+               "}",
+               ""
+              ]
+             },
              "xtype" : "GestureClick"
             }
            ],
       {
        "$ xns" : "Gtk",
        "* prop" : "end_child",
+       "Gtk.Orientation orientation" : "Gtk.Orientation.VERTICAL",
+       "bool hexpand" : true,
+       "bool vexpand" : true,
        "bool visible" : false,
-       "id" : "navigationwindow",
+       "id" : "navigation_holder",
+       "int spacing" : 0,
+       "int width_request" : 120,
        "items" : [
         {
          "$ xns" : "Gtk",
-         "* prop" : "child",
-         "id" : "navigation",
+         "Gtk.Orientation orientation" : "Gtk.Orientation.HORIZONTAL",
+         "int spacing" : 0,
+         "xtype" : "Box"
+        },
+        {
+         "$ xns" : "Gtk",
+         "bool hexpand" : true,
+         "bool vexpand" : true,
+         "bool visible" : true,
+         "id" : "navigationwindow",
          "items" : [
           {
+           "# int last_selected_line" : "-1",
+           "$ Gtk.Widget? selected_row" : "null",
            "$ xns" : "Gtk",
-           "bool expand" : true,
+           "* prop" : "child",
+           "id" : "navigation",
            "items" : [
             {
              "$ xns" : "Gtk",
-             "* prop" : "factory",
-             "listeners" : {
-              "bind" : [
-               "(listitem) => {",
-               "\t// GLib.debug(\"listitme is is %s\", ((Gtk.ListItem)listitem).get_type().name());",
-               "\t",
-               "\t//var expand = (Gtk.TreeExpander) ((Gtk.ListItem)listitem).get_child();",
-               "\tvar expand = (Gtk.TreeExpander)  ((Gtk.ListItem)listitem).get_child();",
-               "\t ",
-               "\t ",
-               "\tvar hbox = (Gtk.Box) expand.child;",
-               " ",
-               "\t",
-               "\tvar img = (Gtk.Image) hbox.get_first_child();",
-               "\tvar lbl = (Gtk.Label) img.get_next_sibling();",
-               "\t",
-               "\tvar lr = (Gtk.TreeListRow)((Gtk.ListItem)listitem).get_item();",
-               "\tvar sym = (Lsp.DocumentSymbol) lr.get_item();",
-               "\t",
-               "\tGLib.debug(\"got %d children for %s\" , (int)sym.children.get_n_items(), sym.name);",
-               "    ",
-               "    expand.set_hide_expander( sym.children.get_n_items()  < 1);",
-               " \texpand.set_list_row(lr);",
-               " \t",
-               " \tsym.bind_property(\"symbol_icon\",",
-               "                    img, \"icon_name\",",
-               "                   GLib.BindingFlags.SYNC_CREATE);",
-               " \t",
-               " \thbox.add_css_class(sym.symbol_icon);",
-               " \t",
-               " \tsym.bind_property(\"name\",",
-               "                    lbl, \"label\",",
-               "                   GLib.BindingFlags.SYNC_CREATE);",
-               " \t// should be better?- --line no?",
-               " \tsym.bind_property(\"tooltip\",",
-               "                    lbl, \"tooltip_markup\",",
-               "                   GLib.BindingFlags.SYNC_CREATE);",
-               " \t// bind image...",
-               " \t",
-               "}",
-               ""
-              ],
-              "setup" : [
-               "(listitem) => {",
-               "\t",
-               "\tvar expand = new Gtk.TreeExpander();",
-               "\t ",
-               "\texpand.set_indent_for_depth(true);",
-               "\texpand.set_indent_for_icon(true);",
-               "\tvar hbox = new Gtk.Box(Gtk.Orientation.HORIZONTAL,0);",
-               "\tvar icon = new Gtk.Image();",
-               "\tvar lbl = new Gtk.Label(\"\");",
-               "\tlbl.use_markup = true;",
-               "\tlbl.ellipsize = Pango.EllipsizeMode.END;",
-               "\t",
-               "\ticon.margin_end = 4;",
-               " \tlbl.justify = Gtk.Justification.LEFT;",
-               " \tlbl.xalign = 0;",
-               "",
-               "//\tlistitem.activatable = true; ??",
-               "\t",
-               "\thbox.append(icon);",
-               "\thbox.append(lbl);",
-               "\texpand.set_child(hbox);",
-               "\t((Gtk.ListItem)listitem).set_child(expand);",
-               "\t",
-               "}",
-               ""
-              ]
-             },
-             "xtype" : "SignalListItemFactory"
-            }
-           ],
-           "string title" : "Code Navigation",
-           "xtype" : "ColumnViewColumn"
-          },
-          {
-           "$ xns" : "Gtk",
-           "* prop" : "model",
-           "id" : "navigationselmodel",
-           "items" : [
+             "bool expand" : true,
+             "items" : [
+              {
+               "$ xns" : "Gtk",
+               "* prop" : "factory",
+               "listeners" : {
+                "bind" : [
+                 "(listitem) => {",
+                 "\t ",
+                 "\t// GLib.debug(\"listitme is is %s\", ((Gtk.ListItem)listitem).get_type().name());",
+                 "\t",
+                 "\t//var expand = (Gtk.TreeExpander) ((Gtk.ListItem)listitem).get_child();",
+                 "\tvar expand = (Gtk.TreeExpander)  ((Gtk.ListItem)listitem).get_child();",
+                 "\t ",
+                 "\t ",
+                 "\tvar hbox = (Gtk.Box) expand.child;",
+                 " ",
+                 "\t",
+                 "\tvar img = (Gtk.Image) hbox.get_first_child();",
+                 "\tvar lbl = (Gtk.Label) img.get_next_sibling();",
+                 "\t",
+                 "\tvar lr = (Gtk.TreeListRow)((Gtk.ListItem)listitem).get_item();",
+                 "\tvar sym = (Lsp.DocumentSymbol) lr.get_item();",
+                 "\t",
+                 "\tsym.set_data<Gtk.Widget>(\"widget\", expand.get_parent());",
+                 "\texpand.get_parent().get_parent().set_data<Lsp.DocumentSymbol>(\"symbol\", sym);",
+                 "\t",
+                 "\t//GLib.debug(\"save sym on %s\", expand.get_parent().get_parent().get_type().name());",
+                 "\t",
+                 "\t//GLib.debug(\"got %d children for %s\" , (int)sym.children.get_n_items(), sym.name);",
+                 "    ",
+                 "    expand.set_hide_expander( sym.children.get_n_items()  < 1);",
+                 " \texpand.set_list_row(lr);",
+                 " \t//this.in_bind = true;",
+                 " \t// default is to expand",
+                 " ",
+                 " \t//this.in_bind = false;",
+                 " \t",
+                 " \tsym.bind_property(\"symbol_icon\",",
+                 "                    img, \"icon_name\",",
+                 "                   GLib.BindingFlags.SYNC_CREATE);",
+                 " \t",
+                 " \thbox.css_classes = { sym.symbol_icon };",
+                 " \t",
+                 " \tsym.bind_property(\"name\",",
+                 "                    lbl, \"label\",",
+                 "                   GLib.BindingFlags.SYNC_CREATE);",
+                 " \t// should be better?- --line no?",
+                 " \tsym.bind_property(\"tooltip\",",
+                 "                    lbl, \"tooltip_markup\",",
+                 "                   GLib.BindingFlags.SYNC_CREATE);",
+                 " \t// bind image...",
+                 " \t",
+                 "}",
+                 ""
+                ],
+                "setup" : [
+                 "(listitem) => {",
+                 "\t",
+                 "\tvar expand = new Gtk.TreeExpander();",
+                 "\t ",
+                 "\texpand.set_indent_for_depth(true);",
+                 "\texpand.set_indent_for_icon(true);",
+                 "\tvar hbox = new Gtk.Box(Gtk.Orientation.HORIZONTAL,0);",
+                 "\tvar icon = new Gtk.Image();",
+                 "\tvar lbl = new Gtk.Label(\"\");",
+                 "\tlbl.use_markup = true;",
+                 "\tlbl.ellipsize = Pango.EllipsizeMode.END;",
+                 "\t",
+                 "\ticon.margin_end = 4;",
+                 " \tlbl.justify = Gtk.Justification.LEFT;",
+                 " \tlbl.xalign = 0;",
+                 "",
+                 "//\tlistitem.activatable = true; ??",
+                 "\t",
+                 "\thbox.append(icon);",
+                 "\thbox.append(lbl);",
+                 "\texpand.set_child(hbox);",
+                 "\t((Gtk.ListItem)listitem).set_child(expand);",
+                 "\t",
+                 "}",
+                 ""
+                ]
+               },
+               "xtype" : "SignalListItemFactory"
+              }
+             ],
+             "string title" : "Code Navigation",
+             "xtype" : "ColumnViewColumn"
+            },
             {
              "$ xns" : "Gtk",
              "* prop" : "model",
+             "id" : "navigationselmodel",
              "items" : [
               {
-               "$ Gtk.TreeListModelCreateModelFunc create_func" : [
-                "(item) => {",
-                " ",
-                "\treturn ((Lsp.DocumentSymbol)item).children;",
-                "}",
-                ""
-               ],
                "$ xns" : "Gtk",
                "* prop" : "model",
-               "bool autoexpand" : true,
-               "bool passthrough" : false,
+               "id" : "navigationsort",
                "items" : [
                 {
-                 "$ GLib.Type item_type" : "typeof(Lsp.DocumentSymbol)",
-                 "$ xns" : "GLib",
-                 "* prop" : "root",
-                 "id" : "navliststore",
-                 "xtype" : "ListStore"
-                }
-               ],
-               "xtype" : "TreeListModel"
-              },
-              {
-               "$ xns" : "Gtk",
-               "* prop" : "sorter",
-               "items" : [
+                 "$ Gtk.TreeListModelCreateModelFunc create_func" : [
+                  "(item) => {",
+                  " ",
+                  "\treturn ((Lsp.DocumentSymbol)item).children;",
+                  "}",
+                  ""
+                 ],
+                 "$ xns" : "Gtk",
+                 "* prop" : "model",
+                 "bool autoexpand" : true,
+                 "bool passthrough" : false,
+                 "items" : [
+                  {
+                   "$ GLib.Type item_type" : "typeof(Lsp.DocumentSymbol)",
+                   "$ xns" : "GLib",
+                   "* prop" : "root",
+                   "id" : "navliststore",
+                   "xtype" : "ListStore",
+                   "| Lsp.DocumentSymbol? symbolAtLine" : [
+                    "(uint line, uint chr) {",
+                    " ",
+                    "\t",
+                    "\tfor(var i = 0; i < this.el.get_n_items();i++) {",
+                    "\t\tvar el = (Lsp.DocumentSymbol)this.el.get_item(i);",
+                    "\t\t//GLib.debug(\"Check sym %s : %d-%d\",",
+                    "\t\t//\tel.name , (int)el.range.start.line,",
+                    "\t\t//\t(int)el.range.end.line",
+                    "\t\t//);",
+                    "\t\tvar ret = el.containsLine(line,chr);",
+                    "\t\tif (ret != null) {",
+                    "\t\t\treturn ret;",
+                    "\t\t}",
+                    "\t\t",
+                    "\t}",
+                    "\t",
+                    "\treturn null;",
+                    "}"
+                   ]
+                  }
+                 ],
+                 "listeners" : {
+                  "items_changed" : [
+                   "(position, removed, added) => {",
+                   "\tGLib.debug(\"tree item changed %d , %d , %d\",(int) position, (int)removed, (int) added);",
+                   "\t if (added < 1) { ",
+                   "\t \treturn;",
+                   " \t}",
+                   "\t//var sym = (Lsp.DocumentSymbol) this.el.get_item(position);",
+                   "\tvar row = this.el.get_row(position);",
+                   "\t",
+                   "\tGLib.debug(\"got %s\", row.get_item().get_type().name());",
+                   "\t",
+                   "",
+                   "}",
+                   ""
+                  ]
+                 },
+                 "xtype" : "TreeListModel"
+                },
                 {
                  "$ xns" : "Gtk",
                  "* prop" : "sorter",
                  "items" : [
                   {
-                   "$ GLib.Type this_type" : "typeof(Lsp.DocumentSymbol)",
                    "$ xns" : "Gtk",
-                   "* prop" : "expression",
-                   "string property_name" : "sort_key",
-                   "xtype" : "PropertyExpression"
+                   "* prop" : "sorter",
+                   "items" : [
+                    {
+                     "$ GLib.Type this_type" : "typeof(Lsp.DocumentSymbol)",
+                     "$ xns" : "Gtk",
+                     "* prop" : "expression",
+                     "string property_name" : "sort_key",
+                     "xtype" : "PropertyExpression"
+                    }
+                   ],
+                   "xtype" : "StringSorter"
                   }
                  ],
-                 "xtype" : "StringSorter"
+                 "xtype" : "TreeListRowSorter"
                 }
                ],
-               "xtype" : "TreeListRowSorter"
+               "xtype" : "SortListModel",
+               "| Lsp.DocumentSymbol? getSymbolAt" : [
+                "(uint row) {",
+                "",
+                "   var tr = (Gtk.TreeListRow)this.el.get_item(row);",
+                "   ",
+                "   var a = tr.get_item();;   ",
+                "   GLib.debug(\"get_item (2) = %s\", a.get_type().name());",
+                "  \t",
+                "   ",
+                "   return (Lsp.DocumentSymbol)tr.get_item();",
+                "\t ",
+                "}"
+               ],
+               "| int getRowFromSymbol" : [
+                "(Lsp.DocumentSymbol sym) {",
+                "",
+                "\tfor (var i=0;i < this.el.get_n_items(); i++) {",
+                "\t\tvar tr = (Gtk.TreeListRow)this.el.get_item(i);",
+                "\t   ",
+                "\t\tif (sym.equals( (Lsp.DocumentSymbol)tr.get_item())) {",
+                "\t\t\treturn i;",
+                "\t\t}",
+                "\t}",
+                "   \treturn -1;",
+                "}"
+               ],
+               "| void collapseOnLoad" : [
+                "() {",
+                "\tfor (var i=0;i < this.el.get_n_items(); i++) {",
+                "\t\tvar tr = (Gtk.TreeListRow)this.el.get_item(i);",
+                "\t\tvar sym =  (Lsp.DocumentSymbol)tr.get_item();",
+                "\t\tswitch (sym.kind) {",
+                "\t \t\tcase Lsp.SymbolKind.Enum: ",
+                "\t \t\t\ttr.expanded = false;",
+                "\t \t\t\tbreak;",
+                "\t\t\tdefault:",
+                "\t\t\t\t//tr.expanded = true;",
+                "\t\t\t\tbreak;",
+                "\t\t}",
+                "\t}",
+                " ",
+                "\t",
+                "",
+                "",
+                "}"
+               ]
               }
              ],
-             "xtype" : "SortListModel"
+             "xtype" : "NoSelection"
+            },
+            {
+             "$ xns" : "Gtk",
+             "listeners" : {
+              "pressed" : [
+               "(n_press, x, y) => {",
+               "\tstring pos;",
+               "  \tvar row = _this.navigation.getRowWidgetAt(x,y, out pos );",
+               "",
+               "    if (row == null) {",
+               "\t    GLib.debug(\"no row selected items\");",
+               "\t    return;",
+               "    }",
+               "\tGLib.debug(\"got click on %s\", row.get_type().name());    ",
+               "    //Lsp.DocumentSymbol",
+               "    var sym =  row.get_data<Lsp.DocumentSymbol>(\"symbol\");",
+               "    if (sym == null) {",
+               "    \treturn;",
+               "\t}",
+               "\t/*",
+               "\t \"range\" : {",
+               "              \"start\" : {",
+               "                \"line\" : 1410,",
+               "                \"character\" : 8",
+               "              },",
+               "              \"end\" : {",
+               "                \"line\" : 1410,",
+               "                \"character\" : 39",
+               "              }",
+               "            },",
+               "        */",
+               "     GLib.debug(\"goto line %d\",   (int)sym.range.start.line); ",
+               "    _this.scroll_to_line((int)sym.range.start.line);",
+               "    Gtk.TextIter iter;",
+               "    _this.buffer.el.get_iter_at_line_offset(out iter, ",
+               "    \t(int)sym.range.start.line,",
+               "    \t(int)sym.range.start.character",
+               "\t);",
+               "    _this.buffer.el.place_cursor(iter);",
+               "\t",
+               "}"
+              ]
+             },
+             "xtype" : "GestureClick"
             }
            ],
-           "xtype" : "NoSelection",
-           "| Lsp.DocumentSymbol? getSymoblAt" : [
-            "(uint row) {",
+           "string name" : "editor-navigation",
+           "xtype" : "ColumnView",
+           "| Gtk.Widget? getRowWidgetAt" : [
+            "(double x,  double  y, out string pos) {",
             "",
-            "   var tr = (Gtk.TreeListRow)this.el.get_item(row);",
-            "   ",
-            "   var a = tr.get_item();;   ",
-            "   GLib.debug(\"get_item (2) = %s\", a.get_type().name());",
-            "  \t",
-            "   ",
-            "   return (Lsp.DocumentSymbol)tr.get_item();",
+            "\tpos = \"\";",
+            "\tvar w = this.el.pick(x, y, Gtk.PickFlags.DEFAULT);",
+            "\t//GLib.debug(\"got widget %s\", w == null ? \"nothing\" : w.get_type().name());",
+            "\tif (w == null) {",
+            "\t\treturn null;",
+            "\t}",
+            "\t",
+            "\tvar row= w.get_ancestor(GLib.Type.from_name(\"GtkColumnViewRowWidget\"));",
+            "\tif (row == null) {",
+            "\t\treturn null;",
+            "\t}",
+            "\t",
+            "\t//GLib.debug(\"got colview %s\", row == null ? \"nothing\" : row.get_type().name());",
+            "\t ",
+            " ",
+            "\t",
+            "\t//GLib.debug(\"row number is %d\", rn);",
+            "\t//GLib.debug(\"click %d, %d\", (int)x, (int)y);",
+            "\t// above or belw",
+            "\tGraphene.Rect  bounds;",
+            "\trow.compute_bounds(this.el, out bounds);",
+            "\t//GLib.debug(\"click x=%d, y=%d, w=%d, h=%d\", ",
+            "\t//\t(int)bounds.get_x(), (int)bounds.get_y(),",
+            "\t//\t(int)bounds.get_width(), (int)bounds.get_height()",
+            "\t//\t);",
+            "\tvar ypos = y - bounds.get_y();",
+            "\t//GLib.debug(\"rel ypos = %d\", (int)ypos);\t",
+            "\tvar rpos = 100.0 * (ypos / bounds.get_height());",
+            "\t//GLib.debug(\"rel pos = %d %%\", (int)rpos);",
+            "\tpos = \"over\";",
+            "\t",
+            "\tif (rpos > 80) {",
+            "\t\tpos = \"below\";",
+            "\t} else if (rpos < 20) {",
+            "\t\tpos = \"above\";",
+            "\t} ",
+            "\treturn row;",
+            " }"
+           ],
+           "| int getRowAt" : [
+            "(double x,  double  y, out string pos) {",
+            "",
+            "\tpos = \"\";",
+            "\tvar w = this.el.pick(x, y, Gtk.PickFlags.DEFAULT);",
+            "\t//GLib.debug(\"got widget %s\", w == null ? \"nothing\" : w.get_type().name());",
+            "\tif (w == null) {",
+            "\t\treturn -1;",
+            "\t}",
+            "\t",
+            "\tvar row= w.get_ancestor(GLib.Type.from_name(\"GtkColumnViewRowWidget\"));",
+            "\tif (row == null) {",
+            "\t\treturn -1;",
+            "\t}",
+            "\t",
+            "\t//GLib.debug(\"got colview %s\", row == null ? \"nothing\" : row.get_type().name());",
+            "\t ",
+            "\tvar rn = 0;",
+            "\tvar cr = row;",
             "\t ",
+            "\twhile (cr.get_prev_sibling() != null) {",
+            "\t\trn++;",
+            "\t\tcr = cr.get_prev_sibling();",
+            "\t}",
+            "\t",
+            "\t//GLib.debug(\"row number is %d\", rn);",
+            "\t//GLib.debug(\"click %d, %d\", (int)x, (int)y);",
+            "\t// above or belw",
+            "\tGraphene.Rect  bounds;",
+            "\trow.compute_bounds(this.el, out bounds);",
+            "\t//GLib.debug(\"click x=%d, y=%d, w=%d, h=%d\", ",
+            "\t//\t(int)bounds.get_x(), (int)bounds.get_y(),",
+            "\t//\t(int)bounds.get_width(), (int)bounds.get_height()",
+            "\t//\t);",
+            "\tvar ypos = y - bounds.get_y();",
+            "\t//GLib.debug(\"rel ypos = %d\", (int)ypos);\t",
+            "\tvar rpos = 100.0 * (ypos / bounds.get_height());",
+            "\t//GLib.debug(\"rel pos = %d %%\", (int)rpos);",
+            "\tpos = \"over\";",
+            "\t",
+            "\tif (rpos > 80) {",
+            "\t\tpos = \"below\";",
+            "\t} else if (rpos < 20) {",
+            "\t\tpos = \"above\";",
+            "\t} ",
+            "\treturn rn;",
+            " }"
+           ],
+           "| void show" : [
+            "(Gee.ArrayList<Lsp.DocumentSymbol> syms) {",
+            "\t",
+            "\tif (!_this.navigation_holder.el.visible && syms.size > 0) {",
+            "\t\t_this.navigation_holder.el.show();",
+            "\t\t_this.paned.el.position  = ",
+            "\t\t\t_this.paned.el.get_width() - 200;",
+            "\t} ",
+            "\t//_this.navliststore.el.remove_all();",
+            "\t",
+            "\t",
+            "\tvar ls  = new GLib.ListStore(typeof(Lsp.DocumentSymbol));",
+            "\t",
+            "\tforeach(var sym in syms) {",
+            "\t\tls.append(sym);",
+            "\t}",
+            "\t// if syms updated is empty, but we already have one..",
+            "\tif (_this.navliststore.el.get_n_items() > 0 && ls.get_n_items() < 1) {",
+            "\t\treturn;",
+            "\t}",
+            "\tLsp.DocumentSymbol.copyList(ls, _this.navliststore.el);",
+            "\t//_this.navliststore.el.append(sym);",
+            "\tthis.last_selected_line = -1;",
+            "\tGLib.Idle.add(() => {",
+            "\t\t_this.navigationsort.collapseOnLoad();",
+            "\t\tGtk.TextIter iter;",
+            "\t\t_this.buffer.el.get_iter_at_offset (",
+            "\t\t\t\tout iter, _this.buffer.el.cursor_position);",
+            "\t\t",
+            "\t\tGLib.debug(\"idle update scroll %d, %d\", iter.get_line(),",
+            "\t\t\t\titer.get_line_offset());",
+            "\t\tthis.updateSelectedLine(",
+            "\t\t\t\t(uint)iter.get_line(),",
+            "\t\t\t\t(uint)iter.get_line_offset()",
+            "\t\t);",
+            "\t\treturn false;",
+            "\t});",
+            "",
+            "}"
+           ],
+           "| void updateSelectedLine" : [
+            "(uint line, uint chr) {",
+            "\tif (line == this.last_selected_line) {",
+            "\t\treturn;",
+            "\t}",
+            "\tGLib.debug(\"select line %d\", (int)line);",
+            "\tthis.last_selected_line = (int)line;",
+            "\t",
+            "\t",
+            "\tvar new_row = -1;",
+            "\tvar sym = _this.navliststore.symbolAtLine(line, chr);",
+            "\tif (sym != null) {",
+            "\t \tnew_row = _this.navigationsort.getRowFromSymbol(sym);",
+            " \t\tGLib.debug(\"select line %d - row found %d\", (int)line, new_row);",
+            " \t} else {",
+            " \t\tGLib.debug(\" no symbol found at line %d\", (int)line);",
+            " \t}",
+            " \t",
+            "\tif (this.selected_row != null) { ",
+            "\t\tGLib.debug(\" remove selected row\");",
+            "\t\tthis.selected_row.remove_css_class(\"selected-row\");",
+            "\t}",
+            "\tthis.selected_row  = null;",
+            "\tif (new_row > -1) {",
+            "\t\tthis.el.scroll_to(new_row,null,Gtk.ListScrollFlags.NONE, null);",
+            "\t\tvar row = sym.get_data<Gtk.Widget>(\"widget\");",
+            "\t\tif (row != null) {",
+            "\t\t\tGLib.debug(\" Add selected row\");",
+            " \t\t\t",
+            "\t\t\trow.add_css_class(\"selected-row\");",
+            "\t\t\tthis.selected_row = row;",
+            "",
+            "\t\t\t",
+            "\t\t} else {",
+            "\t\t\tGLib.debug(\"could not find widget on row %d\", new_row);",
+            "\t\t}",
+            "",
+            "\t}",
+            "",
+            "",
             "}"
            ]
-          },
-          {
-           "$ xns" : "Gtk",
-           "listeners" : {
-            "pressed" : [
-             "(n_press, x, y) => {",
-             "\tstring pos;",
-             "  \tvar row = _this.navigation.getRowAt(x,y, out pos );",
-             "    if (row < 0) {",
-             "\t    GLib.debug(\"no row selected items\");",
-             "\t    return;",
-             "    }",
-             "    //Lsp.DocumentSymbol",
-             "    var sym =   _this.navigationselmodel.getSymoblAt(row);",
-             "    if (sym == null) {",
-             "    \treturn;",
-             "\t}",
-             "\t/*",
-             "\t \"range\" : {",
-             "              \"start\" : {",
-             "                \"line\" : 1410,",
-             "                \"character\" : 8",
-             "              },",
-             "              \"end\" : {",
-             "                \"line\" : 1410,",
-             "                \"character\" : 39",
-             "              }",
-             "            },",
-             "            */",
-             "    _this.scroll_to_line((int)sym.range.start.line);",
-             "\t",
-             "}"
-            ]
-           },
-           "xtype" : "GestureClick"
           }
          ],
-         "string name" : "editor-navigation",
-         "xtype" : "ColumnView",
-         "| int getRowAt" : [
-          "(double x,  double  y, out string pos) {",
-          "",
-          "\tpos = \"\";",
-          "\tvar w = this.el.pick(x, y, Gtk.PickFlags.DEFAULT);",
-          "\t//GLib.debug(\"got widget %s\", w == null ? \"nothing\" : w.get_type().name());",
-          "\tif (w == null) {",
-          "\t\treturn -1;",
-          "\t}",
-          "\t",
-          "\tvar row= w.get_ancestor(GLib.Type.from_name(\"GtkColumnViewRowWidget\"));",
-          "\tif (row == null) {",
-          "\t\treturn -1;",
-          "\t}",
-          "\t",
-          "\t//GLib.debug(\"got colview %s\", row == null ? \"nothing\" : row.get_type().name());",
-          "\t ",
-          "\tvar rn = 0;",
-          "\tvar cr = row;",
-          "\t ",
-          "\twhile (cr.get_prev_sibling() != null) {",
-          "\t\trn++;",
-          "\t\tcr = cr.get_prev_sibling();",
-          "\t}",
-          "\t",
-          "\t//GLib.debug(\"row number is %d\", rn);",
-          "\t//GLib.debug(\"click %d, %d\", (int)x, (int)y);",
-          "\t// above or belw",
-          "\tGraphene.Rect  bounds;",
-          "\trow.compute_bounds(this.el, out bounds);",
-          "\t//GLib.debug(\"click x=%d, y=%d, w=%d, h=%d\", ",
-          "\t//\t(int)bounds.get_x(), (int)bounds.get_y(),",
-          "\t//\t(int)bounds.get_width(), (int)bounds.get_height()",
-          "\t//\t);",
-          "\tvar ypos = y - bounds.get_y();",
-          "\t//GLib.debug(\"rel ypos = %d\", (int)ypos);\t",
-          "\tvar rpos = 100.0 * (ypos / bounds.get_height());",
-          "\t//GLib.debug(\"rel pos = %d %%\", (int)rpos);",
-          "\tpos = \"over\";",
-          "\t",
-          "\tif (rpos > 80) {",
-          "\t\tpos = \"below\";",
-          "\t} else if (rpos < 20) {",
-          "\t\tpos = \"above\";",
-          "\t} ",
-          "\treturn rn;",
-          " }"
-         ],
-         "| void show" : [
-          "(Gee.ArrayList<Lsp.DocumentSymbol> syms) {",
-          "\t_this.navigationwindow.el.show();",
-          "\t_this.navliststore.el.remove_all();",
-          "\tforeach(var sym in syms) {",
-          "\t\t_this.navliststore.el.append(sym);",
-          "\t}",
-          "\t",
-          "",
-          "}"
-         ]
+         "xtype" : "ScrolledWindow"
         }
        ],
-       "xtype" : "ScrolledWindow"
+       "xtype" : "Box"
       }
      ],
      "xtype" : "Paned"
     "(JsRender.JsRender file, JsRender.Node? node, JsRender.NodeProp? prop)",
     "{",
     "    this.reset();",
+    "    if (this.file != null) {",
+    "    \tthis.file.navigation_tree_updated.disconnect(",
+    "    \t\t_this.navigation.show",
+    "    \t);",
+    "    }",
     "    this.file = file;    ",
-    "    ",
+    "    this.file.navigation_tree_updated.connect(",
+    "\t\t_this.navigation.show",
+    "\t);",
     "    if (file.xtype != \"PlainFile\") {",
     "    \tthis.prop = prop;",
     "        this.node = node;",
     "    ",
     "    } else {",
     "        this.view.load(        file.toSource() );",
-    "         this.updateErrorMarks();",
+    "        this.updateErrorMarks();",
     "        this.close_btn.el.hide();",
     "        var ls = file.getLanguageServer();",
-    "        ls.documentSymbols.begin(file, (a,o) => {",
-    "        \t_this.navigation.show(ls.documentSymbols.end(o)); ",
-    "        });",
+    "        ls.queueDocumentSymbols(file);",
+    "        ////ls.documentSymbols.begin(file, (a,o) => {",
+    "        //\t_this.navigation.show(ls.documentSymbols.end(o)); ",
+    "       //});",
     "        //documentSymbols",
     "        ",
     "    }",