fix #7968 - language server support for syntax check and completion
authorAlan Knowles <alan@roojs.com>
Sat, 13 Jan 2024 15:00:30 +0000 (23:00 +0800)
committerAlan Knowles <alan@roojs.com>
Sat, 13 Jan 2024 15:00:30 +0000 (23:00 +0800)
41 files changed:
.roobuilder.jcfg
configure.ac
meson.build
src/Application.vala
src/Builder4/DialogFiles.bjs
src/Builder4/DialogFiles.vala
src/Builder4/Editor.bjs
src/Builder4/Editor.vala
src/Builder4/FakeServer.vala
src/Builder4/GtkView.bjs
src/Builder4/GtkView.vala
src/Builder4/MainWindow.bjs
src/Builder4/MainWindow.vala
src/Builder4/ValaCompileErrors.bjs
src/Builder4/ValaCompileErrors.vala
src/Builder4/WindowLeftTree.bjs
src/Builder4/WindowLeftTree.vala
src/Builder4/WindowRooView.bjs
src/Builder4/WindowRooView.vala
src/Builder4/WindowState.vala
src/JsRender/Dir.vala
src/JsRender/Gtk.vala
src/JsRender/JsRender.vala
src/JsRender/PlainFile.vala
src/JsRender/Roo.vala
src/Lsp.vala [new file with mode: 0644]
src/Main.vala
src/Makefile.am
src/Palete/CompileError.vala
src/Palete/CompletionProvider.vala
src/Palete/Gtk.vala
src/Palete/Javascript.vala
src/Palete/LanguageClient.vala [new file with mode: 0644]
src/Palete/LanguageClientDummy.vala [new file with mode: 0644]
src/Palete/LanguageClientVala.vala [new file with mode: 0644]
src/Palete/Roo.vala
src/Palete/ValaCompileQueue.vala
src/Palete/ValaCompileRequest.vala
src/Project/Gtk.vala
src/Project/Project.vala
src/Project/Roo.vala

index 486260c..38a066e 100644 (file)
                 "src/Spawn.vala",
                 "src/Application.vala",
                 "src/Palete/ValalCompileQueue.vala",
-                "src/Palete/ValaCompileRequest.vala",
-                "src/Palete/ValaCompileQueue.vala",
                 "src/Palete/Javascript.vala",
                 "src/Project/Meson.vala",
-                "src/Palete/RooDatabase.vala"
+                "src/Palete/RooDatabase.vala",
+                "src/Palete/LanguageClient.vala",
+                "src/Palete/LanguageClientVala.vala",
+                "src/Lsp.vala",
+                "src/Palete/LanguageClientDummy.vala",
+                "src/Palete/ValaCompileRequest.vala"
             ]
         }
     ],
         "json-glib-1.0",
         "gobject-introspection-1.0",
         "libvala-0.56",
-        "libadwaita-1",
         "libxml-2.0",
         "posix",
         "roojspacker-1.4",
         "gtksourceview-5",
-        "libgda-5.0"
+        "libgda-5.0",
+        "jsonrpc-glib-1.0",
+        "gio-unix-2.0"
     ]
 }
\ No newline at end of file
index 23f639a..e2a0536 100644 (file)
@@ -33,6 +33,8 @@ PKG_CHECK_MODULES(ROOBUILDER, [ zlib
                 libxml-2.0
                 libsoup-3.0 
                 roojspacker-1.4
+                jsonrpc-glib-1.0
+                gio-unix-2.0
 ]) 
 
 dnl --- libvala -- needs to find matching really..
index c6db965..9e98877 100644 (file)
@@ -24,12 +24,13 @@ deps = [
    dependency('json-glib-1.0'),
    dependency('gobject-introspection-1.0'),
    dependency('libvala-0.56'),
-   dependency('libadwaita-1'),
    dependency('libxml-2.0'),
    valac.find_library('posix'),
    dependency('roojspacker-1.4'),
    dependency('gtksourceview-5'),
    dependency('libgda-5.0'),
+   dependency('jsonrpc-glib-1.0'),
+   dependency('gio-unix-2.0'),
 
 ]
  
@@ -188,11 +189,14 @@ roobuilder_src = files([
    'src/Resources.vala',
    'src/Spawn.vala',
    'src/Application.vala',
-   'src/Palete/ValaCompileRequest.vala',
-   'src/Palete/ValaCompileQueue.vala',
    'src/Palete/Javascript.vala',
    'src/Project/Meson.vala',
    'src/Palete/RooDatabase.vala',
+   'src/Palete/LanguageClient.vala',
+   'src/Palete/LanguageClientVala.vala',
+   'src/Lsp.vala',
+   'src/Palete/LanguageClientDummy.vala',
+   'src/Palete/ValaCompileRequest.vala',
 ])
 
 roobuilder = executable('roobuilder',
index b2d347c..41f1c0a 100644 (file)
@@ -66,7 +66,7 @@
                        { "skip-file", 0, 0, OptionArg.STRING, ref opt_compile_skip ,"For test compiles do not add this (usually used in conjunction with add-file ", null },
                        { "add-file", 0, 0, OptionArg.STRING, ref opt_compile_add, "Add this file to compile list", null },
                        { "output", 0, 0, OptionArg.STRING, ref opt_compile_output, "output binary file path", null },
-                       { "debug", 0, 0, OptionArg.NONE, ref opt_debug, "Show debug messages", null },
+                       { "debug", 0, 0, OptionArg.NONE, ref opt_debug, "Show debug messages for non-ui, or crash on warnings for gdb ", null },
                        { "pull-resources", 0, 0, OptionArg.NONE, ref opt_pull_resources, "Fetch the online resources", null },                 
             
             // some testing code.
@@ -77,7 +77,7 @@
             { "bjs-test-all", 0, 0, OptionArg.NONE, ref opt_bjs_test, "Test all the BJS files to see if the new parser/writer would change anything", null },            
             { "bjs-target", 0, 0, OptionArg.STRING, ref opt_bjs_compile_target, "convert bjs file to tareet  : vala / js", null },
             { "test", 0, 0, OptionArg.STRING, ref opt_test, "run a test use 'help' to list the available tests", null },
-            
+            { "language-server", 0, 0, OptionArg.STRING, ref opt_language_server, "run language server on this file", null },
             { "drop-list", 0, 0, OptionArg.STRING, ref opt_drop_list, "show droplist / children for a Gtk type (eg. Gtk.Widget)", null },
             
             
                public static string opt_compile_skip;
                public static string opt_compile_add;
                public static string opt_compile_output;
-        public static string opt_bjs_compile;
-        public static string opt_bjs_compile_target;
-        public static string opt_test;  
-        public static string opt_drop_list;
-        
+               public static string opt_bjs_compile;
+               public static string opt_bjs_compile_target;
+               public static string opt_test;  
+               public static string opt_drop_list;
+               public static string opt_language_server;
         
         public static bool opt_skip_linking = false;
                public static bool opt_debug = false;
 
 
 
-               public static Palete.ValaCompileQueue valacompilequeue;
+               //public static Palete.ValaCompileQueue valacompilequeue;
 
        
                public BuilderApplication (  string[] args)
                                flags: ApplicationFlags.FLAGS_NONE
                        );
                        BuilderApplication.windows = new        Gee.ArrayList<Xcls_MainWindow>();
-                       BuilderApplication.valacompilequeue = new Palete.ValaCompileQueue();
+                       //BuilderApplication.valacompilequeue = new Palete.ValaCompileQueue();
                        
                        
                        configDirectory();
                Project.Project.loadAll();
                        this.listProjects();
                        var cur_project = this.compileProject();
-                       this.dropList(cur_project);
+                       this.dropList(cur_project); // --drop-list
+                       this.languageServer(cur_project); // --language-server                  
                        this.listFiles(cur_project);
                        this.testBjs(cur_project);
+                       this.languageServer(cur_project);
                        this.compileBjs(cur_project);
                        this.compileVala();
 
                
                void initDebug() 
                {
-               
+                        
+                       
                        if (BuilderApplication.opt_debug  || BuilderApplication.opt_compile_project == null) {
-                               GLib.Log.set_handler(null, 
-                                       GLib.LogLevelFlags.LEVEL_DEBUG | GLib.LogLevelFlags.LEVEL_WARNING | GLib.LogLevelFlags.LEVEL_CRITICAL, 
+                               GLib.Log.set_default_handler( 
+                               //      GLib.LogLevelFlags.LEVEL_DEBUG | GLib.LogLevelFlags.LEVEL_WARNING | GLib.LogLevelFlags.LEVEL_CRITICAL, 
                                        (dom, lvl, msg) => {
-                                       print("%s: %s\n", (new DateTime.now_local()).format("%H:%M:%S.%f"), msg);
+
+                                       print("%s: %s : %s\n", (new DateTime.now_local()).format("%H:%M:%S.%f"), lvl.to_string(), msg);
+                                       
+                                       if (dom== "GtkSourceView") { // seems to be some critical wanrings comming from gtksourceview related to insert?
+                                               return;
+                                       }
+                                       //if (msg.contains("gdk_popup_present")) { // seems to be problems with the popup present on gtksourceview competion.
+                                       //      return;
+                                       //}
+                                       if (BuilderApplication.opt_debug && lvl ==  GLib.LogLevelFlags.LEVEL_CRITICAL) {
+                                               GLib.error(msg);
+                                       }
                                });
                        }
                        
                        
                        
                        
-                       var file = cur_project.getByName(BuilderApplication.opt_bjs_compile);
+                       var file = cur_project.getByRelPath(BuilderApplication.opt_bjs_compile);
                        if (file == null) {
                                // then compile them all, and compare them...
                                
                        
                        GLib.Process.exit(Posix.EXIT_SUCCESS);
                }
-               
+               void languageServer(Project.Project? cur_project)
+               {
+                       if (BuilderApplication.opt_language_server == null) {
+                               return;
+                       }
+                       if (cur_project == null) {
+                               GLib.error("missing project, use --project to select which project");
+                       }
+                       var file = cur_project.getByRelPath(BuilderApplication.opt_language_server);
+                       if (file == null) {
+                               // then compile them all, and compare them...
+                                GLib.error("missing file %s in project %s", BuilderApplication.opt_language_server, cur_project.name);
+                       }
+                       
+                       var ls = file.getLanguageServer();
+                       if (ls == null) {
+                               GLib.error("No langauge server returned for file:%s", file.relpath);
+                       }
+                       var loop = new MainLoop();
+                       GLib.Timeout.add_seconds(1, () => {
+                               if (!ls.isReady()) {
+                                       GLib.debug("waiting for server to be ready");
+                                       return true;
+                               }
+                               GLib.debug("Sending document_open");
+                               // it's ready..
+                                
+                               ls.document_open(file);
+                               return false;
+                               
+                       });
+                       
+                        
+                       loop.run();
+                       GLib.Process.exit(Posix.EXIT_SUCCESS);
+               }
+                       
+                       
                void compileVala()
                {
                        if (BuilderApplication.opt_compile_target == null) {
                                case "help":
                                        print("""
 help             - list available tests
-flutter-project  - create a flutter project in /tmp/test-flutter
+flutter-project  -  was try and read flutter data (but desnt work.)
 """);          
                                        break;
                                case "flutter-project":
@@ -523,6 +574,9 @@ flutter-project  - create a flutter project in /tmp/test-flutter
                                        */
                                        break;
                                        
+                                
+                                       
+                                       
                                default:
                                        print("Invalid test\n");
                                        break;
@@ -593,29 +647,27 @@ flutter-project  - create a flutter project in /tmp/test-flutter
                                if (ww == null || ww.windowstate == null || ww.windowstate.project ==null) {
                                        continue;
                                }
-                               if (ww.windowstate.project.last_request == null) {
-                                       ww.updateErrors(null);                                  
-                                       return;
-                               }
-                               var req = ww.windowstate.project.last_request;
-                               GLib.debug("checking errors editor for %s", ww.windowstate.file.targetName());
-                               
-                               if (req.errorByFile.has_key(ww.windowstate.file.targetName())) {
-                                       GLib.debug("calling update Error margs for  %s", ww.windowstate.file.targetName());             
-                                       ww.windowstate.code_editor_tab.updateErrorMarks(req.errorByFile.get(ww.windowstate.file.targetName()));
-                               } else {
-                                       ww.windowstate.code_editor_tab.updateErrorMarks(null);
+
+                               ww.windowstate.updateErrorMarksAll();
                                 
-                                       GLib.debug("no errors in errrobyfile for  %s", ww.windowstate.file.targetName());               
-                               }
-                               
                                GLib.debug("calling udate Errors of window %s", ww.windowstate.file.targetName());
-                               ww.updateErrors(req);
+                               ww.updateErrors();
                                
                                
                        }
                
                }
+               public static  void showSpinner(bool state)
+               {
+                       foreach (var win in BuilderApplication.windows) {
+                               if (state) {
+                                       win.statusbar_compile_spinner.start();
+                               }  else {
+                                       win.statusbar_compile_spinner.stop();
+                               }
+                       }
+               }
+               
                
                
         
index d53a5a2..647b185 100644 (file)
                  " ",
                  "\tvar lbl = (Gtk.Label)  ((Gtk.ListItem)listitem).get_child();",
                  "\t   ",
-                 "\tvar item = (JsRender.JsRender)  ((Gtk.ListItem)listitem).get_item();",
+                 "\tvar item = (Project.Project)  ((Gtk.ListItem)listitem).get_item();",
                  "",
                  "\titem.bind_property(\"name\",",
                  "                lbl, \"label\",",
index 36e4387..0d3723b 100644 (file)
                  
                        var lbl = (Gtk.Label)  ((Gtk.ListItem)listitem).get_child();
                           
-                       var item = (JsRender.JsRender)  ((Gtk.ListItem)listitem).get_item();
+                       var item = (Project.Project)  ((Gtk.ListItem)listitem).get_item();
                 
                        item.bind_property("name",
                                 lbl, "label",
index 492bdd8..038d0a7 100644 (file)
@@ -1,6 +1,5 @@
 {
  "build_module" : "builder",
- "gen_extended" : false,
  "items" : [
   {
    "# GtkSource.SearchContext searchcontext" : "null",
         "\t",
         " ",
         "\t ",
-        "",
-        "       ",
-        "this.el.completion.add_provider(new Palete.CompletionProvider(_this));",
+        "/*",
+        "this is pretty flakey - triggers Gtk with  < 0 d",
+        " var cp = new GtkSource.CompletionWords(\"test\"); ",
+        " cp.minimum_word_size  = 3;",
+        " //cp.priority = 100; //?? does this do anything",
+        " cp.proposals_batch_size  = 10;",
+        " cp.scan_batch_size = 1000;",
         " ",
-        "",
-        "this.el.completion.unblock_interactive();",
+        "cp.register(_this.buffer.el);",
+        "this.el.completion.add_provider(cp);",
+        "*/",
+        "this.el.completion.add_provider(new Palete.CompletionProvider(_this));",
+        "  ",
+        "//this.el.completion.unblock_interactive();",
         "this.el.completion.select_on_show = true; // select",
-        "",
-        "this.el.completion.remember_info_visibility\t = true;",
+        "//this.el.completion.remember_info_visibility\t = true;",
         "",
         "",
         "var attrs = new GtkSource.MarkAttributes();",
           "    }",
           "    ",
           "    // bit presumptiona",
-          "    if (_this.file.xtype == \"PlainFile\" && _this.file.project.xtype == \"Gtk\") {",
+          "    if (_this.file.xtype == \"PlainFile\") {",
           "    ",
           "        // assume it's gtk...",
-          "           ",
-          "\t\tBuilderApplication.valacompilequeue.addFile( ",
-          "\t\t\tPalete.ValaCompileRequestType.FILE_CHANGE, ",
-          "\t\t\t_this.file , str, false) ;",
-          "  ",
-          "",
+          "         var  oldcode =_this.file.toSource();",
+          "        _this.file.setSource(str);",
+          "        _this.file.getLanguageServer().document_change(_this.file);",
+          "        _this.file.setSource(oldcode);",
+          "        ",
+          "\t\t ",
           "        return true;",
           "    ",
           "    }",
           "     ",
           "    GLib.debug(\"calling validate\");    ",
           "    // clear the buttons.",
-          " ",
-          "    BuilderApplication.valacompilequeue.addProp( ",
-          "    \t\tPalete.ValaCompileRequestType.PROP_CHANGE,",
-          "\t\t\t_this.file,",
-          "\t\t\t_this.node,",
-          "\t\t\t_this.prop,",
-          "\t\t\tstr); ",
-          "     ",
+          " \tif (_this.prop.name == \"xns\" || _this.prop.name == \"xtype\") {",
+          "\t\treturn true ;",
+          "\t}",
+          "\tvar oldcode  = _this.prop.val;",
+          "\t",
+          "\t_this.prop.val = str;",
+          "    _this.file.getLanguageServer().document_change(_this.file);",
+          "    _this.prop.val = oldcode;",
           "    ",
           "    ",
           "    //print(\"done mark line\\n\");",
            "\t\t_this.search_entry.el.grab_focus();",
            "\t    return;",
            "\t}",
-           "    ",
+           "    //_this.view.el.show_completion();",
            "   // print(event.key.keyval)",
            "    ",
            "    return;",
     "}"
    ],
    "| void updateErrorMarks" : [
-    "(GLib.ListStore?  ar) {",
+    "(string category) {",
     "\t",
     " ",
-    "\t",
-    "\t var buf = _this.buffer.el;",
+    "",
+    "\tvar buf = _this.buffer.el;",
     "\tGtk.TextIter start;",
     "\tGtk.TextIter end;     ",
     "\tbuf.get_bounds (out start, out end);",
     "",
-    "\tbuf.remove_source_marks (start, end, \"ERR\");",
-    "\tbuf.remove_source_marks (start, end, \"WARN\");",
-    "\tbuf.remove_source_marks (start, end, \"DEPR\");",
+    "\tbuf.remove_source_marks (start, end, category);",
+    " ",
     "\tGLib.debug(\"highlight errors\");\t\t ",
     "",
     "\t // we should highlight other types of errors..",
     "",
-    "\tif (ar == null || ar.get_n_items() < 1) {",
-    "\t\tGLib.debug(\"Return has no errors\\n\");",
-    "\t\treturn;",
-    "\t}",
-    "",
     "\tif (_this.window.windowstate.state != WindowState.State.CODEONLY ",
     "\t\t&&",
     "\t\t_this.window.windowstate.state != WindowState.State.CODE",
     "\t\treturn;",
     "",
     "\t}",
+    "\tvar ar = this.file.getErrors(category);",
+    "\tif (ar == null || ar.get_n_items() < 1) {",
+    "\t\tGLib.debug(\"highlight %s :  %s has no errors\", this.file.relpath, category);",
+    "\t\treturn;",
+    "\t}",
     " ",
     "",
     " ",
     "\t",
-    "\tvar offset = 1;",
+    "\tvar offset = 0;",
     "\t ",
     "",
     "\tvar tlines = buf.get_line_count () +1;",
     "\t   ",
     "\t\tvar msg = \"Line: %d %s : %s\".printf(eline+1, err.category, err.msg);",
     "\t    buf.create_source_mark( msg, err.category, iter);",
-    "\t    GLib.debug(\"set line %d to %m\", eline, msg);",
-    "\t   // this.marks.set(eline, msg);",
+    "\t    GLib.debug(\"set line %d to %s\", eline, msg);",
+    "\t    //this.marks.set(eline, msg);",
     "\t}",
     "\treturn ;",
     "",
    ]
   }
  ],
- "name" : "Editor"
+ "modOrder" : "",
+ "name" : "Editor",
+ "parent" : "",
+ "path" : "/home/alan/gitlive/roobuilder/src/Builder4/Editor.bjs",
+ "permname" : "",
+ "title" : ""
 }
\ No newline at end of file
index e03db08..c1cca4b 100644 (file)
-    static Editor  _Editor;
+static Editor  _Editor;
 
-    public class Editor : Object
-    {
-        public Gtk.Box el;
-        private Editor  _this;
-
-        public static Editor singleton()
-        {
-            if (_Editor == null) {
-                _Editor= new Editor();
-            }
-            return _Editor;
-        }
-        public Xcls_save_button save_button;
-        public Xcls_close_btn close_btn;
-        public Xcls_RightEditor RightEditor;
-        public Xcls_view view;
-        public Xcls_buffer buffer;
-        public Xcls_search_entry search_entry;
-        public Xcls_search_results search_results;
-        public Xcls_nextBtn nextBtn;
-        public Xcls_backBtn backBtn;
-        public Xcls_search_settings search_settings;
-        public Xcls_case_sensitive case_sensitive;
-        public Xcls_regex regex;
-        public Xcls_multiline multiline;
-
-            // my vars (def)
-        public int pos_root_x;
-        public Xcls_MainWindow window;
-        public bool dirty;
-        public int pos_root_y;
-        public bool pos;
-        public GtkSource.SearchContext searchcontext;
-        public int last_search_end;
-        public signal void save ();
-        public JsRender.JsRender? file;
-        public JsRender.Node node;
-        public JsRender.NodeProp? prop;
-        public string activeEditor;
-
-        // ctor
-        public Editor()
-        {
-            _this = this;
-            this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
-
-            // my vars (dec)
-            this.window = null;
-            this.dirty = false;
-            this.pos = false;
-            this.searchcontext = null;
-            this.last_search_end = 0;
-            this.file = null;
-            this.node = null;
-            this.prop = null;
-            this.activeEditor = "";
+public class Editor : Object
+{
+    public Gtk.Box el;
+    private Editor  _this;
 
-            // set gobject values
-            this.el.homogeneous = false;
-            this.el.hexpand = true;
-            this.el.vexpand = true;
-            var child_1 = new Xcls_Box2( _this );
-            child_1.ref();
-            this.el.append( child_1.el );
-            new Xcls_RightEditor( _this );
-            this.el.append( _this.RightEditor.el );
-            var child_3 = new Xcls_Box12( _this );
-            child_3.ref();
-            this.el.append ( child_3.el  );
+    public static Editor singleton()
+    {
+        if (_Editor == null) {
+            _Editor= new Editor();
         }
+        return _Editor;
+    }
+    public Xcls_save_button save_button;
+    public Xcls_close_btn close_btn;
+    public Xcls_RightEditor RightEditor;
+    public Xcls_view view;
+    public Xcls_buffer buffer;
+    public Xcls_search_entry search_entry;
+    public Xcls_search_results search_results;
+    public Xcls_nextBtn nextBtn;
+    public Xcls_backBtn backBtn;
+    public Xcls_search_settings search_settings;
+    public Xcls_case_sensitive case_sensitive;
+    public Xcls_regex regex;
+    public Xcls_multiline multiline;
+
+        // my vars (def)
+    public int pos_root_x;
+    public Xcls_MainWindow window;
+    public bool dirty;
+    public int pos_root_y;
+    public bool pos;
+    public GtkSource.SearchContext searchcontext;
+    public int last_search_end;
+    public signal void save ();
+    public JsRender.JsRender? file;
+    public JsRender.Node node;
+    public JsRender.NodeProp? prop;
+    public string activeEditor;
+
+    // ctor
+    public Editor()
+    {
+        _this = this;
+        this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
+
+        // my vars (dec)
+        this.window = null;
+        this.dirty = false;
+        this.pos = false;
+        this.searchcontext = null;
+        this.last_search_end = 0;
+        this.file = null;
+        this.node = null;
+        this.prop = null;
+        this.activeEditor = "";
+
+        // set gobject values
+        this.el.homogeneous = false;
+        this.el.hexpand = true;
+        this.el.vexpand = true;
+        var child_1 = new Xcls_Box2( _this );
+        child_1.ref();
+        this.el.append( child_1.el );
+        var child_2 = new Xcls_RightEditor( _this );
+        child_2.ref();
+        this.el.append( child_2.el );
+        var child_3 = new Xcls_Box12( _this );
+        child_3.ref();
+        this.el.append ( child_3.el  );
+    }
 
-        // user defined functions
-        public bool saveContents ()  {
-            
-            
-            if (_this.file == null) {
-                return true;
-            }
-            
-             
-             
-             var str = _this.buffer.toString();
-             
-             _this.buffer.checkSyntax();
-             
-             
-             
-             // LeftPanel.model.changed(  str , false);
-             _this.dirty = false;
-             _this.save_button.el.sensitive = false;
-             
-            // find the text for the node..
-            if (_this.file.xtype != "PlainFile") {
-               // in theory these properties have to exist!?!
-               this.prop.val = str;
-                //this.window.windowstate.left_props.reload();
-            } else {
-                _this.file.setSource(  str );
-             }
-            
-            // call the signal..
-            this.save();
-            
-            return true;
+    // user defined functions
+    public bool saveContents ()  {
         
-        }
-        public void forwardSearch (bool change_focus) {
         
-               if (this.searchcontext == null) {
-                       return;
-               } 
-               
-               Gtk.TextIter beg, st,en;
-                bool has_wrapped_around;
-               this.buffer.el.get_iter_at_offset(out beg, this.last_search_end);
-               if (!this.searchcontext.forward(beg, out st, out en, out has_wrapped_around)) {
-               
-                       this.last_search_end = 0; // not sure if this should happen
-               } else {
-                       if (has_wrapped_around) {
-                               return;
-                       }
-               
-                       this.last_search_end = en.get_offset();
-                       if (change_focus) {
-                               this.view.el.grab_focus();
-                       }
-                       this.buffer.el.place_cursor(st);
-                       this.view.el.scroll_to_iter(st,  0.1f, true, 0.0f, 0.5f);
-               }
-         
+        if (_this.file == null) {
+            return true;
         }
-        public void show (JsRender.JsRender file, JsRender.Node? node, JsRender.NodeProp? prop)
-        {
-            this.reset();
-            this.file = file;    
-            
-            if (file.xtype != "PlainFile") {
-               this.prop = prop;
-                this.node = node;
         
-                // find the text for the node..
-                this.view.load( prop.val );
-                
-                
-                this.close_btn.el.show();       
-            
-            } else {
-                this.view.load(        file.toSource() );
-                this.close_btn.el.hide();
-            }
          
-        }
-        public void backSearch (bool change_focus) {
-        
-               if (this.searchcontext == null) {
-                       return;
-               } 
-               
-               Gtk.TextIter beg, st,en;
-               bool has_wrapped_around;
-               this.buffer.el.get_iter_at_offset(out beg, this.last_search_end -1 );
-               
-               if (!this.searchcontext.backward(beg, out st, out en, out has_wrapped_around)) {
-                       this.last_search_end = 0;
-               } else {
-                       this.last_search_end = en.get_offset();
-                       if (change_focus) {
-                               this.view.el.grab_focus();
-                       }
-                       this.buffer.el.place_cursor(st);
-                       this.view.el.scroll_to_iter(st,  0.1f, true, 0.0f, 0.5f);
-               }
-        
-        }
-        public void reset () {
-                this.file = null;    
-             
-            this.node = null;
-            this.prop = null;
-               this.searchcontext = null;
-          
-        }
-        public int search (string in_txt) {
-        
-               var s = new GtkSource.SearchSettings();
-               s.case_sensitive = _this.case_sensitive.el.active;
-               s.regex_enabled = _this.regex.el.active;        
-               s.wrap_around = false;
-               
-               this.searchcontext = new GtkSource.SearchContext(this.buffer.el,s);
-               this.searchcontext.set_highlight(true);
-               var txt = in_txt;
-               
-               if (_this.multiline.el.active) {
-                       txt = in_txt.replace("\\n", "\n");
-               }
-               
-               s.set_search_text(txt);
-               Gtk.TextIter beg, st,en;
-                
-               this.buffer.el.get_start_iter(out beg);
-               bool has_wrapped_around;
-               this.searchcontext.forward(beg, out st, out en, out has_wrapped_around);
-               this.last_search_end = 0;
-               
-               return this.searchcontext.get_occurrences_count();
-        
          
-           
-        
-        }
-        public void updateErrorMarks (GLib.ListStore?  ar) {
-               
+         var str = _this.buffer.toString();
          
-               
-                var buf = _this.buffer.el;
-               Gtk.TextIter start;
-               Gtk.TextIter end;     
-               buf.get_bounds (out start, out end);
-        
-               buf.remove_source_marks (start, end, "ERR");
-               buf.remove_source_marks (start, end, "WARN");
-               buf.remove_source_marks (start, end, "DEPR");
-               GLib.debug("highlight errors");          
-        
-                // we should highlight other types of errors..
-        
-               if (ar == null || ar.get_n_items() < 1) {
-                       GLib.debug("Return has no errors\n");
-                       return;
-               }
-        
-               if (_this.window.windowstate.state != WindowState.State.CODEONLY 
-                       &&
-                       _this.window.windowstate.state != WindowState.State.CODE
-                       ) {
-                       GLib.debug("windowstate != CODEONLY?");
-                       
-                       return;
-               } 
-        
-                
-               if (_this.file == null) {
-                       GLib.debug("file is null?");
-                       return;
-        
-               }
+         _this.buffer.checkSyntax();
          
-        
          
-               
-               var offset = 1;
-                
-        
-               var tlines = buf.get_line_count () +1;
-               
-               if (_this.prop != null) {
-               
-                       tlines = _this.prop.end_line + 1;
-                       offset = _this.prop.start_line + 1;
-               
-               }
-                
-               for (var i = 0; i < ar.get_n_items();i++) {
-                       var err = (Palete.CompileError) ar.get_item(i);
-                       
-                    Gtk.TextIter iter;
-        //        print("get inter\n");
-                   var eline = err.line - offset;
-                   GLib.debug("GOT ERROR on line %d -- converted to %d  (offset = %d)",
-                       err.line ,eline, offset);
-                   
-                   
-                   if (eline > tlines || eline < 0) {
-                       return;
-                   }
-                  
-                   
-                   buf.get_iter_at_line( out iter, eline);
-                  
-                  
-                       var msg = "Line: %d %s : %s".printf(eline+1, err.category, err.msg);
-                   buf.create_source_mark( msg, err.category, iter);
-                   GLib.debug("set line %d to %m", eline, msg);
-                  // this.marks.set(eline, msg);
-               }
-               return ;
-        
-        
-        
          
+         // LeftPanel.model.changed(  str , false);
+         _this.dirty = false;
+         _this.save_button.el.sensitive = false;
+         
+        // find the text for the node..
+        if (_this.file.xtype != "PlainFile") {
+           // in theory these properties have to exist!?!
+               this.prop.val = str;
+            //this.window.windowstate.left_props.reload();
+        } else {
+            _this.file.setSource(  str );
+         }
         
-        }
-        public void scroll_to_line (int line) {
+        // call the signal..
+        this.save();
         
-               GLib.Timeout.add(500, () => {
-           
-                       var buf = this.view.el.get_buffer();
-        
-                       var sbuf = (GtkSource.Buffer) buf;
+        return true;
+    
+    }
+    public void forwardSearch (bool change_focus) {
+    
+       if (this.searchcontext == null) {
+               return;
+       } 
+       
+       Gtk.TextIter beg, st,en;
+        bool has_wrapped_around;
+       this.buffer.el.get_iter_at_offset(out beg, this.last_search_end);
+       if (!this.searchcontext.forward(beg, out st, out en, out has_wrapped_around)) {
+       
+               this.last_search_end = 0; // not sure if this should happen
+       } else {
+               if (has_wrapped_around) {
+                       return;
+               }
+       
+               this.last_search_end = en.get_offset();
+               if (change_focus) {
+                       this.view.el.grab_focus();
+               }
+               this.buffer.el.place_cursor(st);
+               this.view.el.scroll_to_iter(st,  0.1f, true, 0.0f, 0.5f);
+       }
+     
+    }
+    public void show (JsRender.JsRender file, JsRender.Node? node, JsRender.NodeProp? prop)
+    {
+        this.reset();
+        this.file = file;    
         
+        if (file.xtype != "PlainFile") {
+               this.prop = prop;
+            this.node = node;
+    
+            // find the text for the node..
+            this.view.load( prop.val );
+            
+            
+            this.close_btn.el.show();       
         
-                       Gtk.TextIter iter;   
-                       sbuf.get_iter_at_line(out iter,  line);
-                       this.view.el.scroll_to_iter(iter,  0.1f, true, 0.0f, 0.5f);
-                       return false;
-               });   
+        } else {
+            this.view.load(        file.toSource() );
+            this.close_btn.el.hide();
         }
-        public class Xcls_Box2 : Object
-        {
-            public Gtk.Box el;
-            private Editor  _this;
+     
+    }
+    public void backSearch (bool change_focus) {
+    
+       if (this.searchcontext == null) {
+               return;
+       } 
+       
+       Gtk.TextIter beg, st,en;
+       bool has_wrapped_around;
+       this.buffer.el.get_iter_at_offset(out beg, this.last_search_end -1 );
+       
+       if (!this.searchcontext.backward(beg, out st, out en, out has_wrapped_around)) {
+               this.last_search_end = 0;
+       } else {
+               this.last_search_end = en.get_offset();
+               if (change_focus) {
+                       this.view.el.grab_focus();
+               }
+               this.buffer.el.place_cursor(st);
+               this.view.el.scroll_to_iter(st,  0.1f, true, 0.0f, 0.5f);
+       }
+    
+    }
+    public void reset () {
+        this.file = null;    
+         
+        this.node = null;
+        this.prop = null;
+       this.searchcontext = null;
+      
+    }
+    public int search (string in_txt) {
+    
+       var s = new GtkSource.SearchSettings();
+       s.case_sensitive = _this.case_sensitive.el.active;
+       s.regex_enabled = _this.regex.el.active;        
+       s.wrap_around = false;
+       
+       this.searchcontext = new GtkSource.SearchContext(this.buffer.el,s);
+       this.searchcontext.set_highlight(true);
+       var txt = in_txt;
+       
+       if (_this.multiline.el.active) {
+               txt = in_txt.replace("\\n", "\n");
+       }
+       
+       s.set_search_text(txt);
+       Gtk.TextIter beg, st,en;
+        
+       this.buffer.el.get_start_iter(out beg);
+       bool has_wrapped_around;
+       this.searchcontext.forward(beg, out st, out en, out has_wrapped_around);
+       this.last_search_end = 0;
+       
+       return this.searchcontext.get_occurrences_count();
+    
+     
+       
+    
+    }
+    public void updateErrorMarks (string category) {
+       
+     
+    
+       var buf = _this.buffer.el;
+       Gtk.TextIter start;
+       Gtk.TextIter end;     
+       buf.get_bounds (out start, out end);
+    
+       buf.remove_source_marks (start, end, category);
+     
+       GLib.debug("highlight errors");          
+    
+        // we should highlight other types of errors..
+    
+       if (_this.window.windowstate.state != WindowState.State.CODEONLY 
+               &&
+               _this.window.windowstate.state != WindowState.State.CODE
+               ) {
+               GLib.debug("windowstate != CODEONLY?");
+               
+               return;
+       } 
+    
+        
+       if (_this.file == null) {
+               GLib.debug("file is null?");
+               return;
+    
+       }
+       var ar = this.file.getErrors(category);
+       if (ar == null || ar.get_n_items() < 1) {
+               GLib.debug("highlight %s :  %s has no errors", this.file.relpath, category);
+               return;
+       }
+     
+    
+     
+       
+       var offset = 0;
+        
+    
+       var tlines = buf.get_line_count () +1;
+       
+       if (_this.prop != null) {
+       
+               tlines = _this.prop.end_line + 1;
+               offset = _this.prop.start_line + 1;
+       
+       }
+        
+       for (var i = 0; i < ar.get_n_items();i++) {
+               var err = (Palete.CompileError) ar.get_item(i);
+               
+            Gtk.TextIter iter;
+    //        print("get inter\n");
+           var eline = err.line - offset;
+           GLib.debug("GOT ERROR on line %d -- converted to %d  (offset = %d)",
+               err.line ,eline, offset);
+           
+           
+           if (eline > tlines || eline < 0) {
+               return;
+           }
+          
+           
+           buf.get_iter_at_line( out iter, eline);
+          
+          
+               var msg = "Line: %d %s : %s".printf(eline+1, err.category, err.msg);
+           buf.create_source_mark( msg, err.category, iter);
+           GLib.debug("set line %d to %s", eline, msg);
+           //this.marks.set(eline, msg);
+       }
+       return ;
+    
+    
+    
+     
+    
+    }
+    public void scroll_to_line (int line) {
+    
+       GLib.Timeout.add(500, () => {
+       
+               var buf = this.view.el.get_buffer();
+    
+               var sbuf = (GtkSource.Buffer) buf;
+    
+    
+               Gtk.TextIter iter;   
+               sbuf.get_iter_at_line(out iter,  line);
+               this.view.el.scroll_to_iter(iter,  0.1f, true, 0.0f, 0.5f);
+               return false;
+       });   
+    }
+    public class Xcls_Box2 : Object
+    {
+        public Gtk.Box el;
+        private Editor  _this;
 
 
-                // my vars (def)
+            // my vars (def)
 
-            // ctor
-            public Xcls_Box2(Editor _owner )
-            {
-                _this = _owner;
-                this.el = new Gtk.Box( Gtk.Orientation.HORIZONTAL, 0 );
-
-                // my vars (dec)
-
-                // set gobject values
-                this.el.homogeneous = false;
-                this.el.hexpand = true;
-                new Xcls_save_button( _this );
-                this.el.append( _this.save_button.el );
-                var child_2 = new Xcls_Label4( _this );
-                child_2.ref();
-                this.el.append( child_2.el );
-                var child_3 = new Xcls_Scale5( _this );
-                child_3.ref();
-                this.el.append( child_3.el );
-                new Xcls_close_btn( _this );
-                this.el.append( _this.close_btn.el );
-            }
+        // ctor
+        public Xcls_Box2(Editor _owner )
+        {
+            _this = _owner;
+            this.el = new Gtk.Box( Gtk.Orientation.HORIZONTAL, 0 );
+
+            // my vars (dec)
 
-            // user defined functions
+            // set gobject values
+            this.el.homogeneous = false;
+            this.el.hexpand = true;
+            var child_1 = new Xcls_save_button( _this );
+            child_1.ref();
+            this.el.append( child_1.el );
+            var child_2 = new Xcls_Label4( _this );
+            child_2.ref();
+            this.el.append( child_2.el );
+            var child_3 = new Xcls_Scale5( _this );
+            child_3.ref();
+            this.el.append( child_3.el );
+            var child_4 = new Xcls_close_btn( _this );
+            child_4.ref();
+            this.el.append( child_4.el );
         }
-        public class Xcls_save_button : Object
-        {
-            public Gtk.Button el;
-            private Editor  _this;
 
+        // user defined functions
+    }
+    public class Xcls_save_button : Object
+    {
+        public Gtk.Button el;
+        private Editor  _this;
 
-                // my vars (def)
 
-            // ctor
-            public Xcls_save_button(Editor _owner )
-            {
-                _this = _owner;
-                _this.save_button = this;
-                this.el = new Gtk.Button();
+            // my vars (def)
 
-                // my vars (dec)
+        // ctor
+        public Xcls_save_button(Editor _owner )
+        {
+            _this = _owner;
+            _this.save_button = this;
+            this.el = new Gtk.Button();
 
-                // set gobject values
-                this.el.label = "Save";
+            // my vars (dec)
 
-                //listeners
-                this.el.clicked.connect( () => { 
-                    _this.saveContents();
-                });
-            }
+            // set gobject values
+            this.el.label = "Save";
 
-            // user defined functions
+            //listeners
+            this.el.clicked.connect( () => { 
+                _this.saveContents();
+            });
         }
 
-        public class Xcls_Label4 : Object
-        {
-            public Gtk.Label el;
-            private Editor  _this;
+        // user defined functions
+    }
 
+    public class Xcls_Label4 : Object
+    {
+        public Gtk.Label el;
+        private Editor  _this;
 
-                // my vars (def)
 
-            // ctor
-            public Xcls_Label4(Editor _owner )
-            {
-                _this = _owner;
-                this.el = new Gtk.Label( null );
+            // my vars (def)
 
-                // my vars (dec)
+        // ctor
+        public Xcls_Label4(Editor _owner )
+        {
+            _this = _owner;
+            this.el = new Gtk.Label( null );
 
-                // set gobject values
-                this.el.hexpand = true;
-            }
+            // my vars (dec)
 
-            // user defined functions
+            // set gobject values
+            this.el.hexpand = true;
         }
 
-        public class Xcls_Scale5 : Object
-        {
-            public Gtk.Scale el;
-            private Editor  _this;
+        // user defined functions
+    }
 
+    public class Xcls_Scale5 : Object
+    {
+        public Gtk.Scale el;
+        private Editor  _this;
 
-                // my vars (def)
 
-            // ctor
-            public Xcls_Scale5(Editor _owner )
-            {
-                _this = _owner;
-                this.el = new Gtk.Scale.with_range (Gtk.Orientation.HORIZONTAL,6, 30, 1);
+            // my vars (def)
 
-                // my vars (dec)
+        // ctor
+        public Xcls_Scale5(Editor _owner )
+        {
+            _this = _owner;
+            this.el = new Gtk.Scale.with_range (Gtk.Orientation.HORIZONTAL,6, 30, 1);
 
-                // set gobject values
-                this.el.width_request = 200;
-                this.el.has_origin = true;
-                this.el.draw_value = false;
-                this.el.digits = 0;
-                this.el.sensitive = true;
+            // my vars (dec)
 
-                // init method
+            // set gobject values
+            this.el.width_request = 200;
+            this.el.has_origin = true;
+            this.el.draw_value = false;
+            this.el.digits = 0;
+            this.el.sensitive = true;
 
-                {
-                       this.el.set_range(6,30);
-                       this.el.set_value(8);
-                }
+            // init method
 
-                //listeners
-                this.el.change_value.connect( (st, val ) => {
-                        
-                          
-                         _this.view.css.load_from_string(
-                                       "#editor-view { font: %dpx monospace; }".printf((int)val)
-                          );
-                     
-                       return false;
-                });
+            {
+               this.el.set_range(6,30);
+               this.el.set_value(8);
             }
 
-            // user defined functions
+            //listeners
+            this.el.change_value.connect( (st, val ) => {
+                
+                  
+                 _this.view.css.load_from_string(
+                               "#editor-view { font: %dpx monospace; }".printf((int)val)
+                  );
+                 
+               return false;
+            });
         }
 
-        public class Xcls_close_btn : Object
-        {
-            public Gtk.Button el;
-            private Editor  _this;
+        // user defined functions
+    }
 
+    public class Xcls_close_btn : Object
+    {
+        public Gtk.Button el;
+        private Editor  _this;
 
-                // my vars (def)
 
-            // ctor
-            public Xcls_close_btn(Editor _owner )
-            {
-                _this = _owner;
-                _this.close_btn = this;
-                this.el = new Gtk.Button();
+            // my vars (def)
 
-                // my vars (dec)
+        // ctor
+        public Xcls_close_btn(Editor _owner )
+        {
+            _this = _owner;
+            _this.close_btn = this;
+            this.el = new Gtk.Button();
 
-                // set gobject values
-                this.el.icon_name = "window-close";
-                var child_1 = new Xcls_Image7( _this );
-                this.el.child = child_1.el;
+            // my vars (dec)
 
-                //listeners
-                this.el.clicked.connect( () => { 
-                    _this.saveContents();
-                    _this.window.windowstate.switchState(WindowState.State.PREVIEW);
-                });
-            }
+            // set gobject values
+            this.el.icon_name = "window-close";
+            var child_1 = new Xcls_Image7( _this );
+            child_1.ref();
+            this.el.child = child_1.el;
 
-            // user defined functions
+            //listeners
+            this.el.clicked.connect( () => { 
+                _this.saveContents();
+                _this.window.windowstate.switchState(WindowState.State.PREVIEW);
+            });
         }
-        public class Xcls_Image7 : Object
-        {
-            public Gtk.Image el;
-            private Editor  _this;
 
+        // user defined functions
+    }
+    public class Xcls_Image7 : Object
+    {
+        public Gtk.Image el;
+        private Editor  _this;
 
-                // my vars (def)
 
-            // ctor
-            public Xcls_Image7(Editor _owner )
-            {
-                _this = _owner;
-                this.el = new Gtk.Image();
+            // my vars (def)
 
-                // my vars (dec)
+        // ctor
+        public Xcls_Image7(Editor _owner )
+        {
+            _this = _owner;
+            this.el = new Gtk.Image();
 
-                // set gobject values
-                this.el.icon_name = "window-close";
-                this.el.icon_size = Gtk.IconSize.NORMAL;
-            }
+            // my vars (dec)
 
-            // user defined functions
+            // set gobject values
+            this.el.icon_name = "window-close";
+            this.el.icon_size = Gtk.IconSize.NORMAL;
         }
 
+        // user defined functions
+    }
 
 
-        public class Xcls_RightEditor : Object
-        {
-            public Gtk.ScrolledWindow el;
-            private Editor  _this;
 
+    public class Xcls_RightEditor : Object
+    {
+        public Gtk.ScrolledWindow el;
+        private Editor  _this;
 
-                // my vars (def)
 
-            // ctor
-            public Xcls_RightEditor(Editor _owner )
-            {
-                _this = _owner;
-                _this.RightEditor = this;
-                this.el = new Gtk.ScrolledWindow();
-
-                // my vars (dec)
-
-                // set gobject values
-                this.el.vscrollbar_policy = Gtk.PolicyType.AUTOMATIC;
-                this.el.vexpand = true;
-                this.el.overlay_scrolling = false;
-                this.el.hscrollbar_policy = Gtk.PolicyType.AUTOMATIC;
-                new Xcls_view( _this );
-                this.el.child = _this.view.el;
-            }
+            // my vars (def)
 
-            // user defined functions
-        }
-        public class Xcls_view : Object
+        // ctor
+        public Xcls_RightEditor(Editor _owner )
         {
-            public GtkSource.View el;
-            private Editor  _this;
+            _this = _owner;
+            _this.RightEditor = this;
+            this.el = new Gtk.ScrolledWindow();
 
+            // my vars (dec)
 
-                // my vars (def)
-            public Gtk.CssProvider css;
+            // set gobject values
+            this.el.vscrollbar_policy = Gtk.PolicyType.AUTOMATIC;
+            this.el.vexpand = true;
+            this.el.overlay_scrolling = false;
+            this.el.hscrollbar_policy = Gtk.PolicyType.AUTOMATIC;
+            var child_1 = new Xcls_view( _this );
+            child_1.ref();
+            this.el.child = child_1.el;
+        }
 
-            // ctor
-            public Xcls_view(Editor _owner )
-            {
-                _this = _owner;
-                _this.view = this;
-                this.el = new GtkSource.View();
-
-                // my vars (dec)
-                this.css = null;
-
-                // set gobject values
-                this.el.auto_indent = true;
-                this.el.indent_width = 4;
-                this.el.name = "editor-view";
-                this.el.show_line_marks = true;
-                this.el.insert_spaces_instead_of_tabs = true;
-                this.el.show_line_numbers = true;
-                this.el.hexpand = true;
-                this.el.vexpand = true;
-                this.el.has_tooltip = true;
-                this.el.tab_width = 4;
-                this.el.highlight_current_line = true;
-                new Xcls_buffer( _this );
-                this.el.buffer = _this.buffer.el;
-                var child_2 = new Xcls_EventControllerKey11( _this );
-                child_2.ref();
-                this.el.add_controller(  child_2.el );
-
-                // init method
-
-                this.css = new Gtk.CssProvider();
-                
-                this.css.load_from_string(
-                       "#editor-view { font:  12px monospace;}"
-                );
-                 
-                Gtk.StyleContext.add_provider_for_display(
-                       this.el.get_display(),
-                       this.css,
-                       Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
-                );
-                       
-                 
-                        
-                
-                       
-                this.el.completion.add_provider(new Palete.CompletionProvider(_this));
-                 
-                
-                this.el.completion.unblock_interactive();
-                this.el.completion.select_on_show = true; // select
-                
-                this.el.completion.remember_info_visibility     = true;
-                
-                
-                var attrs = new GtkSource.MarkAttributes();
-                var  pink =   Gdk.RGBA();
-                pink.parse ( "pink");
-                attrs.set_background ( pink);
-                attrs.set_icon_name ( "process-stop");    
-                attrs.query_tooltip_text.connect(( mark) => {
-                     GLib.debug("tooltip query? %s", mark.name);
-                    return strdup( mark.name);
-                });
-                 attrs.query_tooltip_markup.connect(( mark) => {
-                     GLib.debug("tooltip query? %s", mark.name);
-                    return strdup( mark.name);
-                });
-                this.el.set_mark_attributes ("ERR", attrs, 1);
-                attrs.ref();
-                 var wattrs = new GtkSource.MarkAttributes();
-                var  blue =   Gdk.RGBA();
-                blue.parse ( "#ABF4EB");
-                wattrs.set_background ( blue);
-                wattrs.set_icon_name ( "process-stop");    
-                wattrs.query_tooltip_text.connect(( mark) => {
-                     GLib.debug("tooltip query? %s", mark.name);
-                    return strdup(mark.name);
-                });
-                wattrs.query_tooltip_markup.connect(( mark) => {
-                     GLib.debug("tooltip query? %s", mark.name);
-                    return strdup(mark.name);
-                });
-                this.el.set_mark_attributes ("WARN", wattrs, 1);
-                wattrs.ref();
-                
-                
-                 var dattrs = new GtkSource.MarkAttributes();
-                var  purple =   Gdk.RGBA();
-                purple.parse ( "#EEA9FF");
-                dattrs.set_background ( purple);
-                dattrs.set_icon_name ( "process-stop");    
-                dattrs.query_tooltip_text.connect(( mark) => {
-                       GLib.debug("tooltip query? %s", mark.name);
-                    return strdup(mark.name);
-                });
-                dattrs.query_tooltip_markup.connect(( mark) => {
-                       GLib.debug("tooltip query? %s", mark.name);
-                    return strdup(mark.name);
-                });
-                this.el.set_mark_attributes ("DEPR", dattrs, 1);
-                dattrs.ref();    
-                
-                 this.el.get_space_drawer().set_matrix(null);
-                 this.el.get_space_drawer().set_types_for_locations( 
-                       GtkSource.SpaceLocationFlags.ALL,
-                       GtkSource.SpaceTypeFlags.ALL
-                );
-                this.el.get_space_drawer().set_enable_matrix(true);
-                /*
-                Gtk.SourceDrawSpacesFlags.LEADING + 
-                Gtk.SourceDrawSpacesFlags.TRAILING + 
-                Gtk.SourceDrawSpacesFlags.TAB + 
-                Gtk.SourceDrawSpacesFlags.SPACE
-                */
-
-                //listeners
-                this.el.query_tooltip.connect( (x, y, keyboard_tooltip, tooltip) => {
-                       
-                       //GLib.debug("query tooltip");
-                       Gtk.TextIter iter;
-                       int trailing;
-                       
-                       var yoff = (int) _this.RightEditor.el.vadjustment.value;
-                       
-                       // I think this is problematic - if it's compliing  / updating at same time as query.
-                       
-                       //if (_this.window.statusbar_compile_spinner.el.spinning) {
-                       //      return false;
-                       //}
-                       
-                       this.el.get_iter_at_position (out iter, out trailing,  x,  y + yoff);
-                        
-                       var l = iter.get_line();
-                
-                       
-                        
-                       // GLib.debug("query tooltip line %d", (int) l);
-                       if (l < 0) {
-                
-                               return false;
-                       }
-                       /*
-                       if (_this.buffer.marks != null && _this.buffer.marks.has_key(l)) {
-                               GLib.debug("line %d setting tip to %s", l,  _this.buffer.marks.get(l));
-                               tooltip.set_text(_this.buffer.marks.get(l).dup());
-                               return true;
-                       }
-                 
-                       return false;
-                       */
-                       
-                         
-                       // this crashes?? - not sure why.
-                       var marks = _this.buffer.el.get_source_marks_at_line(l, "ERR");
-                       if (marks.is_empty()) {
-                               marks = _this.buffer.el.get_source_marks_at_line(l, "WARN");
-                       }
-                       if (marks.is_empty()) {
-                               marks = _this.buffer.el.get_source_marks_at_line(l, "DEPR");
-                       }
-                       
-                       // GLib.debug("query tooltip line %d marks %d", (int)l, (int) marks.length());
-                       var str = "";
-                       marks.@foreach((m) => { 
-                               //GLib.debug("got mark %s", m.name);
-                               str += (str.length > 0 ? "\n" : "") + m.category + ": " + m.name;
-                       });
-                       // true if there is a mark..
-                       if (str.length > 0 ) {
-                               tooltip.set_text( str );
-                       }
-                       return str.length > 0 ? true : false;
-                        
-                });
-            }
+        // user defined functions
+    }
+    public class Xcls_view : Object
+    {
+        public GtkSource.View el;
+        private Editor  _this;
 
-            // user defined functions
-            public void load (string str) {
-            
-            // show the help page for the active node..
-               //this.get('/Help').show();
-             
-              // this.get('/BottomPane').el.set_current_page(0);
-               GLib.debug("load called - Reset undo buffer");
-               
-                var buf = (GtkSource.Buffer)this.el.get_buffer();
-                buf.begin_irreversible_action();
-                buf.set_text(str, str.length);
-                buf.end_irreversible_action();
-                
-                var lm = GtkSource.LanguageManager.get_default();
-                var lang = "vala";
-                if (_this.file != null) {
-                     lang = _this.file.language;
-                }
-                print("lang=%s, content_type = %s\n", lang, _this.file.content_type);
-                var lg = _this.file.content_type.length > 0  ?
-                        lm.guess_language(_this.file.path, _this.file.content_type) :
-                        lm.get_language(lang);
-                 
-               
-                ((GtkSource.Buffer)(this.el.get_buffer())) .set_language(lg); 
-            
-                this.el.insert_spaces_instead_of_tabs = true;
-                if (lg != null) {
-                       print("sourcelanguage  = %s\n", lg.name);
-                       if (lg.name == "Vala") {
-                           this.el.insert_spaces_instead_of_tabs = false;
-                       }
-                 }
-                _this.dirty = false;
-                this.el.grab_focus();
-                _this.save_button.el.sensitive = false;
-            }
-        }
-        public class Xcls_buffer : Object
+
+            // my vars (def)
+        public Gtk.CssProvider css;
+
+        // ctor
+        public Xcls_view(Editor _owner )
         {
-            public GtkSource.Buffer el;
-            private Editor  _this;
+            _this = _owner;
+            _this.view = this;
+            this.el = new GtkSource.View();
 
+            // my vars (dec)
+            this.css = null;
 
-                // my vars (def)
-            public int error_line;
-            public Gee.HashMap<int,string>? xmarks;
-            public bool check_queued;
+            // set gobject values
+            this.el.auto_indent = true;
+            this.el.indent_width = 4;
+            this.el.name = "editor-view";
+            this.el.show_line_marks = true;
+            this.el.insert_spaces_instead_of_tabs = true;
+            this.el.show_line_numbers = true;
+            this.el.hexpand = true;
+            this.el.vexpand = true;
+            this.el.has_tooltip = true;
+            this.el.tab_width = 4;
+            this.el.highlight_current_line = true;
+            var child_1 = new Xcls_buffer( _this );
+            child_1.ref();
+            this.el.buffer = child_1.el;
+            var child_2 = new Xcls_EventControllerKey11( _this );
+            child_2.ref();
+            this.el.add_controller(  child_2.el );
 
-            // ctor
-            public Xcls_buffer(Editor _owner )
-            {
-                _this = _owner;
-                _this.buffer = this;
-                this.el = new GtkSource.Buffer( null );
-
-                // my vars (dec)
-                this.error_line = -1;
-                this.xmarks = null;
-                this.check_queued = false;
-
-                // set gobject values
-                this.el.enable_undo = true;
-
-                //listeners
-                this.el.changed.connect( () => {
-                    // check syntax??
-                    // ??needed..??
-                    _this.save_button.el.sensitive = true;
-                    print("EDITOR CHANGED");
-                    this.checkSyntax();
-                   
-                    _this.dirty = true;
-                
-                    // this.get('/LeftPanel.model').changed(  str , false);
-                    return ;
-                });
-            }
+            // init method
 
-            // user defined functions
-            public bool checkSyntax () {
-             
-                
-                var str = this.toString();
-                
-                // needed???
-                if (this.error_line > 0) {
-                     Gtk.TextIter start;
-                     Gtk.TextIter end;     
-                    this.el.get_bounds (out start, out end);
+            this.css = new Gtk.CssProvider();
             
-                    this.el.remove_source_marks (start, end, null);
-                }
-                if (str.length < 1) {
-                    print("checkSyntax - empty string?\n");
-                    return true;
-                }
-                
-                // bit presumptiona
-                if (_this.file.xtype == "PlainFile" && _this.file.project.xtype == "Gtk") {
-                
-                    // assume it's gtk...
-                       
-                       BuilderApplication.valacompilequeue.addFile( 
-                               Palete.ValaCompileRequestType.FILE_CHANGE, 
-                               _this.file , str, false) ;
+            this.css.load_from_string(
+               "#editor-view { font:  12px monospace;}"
+            );
+             
+            Gtk.StyleContext.add_provider_for_display(
+               this.el.get_display(),
+               this.css,
+               Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
+            );
+               
+             
+                
+            /*
+            this is pretty flakey - triggers Gtk with  < 0 d
+             var cp = new GtkSource.CompletionWords("test"); 
+             cp.minimum_word_size  = 3;
+             //cp.priority = 100; //?? does this do anything
+             cp.proposals_batch_size  = 10;
+             cp.scan_batch_size = 1000;
+             
+            cp.register(_this.buffer.el);
+            this.el.completion.add_provider(cp);
+            */
+            this.el.completion.add_provider(new Palete.CompletionProvider(_this));
               
+            //this.el.completion.unblock_interactive();
+            this.el.completion.select_on_show = true; // select
+            //this.el.completion.remember_info_visibility       = true;
             
-                    return true;
-                
-                }
-               if (_this.file == null) {
-                   return true;
-               }
-             
-                
             
-                  
-                 
-                GLib.debug("calling validate");    
-                // clear the buttons.
-             
-                BuilderApplication.valacompilequeue.addProp( 
-                               Palete.ValaCompileRequestType.PROP_CHANGE,
-                               _this.file,
-                               _this.node,
-                               _this.prop,
-                               str); 
-                 
-                
-                
-                //print("done mark line\n");
-                 
-                return true; // at present allow saving - even if it's invalid..
-            }
-            public bool highlightErrorsJson (string type, Json.Object obj) {
-               Gtk.TextIter start;
-               Gtk.TextIter end;     
-               this.el.get_bounds (out start, out end);
+            var attrs = new GtkSource.MarkAttributes();
+            var  pink =   Gdk.RGBA();
+            pink.parse ( "pink");
+            attrs.set_background ( pink);
+            attrs.set_icon_name ( "process-stop");    
+            attrs.query_tooltip_text.connect(( mark) => {
+                 GLib.debug("tooltip query? %s", mark.name);
+                return strdup( mark.name);
+            });
+             attrs.query_tooltip_markup.connect(( mark) => {
+                 GLib.debug("tooltip query? %s", mark.name);
+                return strdup( mark.name);
+            });
+            this.el.set_mark_attributes ("ERR", attrs, 1);
+            attrs.ref();
+             var wattrs = new GtkSource.MarkAttributes();
+            var  blue =   Gdk.RGBA();
+            blue.parse ( "#ABF4EB");
+            wattrs.set_background ( blue);
+            wattrs.set_icon_name ( "process-stop");    
+            wattrs.query_tooltip_text.connect(( mark) => {
+                 GLib.debug("tooltip query? %s", mark.name);
+                return strdup(mark.name);
+            });
+            wattrs.query_tooltip_markup.connect(( mark) => {
+                 GLib.debug("tooltip query? %s", mark.name);
+                return strdup(mark.name);
+            });
+            this.el.set_mark_attributes ("WARN", wattrs, 1);
+            wattrs.ref();
             
-               this.el.remove_source_marks (start, end, type);
-               GLib.debug("highlight errors");          
             
-                // we should highlight other types of errors..
+             var dattrs = new GtkSource.MarkAttributes();
+            var  purple =   Gdk.RGBA();
+            purple.parse ( "#EEA9FF");
+            dattrs.set_background ( purple);
+            dattrs.set_icon_name ( "process-stop");    
+            dattrs.query_tooltip_text.connect(( mark) => {
+               GLib.debug("tooltip query? %s", mark.name);
+                return strdup(mark.name);
+            });
+            dattrs.query_tooltip_markup.connect(( mark) => {
+               GLib.debug("tooltip query? %s", mark.name);
+                return strdup(mark.name);
+            });
+            this.el.set_mark_attributes ("DEPR", dattrs, 1);
+            dattrs.ref();    
             
-               if (!obj.has_member(type)) {
-                       GLib.debug("Return has no errors\n");
-                       return true;
-               }
+             this.el.get_space_drawer().set_matrix(null);
+             this.el.get_space_drawer().set_types_for_locations( 
+               GtkSource.SpaceLocationFlags.ALL,
+               GtkSource.SpaceTypeFlags.ALL
+            );
+            this.el.get_space_drawer().set_enable_matrix(true);
+            /*
+            Gtk.SourceDrawSpacesFlags.LEADING + 
+            Gtk.SourceDrawSpacesFlags.TRAILING + 
+            Gtk.SourceDrawSpacesFlags.TAB + 
+            Gtk.SourceDrawSpacesFlags.SPACE
+            */
+
+            //listeners
+            this.el.query_tooltip.connect( (x, y, keyboard_tooltip, tooltip) => {
+               
+               //GLib.debug("query tooltip");
+               Gtk.TextIter iter;
+               int trailing;
+               
+               var yoff = (int) _this.RightEditor.el.vadjustment.value;
+               
+               // I think this is problematic - if it's compliing  / updating at same time as query.
+               
+               //if (_this.window.statusbar_compile_spinner.el.spinning) {
+               //      return false;
+               //}
+               
+               this.el.get_iter_at_position (out iter, out trailing,  x,  y + yoff);
+                
+               var l = iter.get_line();
             
-               if (_this.window.windowstate.state != WindowState.State.CODEONLY 
-                       &&
-                       _this.window.windowstate.state != WindowState.State.CODE
-                       ) {
-                       GLib.debug("windowstate != CODEONLY?");
-                       
-                       return true;
-               } 
+               
+                
+               // GLib.debug("query tooltip line %d", (int) l);
+               if (l < 0) {
             
-               //this.marks = new Gee.HashMap<int,string>();
-               var err = obj.get_object_member(type);
-             
-               if (_this.file == null) {
-                       GLib.debug("file is null?");
+                       return false;
+               }
+               /*
+               if (_this.buffer.marks != null && _this.buffer.marks.has_key(l)) {
+                       GLib.debug("line %d setting tip to %s", l,  _this.buffer.marks.get(l));
+                       tooltip.set_text(_this.buffer.marks.get(l).dup());
                        return true;
-            
                }
-               var valafn = _this.file.path;
-            
-               if (_this.file.xtype != "PlainFile") {
-            
-                       valafn = "";
-                       try {             
-                               var  regex = new Regex("\\.bjs$");
-                               // should not happen
-                               valafn = regex.replace(_this.file.path,_this.file.path.length , 0 , ".vala");
-                       } catch (GLib.RegexError e) {
-                               return true;
-                       }   
-            
-            
-            
+             
+               return false;
+               */
+               
+                 
+               // this crashes?? - not sure why.
+               var marks = _this.buffer.el.get_source_marks_at_line(l, "ERR");
+               if (marks.is_empty()) {
+                       marks = _this.buffer.el.get_source_marks_at_line(l, "WARN");
                }
-               if (!err.has_member(valafn)) {
-                       GLib.debug("File path has no errors");
-                       return  true;
+               if (marks.is_empty()) {
+                       marks = _this.buffer.el.get_source_marks_at_line(l, "DEPR");
                }
-            
-               var lines = err.get_object_member(valafn);
                
-               var offset = 1;
-               if (obj.has_member("line_offset")) { // ?? why??
-                       offset = (int)obj.get_int_member("line_offset") + 1;
+               // GLib.debug("query tooltip line %d marks %d", (int)l, (int) marks.length());
+               var str = "";
+               marks.@foreach((m) => { 
+                       //GLib.debug("got mark %s", m.name);
+                       str += (str.length > 0 ? "\n" : "") + m.category + ": " + m.name;
+               });
+               // true if there is a mark..
+               if (str.length > 0 ) {
+                       tooltip.set_text( str );
                }
+               return str.length > 0 ? true : false;
+                
+            });
+        }
+
+        // user defined functions
+        public void load (string str) {
+        
+        // show the help page for the active node..
+           //this.get('/Help').show();
+         
+          // this.get('/BottomPane').el.set_current_page(0);
+               GLib.debug("load called - Reset undo buffer");
+               
+            var buf = (GtkSource.Buffer)this.el.get_buffer();
+            buf.begin_irreversible_action();
+            buf.set_text(str, str.length);
+            buf.end_irreversible_action();
+            
+            var lm = GtkSource.LanguageManager.get_default();
+            var lang = "vala";
+            if (_this.file != null) {
+                 lang = _this.file.language;
+            }
+            print("lang=%s, content_type = %s\n", lang, _this.file.content_type);
+            var lg = _this.file.content_type.length > 0  ?
+                    lm.guess_language(_this.file.path, _this.file.content_type) :
+                    lm.get_language(lang);
+             
+           
+            ((GtkSource.Buffer)(this.el.get_buffer())) .set_language(lg); 
+        
+            this.el.insert_spaces_instead_of_tabs = true;
+            if (lg != null) {
+                       print("sourcelanguage  = %s\n", lg.name);
+                       if (lg.name == "Vala") {
+                           this.el.insert_spaces_instead_of_tabs = false;
+                       }
+             }
+            _this.dirty = false;
+            this.el.grab_focus();
+            _this.save_button.el.sensitive = false;
+        }
+    }
+    public class Xcls_buffer : Object
+    {
+        public GtkSource.Buffer el;
+        private Editor  _this;
+
+
+            // my vars (def)
+        public int error_line;
+        public Gee.HashMap<int,string>? xmarks;
+        public bool check_queued;
+
+        // ctor
+        public Xcls_buffer(Editor _owner )
+        {
+            _this = _owner;
+            _this.buffer = this;
+            this.el = new GtkSource.Buffer( null );
+
+            // my vars (dec)
+            this.error_line = -1;
+            this.xmarks = null;
+            this.check_queued = false;
+
+            // set gobject values
+            this.el.enable_undo = true;
+
+            //listeners
+            this.el.changed.connect( () => {
+                // check syntax??
+                // ??needed..??
+                _this.save_button.el.sensitive = true;
+                print("EDITOR CHANGED");
+                this.checkSyntax();
+               
+                _this.dirty = true;
             
+                // this.get('/LeftPanel.model').changed(  str , false);
+                return ;
+            });
+        }
+
+        // user defined functions
+        public bool checkSyntax () {
+         
             
-               var tlines = this.el.get_line_count () +1;
-               
-               if (_this.prop != null) {
-               
-                       tlines = _this.prop.end_line + 1;
-                       offset = _this.prop.start_line + 1;
-               
-               }
-               
+            var str = this.toString();
             
+            // needed???
+            if (this.error_line > 0) {
+                 Gtk.TextIter start;
+                 Gtk.TextIter end;     
+                this.el.get_bounds (out start, out end);
+        
+                this.el.remove_source_marks (start, end, null);
+            }
+            if (str.length < 1) {
+                print("checkSyntax - empty string?\n");
+                return true;
+            }
             
-               lines.foreach_member((obj, line, node) => {
-                       
-                    Gtk.TextIter iter;
-            //        print("get inter\n");
-                   var eline = int.parse(line) - offset;
-                   GLib.debug("GOT ERROR on line %s -- converted to %d  (offset = %d)\n", line,eline, offset);
-                   
-                   
-                   if (eline > tlines || eline < 0) {
-                       return;
-                   }
-                  
-                   
-                   this.el.get_iter_at_line( out iter, eline);
-                   //print("mark line\n");
-                   var msg  = "";
-                   var ar = lines.get_array_member(line);
-                   for (var i = 0 ; i < ar.get_length(); i++) {
-                       if (ar.get_string_element(i) == "Success") {
-                               continue;
-                               }
-                               msg += (msg.length > 0) ? "\n" : "";
-                               msg += ar.get_string_element(i);
-                       }
-                       if (msg == "") {
-                               return;
-                       }
-                       msg = "Line: %d".printf(eline+1) +  " " + msg;
-                   this.el.create_source_mark(msg, type, iter);
-                   GLib.debug("set line %d to %m", eline, msg);
-                  // this.marks.set(eline, msg);
-               } );
-               return false;
+            // bit presumptiona
+            if (_this.file.xtype == "PlainFile") {
             
+                // assume it's gtk...
+                 var  oldcode =_this.file.toSource();
+                _this.file.setSource(str);
+                _this.file.getLanguageServer().document_change(_this.file);
+                _this.file.setSource(oldcode);
+                
+                        
+                return true;
             
+            }
+           if (_this.file == null) {
+               return true;
+           }
+         
             
+        
+              
+             
+            GLib.debug("calling validate");    
+            // clear the buttons.
+               if (_this.prop.name == "xns" || _this.prop.name == "xtype") {
+                       return true ;
+               }
+               var oldcode  = _this.prop.val;
+               
+               _this.prop.val = str;
+            _this.file.getLanguageServer().document_change(_this.file);
+            _this.prop.val = oldcode;
+            
+            
+            //print("done mark line\n");
+             
+            return true; // at present allow saving - even if it's invalid..
+        }
+        public bool highlightErrorsJson (string type, Json.Object obj) {
+               Gtk.TextIter start;
+               Gtk.TextIter end;     
+               this.el.get_bounds (out start, out end);
+        
+               this.el.remove_source_marks (start, end, type);
+               GLib.debug("highlight errors");          
+        
+                // we should highlight other types of errors..
+        
+               if (!obj.has_member(type)) {
+                       GLib.debug("Return has no errors\n");
+                       return true;
+               }
+        
+               if (_this.window.windowstate.state != WindowState.State.CODEONLY 
+                       &&
+                       _this.window.windowstate.state != WindowState.State.CODE
+                       ) {
+                       GLib.debug("windowstate != CODEONLY?");
+                       
+                       return true;
+               } 
+        
+               //this.marks = new Gee.HashMap<int,string>();
+               var err = obj.get_object_member(type);
+         
+               if (_this.file == null) {
+                       GLib.debug("file is null?");
+                       return true;
+        
+               }
+               var valafn = _this.file.path;
+        
+               if (_this.file.xtype != "PlainFile") {
+        
+                       valafn = "";
+                       try {             
+                               var  regex = new Regex("\\.bjs$");
+                               // should not happen
+                               valafn = regex.replace(_this.file.path,_this.file.path.length , 0 , ".vala");
+                       } catch (GLib.RegexError e) {
+                               return true;
+                       }   
+        
+        
+        
+               }
+               if (!err.has_member(valafn)) {
+                       GLib.debug("File path has no errors");
+                       return  true;
+               }
+        
+               var lines = err.get_object_member(valafn);
+               
+               var offset = 1;
+               if (obj.has_member("line_offset")) { // ?? why??
+                       offset = (int)obj.get_int_member("line_offset") + 1;
+               }
+        
+        
+               var tlines = this.el.get_line_count () +1;
+               
+               if (_this.prop != null) {
+               
+                       tlines = _this.prop.end_line + 1;
+                       offset = _this.prop.start_line + 1;
+               
+               }
+               
+        
+        
+               lines.foreach_member((obj, line, node) => {
+                       
+                    Gtk.TextIter iter;
+        //        print("get inter\n");
+                   var eline = int.parse(line) - offset;
+                   GLib.debug("GOT ERROR on line %s -- converted to %d  (offset = %d)\n", line,eline, offset);
+                   
+                   
+                   if (eline > tlines || eline < 0) {
+                       return;
+                   }
+                  
+                   
+                   this.el.get_iter_at_line( out iter, eline);
+                   //print("mark line\n");
+                   var msg  = "";
+                   var ar = lines.get_array_member(line);
+                   for (var i = 0 ; i < ar.get_length(); i++) {
+                       if (ar.get_string_element(i) == "Success") {
+                               continue;
+                       }
+                               msg += (msg.length > 0) ? "\n" : "";
+                               msg += ar.get_string_element(i);
+                       }
+                       if (msg == "") {
+                               return;
+                       }
+                       msg = "Line: %d".printf(eline+1) +  " " + msg;
+                   this.el.create_source_mark(msg, type, iter);
+                   GLib.debug("set line %d to %m", eline, msg);
+                  // this.marks.set(eline, msg);
+               } );
+               return false;
+        
+        
+        
+        
+        
+               }
+        public bool highlightErrors ( Gee.HashMap<int,string> validate_res) {
+                 
+               this.error_line = validate_res.size;
+        
+               if (this.error_line < 1) {
+                       return true;
+               }
+               var tlines = this.el.get_line_count ();
+               Gtk.TextIter iter;
+               var valiter = validate_res.map_iterator();
+               while (valiter.next()) {
+        
+               //        print("get inter\n");
+                       var eline = valiter.get_key();
+                       if (eline > tlines) {
+                               continue;
+                       }
+                       this.el.get_iter_at_line( out iter, eline);
+                       //print("mark line\n");
+                       this.el.create_source_mark(valiter.get_value(), "ERR", iter);
+               }   
+               return false;
+        }
+        public string toString () {
             
+            Gtk.TextIter s;
+            Gtk.TextIter e;
+            this.el.get_start_iter(out s);
+            this.el.get_end_iter(out e);
+            var ret = this.el.get_text(s,e,true);
+            //print("TO STRING? " + ret);
+            return ret;
+        }
+    }
+
+    public class Xcls_EventControllerKey11 : Object
+    {
+        public Gtk.EventControllerKey el;
+        private Editor  _this;
+
+
+            // my vars (def)
+
+        // ctor
+        public Xcls_EventControllerKey11(Editor _owner )
+        {
+            _this = _owner;
+            this.el = new Gtk.EventControllerKey();
+
+            // my vars (dec)
+
+            // set gobject values
+
+            //listeners
+            this.el.key_released.connect( (keyval, keycode, state) => {
             
+              
+                if (keyval == Gdk.Key.s && (state & Gdk.ModifierType.CONTROL_MASK ) > 0 ) {
+                    GLib.debug("SAVE: ctrl-S  pressed");
+                    _this.saveContents();
+                    return;
+                }
+                
+                if (keyval == Gdk.Key.g && (state & Gdk.ModifierType.CONTROL_MASK ) > 0 ) {
+                   GLib.debug("SAVE: ctrl-g  pressed");
+                       _this.forwardSearch(true);
+                   return;
                }
-            public bool highlightErrors ( Gee.HashMap<int,string> validate_res) {
-                     
-               this.error_line = validate_res.size;
-            
-               if (this.error_line < 1) {
-                       return true;
+               if (keyval == Gdk.Key.f && (state & Gdk.ModifierType.CONTROL_MASK ) > 0 ) {
+                   GLib.debug("SAVE: ctrl-f  pressed");
+                       _this.search_entry.el.grab_focus();
+                   return;
                }
-               var tlines = this.el.get_line_count ();
-               Gtk.TextIter iter;
-               var valiter = validate_res.map_iterator();
-               while (valiter.next()) {
-            
-               //        print("get inter\n");
-                       var eline = valiter.get_key();
-                       if (eline > tlines) {
-                               continue;
-                       }
-                       this.el.get_iter_at_line( out iter, eline);
-                       //print("mark line\n");
-                       this.el.create_source_mark(valiter.get_value(), "ERR", iter);
-               }   
-               return false;
-            }
-            public string toString () {
+                //_this.view.el.show_completion();
+               // print(event.key.keyval)
                 
-                Gtk.TextIter s;
-                Gtk.TextIter e;
-                this.el.get_start_iter(out s);
-                this.el.get_end_iter(out e);
-                var ret = this.el.get_text(s,e,true);
-                //print("TO STRING? " + ret);
-                return ret;
-            }
+                return;
+             
+             
+            });
         }
 
-        public class Xcls_EventControllerKey11 : Object
-        {
-            public Gtk.EventControllerKey el;
-            private Editor  _this;
+        // user defined functions
+    }
 
 
-                // my vars (def)
 
-            // ctor
-            public Xcls_EventControllerKey11(Editor _owner )
-            {
-                _this = _owner;
-                this.el = new Gtk.EventControllerKey();
+    public class Xcls_Box12 : Object
+    {
+        public Gtk.Box el;
+        private Editor  _this;
 
-                // my vars (dec)
 
-                // set gobject values
+            // my vars (def)
 
-                //listeners
-                this.el.key_released.connect( (keyval, keycode, state) => {
-                
-                  
-                    if (keyval == Gdk.Key.s && (state & Gdk.ModifierType.CONTROL_MASK ) > 0 ) {
-                        GLib.debug("SAVE: ctrl-S  pressed");
-                        _this.saveContents();
-                        return;
-                    }
-                    
-                    if (keyval == Gdk.Key.g && (state & Gdk.ModifierType.CONTROL_MASK ) > 0 ) {
-                           GLib.debug("SAVE: ctrl-g  pressed");
-                               _this.forwardSearch(true);
-                           return;
-                       }
-                       if (keyval == Gdk.Key.f && (state & Gdk.ModifierType.CONTROL_MASK ) > 0 ) {
-                           GLib.debug("SAVE: ctrl-f  pressed");
-                               _this.search_entry.el.grab_focus();
-                           return;
-                       }
-                    
-                   // print(event.key.keyval)
-                    
-                    return;
-                 
-                 
-                });
-            }
+        // ctor
+        public Xcls_Box12(Editor _owner )
+        {
+            _this = _owner;
+            this.el = new Gtk.Box( Gtk.Orientation.HORIZONTAL, 0 );
+
+            // my vars (dec)
 
-            // user defined functions
+            // set gobject values
+            this.el.homogeneous = false;
+            this.el.vexpand = false;
+            var child_1 = new Xcls_search_entry( _this );
+            child_1.ref();
+            this.el.append( child_1.el );
+            var child_2 = new Xcls_search_results( _this );
+            child_2.ref();
+            this.el.append( child_2.el );
+            var child_3 = new Xcls_nextBtn( _this );
+            child_3.ref();
+            this.el.append( child_3.el );
+            var child_4 = new Xcls_backBtn( _this );
+            child_4.ref();
+            this.el.append( child_4.el );
+            var child_5 = new Xcls_MenuButton18( _this );
+            child_5.ref();
+            this.el.append( child_5.el );
         }
 
+        // user defined functions
+    }
+    public class Xcls_search_entry : Object
+    {
+        public Gtk.SearchEntry el;
+        private Editor  _this;
+
 
+            // my vars (def)
+        public Gtk.CssProvider css;
 
-        public class Xcls_Box12 : Object
+        // ctor
+        public Xcls_search_entry(Editor _owner )
         {
-            public Gtk.Box el;
-            private Editor  _this;
+            _this = _owner;
+            _this.search_entry = this;
+            this.el = new Gtk.SearchEntry();
 
+            // my vars (dec)
 
-                // my vars (def)
+            // set gobject values
+            this.el.name = "editor-search-entry";
+            this.el.hexpand = true;
+            this.el.placeholder_text = "Press enter to search";
+            this.el.search_delay = 3;
+            var child_1 = new Xcls_EventControllerKey14( _this );
+            child_1.ref();
+            this.el.add_controller(  child_1.el );
 
-            // ctor
-            public Xcls_Box12(Editor _owner )
-            {
-                _this = _owner;
-                this.el = new Gtk.Box( Gtk.Orientation.HORIZONTAL, 0 );
-
-                // my vars (dec)
-
-                // set gobject values
-                this.el.homogeneous = false;
-                this.el.vexpand = false;
-                new Xcls_search_entry( _this );
-                this.el.append( _this.search_entry.el );
-                new Xcls_search_results( _this );
-                this.el.append( _this.search_results.el );
-                new Xcls_nextBtn( _this );
-                this.el.append( _this.nextBtn.el );
-                new Xcls_backBtn( _this );
-                this.el.append( _this.backBtn.el );
-                var child_5 = new Xcls_MenuButton18( _this );
-                child_5.ref();
-                this.el.append( child_5.el );
-            }
+            //listeners
+            this.el.search_changed.connect( ( ) => {
+            
+            _this.search(_this.search_entry.el.text);
+                _this.search_results.updateResults();
+            
+               GLib.Timeout.add_seconds(1,() => {
+                        _this.search_results.updateResults();
+                        return false;
+                });
+            });
+        }
 
-            // user defined functions
+        // user defined functions
+        public void forwardSearch (bool change_focus) {
+        
+        
+               _this.forwardSearch(change_focus);
+        
+        /*
+        
+               switch(_this.windowstate.state) {
+                       case WindowState.State.CODEONLY:
+                       //case WindowState.State.CODE:
+                               // search the code being edited..
+                               _this.windowstate.code_editor_tab.forwardSearch(change_focus);
+                                
+                               break;
+                       case WindowState.State.PREVIEW:
+                               if (_this.windowstate.file.xtype == "Gtk") {
+                                       _this.windowstate.window_gladeview.forwardSearch(change_focus);
+                               } else { 
+                                        _this.windowstate.window_rooview.forwardSearch(change_focus);
+                               }
+                       
+                               break;
+               }
+               */
+               
         }
-        public class Xcls_search_entry : Object
-        {
-            public Gtk.SearchEntry el;
-            private Editor  _this;
+    }
+    public class Xcls_EventControllerKey14 : Object
+    {
+        public Gtk.EventControllerKey el;
+        private Editor  _this;
 
 
-                // my vars (def)
-            public Gtk.CssProvider css;
+            // my vars (def)
 
-            // ctor
-            public Xcls_search_entry(Editor _owner )
-            {
-                _this = _owner;
-                _this.search_entry = this;
-                this.el = new Gtk.SearchEntry();
-
-                // my vars (dec)
-
-                // set gobject values
-                this.el.name = "editor-search-entry";
-                this.el.hexpand = true;
-                this.el.placeholder_text = "Press enter to search";
-                this.el.search_delay = 3;
-                var child_1 = new Xcls_EventControllerKey14( _this );
-                child_1.ref();
-                this.el.add_controller(  child_1.el );
-
-                //listeners
-                this.el.search_changed.connect( ( ) => {
-                
-                _this.search(_this.search_entry.el.text);
-                        _this.search_results.updateResults();
-                
-                       GLib.Timeout.add_seconds(1,() => {
-                                _this.search_results.updateResults();
-                                return false;
-                        });
-                });
-            }
+        // ctor
+        public Xcls_EventControllerKey14(Editor _owner )
+        {
+            _this = _owner;
+            this.el = new Gtk.EventControllerKey();
 
-            // user defined functions
-            public void forwardSearch (bool change_focus) {
-            
-            
-               _this.forwardSearch(change_focus);
-            
-            /*
+            // my vars (dec)
+
+            // set gobject values
+
+            //listeners
+            this.el.key_pressed.connect( (keyval, keycode, state) => {
             
-               switch(_this.windowstate.state) {
-                       case WindowState.State.CODEONLY:
-                       //case WindowState.State.CODE:
-                               // search the code being edited..
-                               _this.windowstate.code_editor_tab.forwardSearch(change_focus);
-                                
-                               break;
-                       case WindowState.State.PREVIEW:
-                               if (_this.windowstate.file.xtype == "Gtk") {
-                                       _this.windowstate.window_gladeview.forwardSearch(change_focus);
-                               } else { 
-                                        _this.windowstate.window_rooview.forwardSearch(change_focus);
-                               }
-                       
-                               break;
+               if (keyval == Gdk.Key.g && (state & Gdk.ModifierType.CONTROL_MASK ) > 0 ) {
+                   GLib.debug("SAVE: ctrl-g  pressed");
+                       _this.forwardSearch(true);
+                   return true;
                }
-               */
-               
-            }
+                
+              
+               if (keyval == Gdk.Key.Return && _this.search_entry.el.text.length > 0) {
+                       _this.forwardSearch(true);
+                       
+                       
+                   return true;
+            
+               }    
+               // print(event.key.keyval)
+               
+                return false;
+            });
         }
-        public class Xcls_EventControllerKey14 : Object
-        {
-            public Gtk.EventControllerKey el;
-            private Editor  _this;
 
+        // user defined functions
+    }
 
-                // my vars (def)
 
-            // ctor
-            public Xcls_EventControllerKey14(Editor _owner )
-            {
-                _this = _owner;
-                this.el = new Gtk.EventControllerKey();
+    public class Xcls_search_results : Object
+    {
+        public Gtk.Label el;
+        private Editor  _this;
 
-                // my vars (dec)
 
-                // set gobject values
+            // my vars (def)
 
-                //listeners
-                this.el.key_pressed.connect( (keyval, keycode, state) => {
-                
-                       if (keyval == Gdk.Key.g && (state & Gdk.ModifierType.CONTROL_MASK ) > 0 ) {
-                           GLib.debug("SAVE: ctrl-g  pressed");
-                               _this.forwardSearch(true);
-                           return true;
-                       }
-                    
-                  
-                       if (keyval == Gdk.Key.Return && _this.search_entry.el.text.length > 0) {
-                               _this.forwardSearch(true);
-                               
-                               
-                           return true;
-                
-                       }    
-                   // print(event.key.keyval)
-                   
-                    return false;
-                });
-            }
+        // ctor
+        public Xcls_search_results(Editor _owner )
+        {
+            _this = _owner;
+            _this.search_results = this;
+            this.el = new Gtk.Label( "No Results" );
+
+            // my vars (dec)
 
-            // user defined functions
+            // set gobject values
+            this.el.margin_end = 4;
+            this.el.margin_start = 4;
         }
 
+        // user defined functions
+        public void updateResults () {
+               this.el.visible = true;
+               
+               var res = _this.searchcontext.get_occurrences_count();
+               if (res < 0) {
+                       _this.search_results.el.label = "??? Matches";          
+                       return;
+               }
+        
+               _this.nextBtn.el.sensitive = false;
+               _this.backBtn.el.sensitive = false;     
+        
+               if (res > 0) {
+                       _this.search_results.el.label = "%d Matches".printf(res);
+                       _this.nextBtn.el.sensitive = true;
+                       _this.backBtn.el.sensitive = true;
+                       return;
+               } 
+               _this.search_results.el.label = "No Matches";
+               
+        }
+    }
 
-        public class Xcls_search_results : Object
-        {
-            public Gtk.Label el;
-            private Editor  _this;
+    public class Xcls_nextBtn : Object
+    {
+        public Gtk.Button el;
+        private Editor  _this;
 
 
-                // my vars (def)
+            // my vars (def)
+        public bool always_show_image;
 
-            // ctor
-            public Xcls_search_results(Editor _owner )
-            {
-                _this = _owner;
-                _this.search_results = this;
-                this.el = new Gtk.Label( "No Results" );
+        // ctor
+        public Xcls_nextBtn(Editor _owner )
+        {
+            _this = _owner;
+            _this.nextBtn = this;
+            this.el = new Gtk.Button();
 
-                // my vars (dec)
+            // my vars (dec)
+            this.always_show_image = true;
 
-                // set gobject values
-                this.el.margin_end = 4;
-                this.el.margin_start = 4;
-            }
+            // set gobject values
+            this.el.icon_name = "go-down";
+            this.el.sensitive = false;
 
-            // user defined functions
-            public void updateResults () {
-               this.el.visible = true;
-               
-               var res = _this.searchcontext.get_occurrences_count();
-               if (res < 0) {
-                       _this.search_results.el.label = "??? Matches";          
-                       return;
-               }
+            //listeners
+            this.el.clicked.connect( (event) => {
             
-               _this.nextBtn.el.sensitive = false;
-               _this.backBtn.el.sensitive = false;     
-            
-               if (res > 0) {
-                       _this.search_results.el.label = "%d Matches".printf(res);
-                       _this.nextBtn.el.sensitive = true;
-                       _this.backBtn.el.sensitive = true;
-                       return;
-               } 
-               _this.search_results.el.label = "No Matches";
+               _this.forwardSearch(true);
                
-            }
+                
+            });
         }
 
-        public class Xcls_nextBtn : Object
-        {
-            public Gtk.Button el;
-            private Editor  _this;
+        // user defined functions
+    }
 
+    public class Xcls_backBtn : Object
+    {
+        public Gtk.Button el;
+        private Editor  _this;
 
-                // my vars (def)
-            public bool always_show_image;
 
-            // ctor
-            public Xcls_nextBtn(Editor _owner )
-            {
-                _this = _owner;
-                _this.nextBtn = this;
-                this.el = new Gtk.Button();
+            // my vars (def)
+        public bool always_show_image;
 
-                // my vars (dec)
-                this.always_show_image = true;
+        // ctor
+        public Xcls_backBtn(Editor _owner )
+        {
+            _this = _owner;
+            _this.backBtn = this;
+            this.el = new Gtk.Button();
 
-                // set gobject values
-                this.el.icon_name = "go-down";
-                this.el.sensitive = false;
+            // my vars (dec)
+            this.always_show_image = true;
 
-                //listeners
-                this.el.clicked.connect( (event) => {
-                
-                       _this.forwardSearch(true);
-                       
-                        
-                });
-            }
+            // set gobject values
+            this.el.icon_name = "go-up";
+            this.el.sensitive = false;
 
-            // user defined functions
+            //listeners
+            this.el.clicked.connect( (event) => {
+            
+               _this.backSearch(true);
+                
+            });
         }
 
-        public class Xcls_backBtn : Object
-        {
-            public Gtk.Button el;
-            private Editor  _this;
-
+        // user defined functions
+    }
 
-                // my vars (def)
-            public bool always_show_image;
+    public class Xcls_MenuButton18 : Object
+    {
+        public Gtk.MenuButton el;
+        private Editor  _this;
 
-            // ctor
-            public Xcls_backBtn(Editor _owner )
-            {
-                _this = _owner;
-                _this.backBtn = this;
-                this.el = new Gtk.Button();
 
-                // my vars (dec)
-                this.always_show_image = true;
+            // my vars (def)
+        public bool always_show_image;
 
-                // set gobject values
-                this.el.icon_name = "go-up";
-                this.el.sensitive = false;
+        // ctor
+        public Xcls_MenuButton18(Editor _owner )
+        {
+            _this = _owner;
+            this.el = new Gtk.MenuButton();
 
-                //listeners
-                this.el.clicked.connect( (event) => {
-                
-                       _this.backSearch(true);
-                        
-                });
-            }
+            // my vars (dec)
+            this.always_show_image = true;
 
-            // user defined functions
+            // set gobject values
+            this.el.icon_name = "emblem-system";
+            this.el.always_show_arrow = true;
+            var child_1 = new Xcls_search_settings( _this );
+            child_1.ref();
+            this.el.popover = child_1.el;
         }
 
-        public class Xcls_MenuButton18 : Object
-        {
-            public Gtk.MenuButton el;
-            private Editor  _this;
-
+        // user defined functions
+    }
+    public class Xcls_search_settings : Object
+    {
+        public Gtk.Popover el;
+        private Editor  _this;
 
-                // my vars (def)
-            public bool always_show_image;
 
-            // ctor
-            public Xcls_MenuButton18(Editor _owner )
-            {
-                _this = _owner;
-                this.el = new Gtk.MenuButton();
+            // my vars (def)
 
-                // my vars (dec)
-                this.always_show_image = true;
+        // ctor
+        public Xcls_search_settings(Editor _owner )
+        {
+            _this = _owner;
+            _this.search_settings = this;
+            this.el = new Gtk.Popover();
 
-                // set gobject values
-                this.el.icon_name = "emblem-system";
-                this.el.always_show_arrow = true;
-                new Xcls_search_settings( _this );
-                this.el.popover = _this.search_settings.el;
-            }
+            // my vars (dec)
 
-            // user defined functions
+            // set gobject values
+            var child_1 = new Xcls_Box20( _this );
+            child_1.ref();
+            this.el.child = child_1.el;
         }
-        public class Xcls_search_settings : Object
-        {
-            public Gtk.Popover el;
-            private Editor  _this;
 
+        // user defined functions
+    }
+    public class Xcls_Box20 : Object
+    {
+        public Gtk.Box el;
+        private Editor  _this;
 
-                // my vars (def)
 
-            // ctor
-            public Xcls_search_settings(Editor _owner )
-            {
-                _this = _owner;
-                _this.search_settings = this;
-                this.el = new Gtk.Popover();
+            // my vars (def)
 
-                // my vars (dec)
+        // ctor
+        public Xcls_Box20(Editor _owner )
+        {
+            _this = _owner;
+            this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
 
-                // set gobject values
-                var child_1 = new Xcls_Box20( _this );
-                this.el.child = child_1.el;
-            }
+            // my vars (dec)
 
-            // user defined functions
+            // set gobject values
+            var child_1 = new Xcls_case_sensitive( _this );
+            child_1.ref();
+            this.el.append( child_1.el );
+            var child_2 = new Xcls_regex( _this );
+            child_2.ref();
+            this.el.append( child_2.el );
+            var child_3 = new Xcls_multiline( _this );
+            child_3.ref();
+            this.el.append( child_3.el );
         }
-        public class Xcls_Box20 : Object
-        {
-            public Gtk.Box el;
-            private Editor  _this;
 
+        // user defined functions
+    }
+    public class Xcls_case_sensitive : Object
+    {
+        public Gtk.CheckButton el;
+        private Editor  _this;
 
-                // my vars (def)
 
-            // ctor
-            public Xcls_Box20(Editor _owner )
-            {
-                _this = _owner;
-                this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
-
-                // my vars (dec)
-
-                // set gobject values
-                new Xcls_case_sensitive( _this );
-                this.el.append( _this.case_sensitive.el );
-                new Xcls_regex( _this );
-                this.el.append( _this.regex.el );
-                new Xcls_multiline( _this );
-                this.el.append( _this.multiline.el );
-            }
+            // my vars (def)
 
-            // user defined functions
-        }
-        public class Xcls_case_sensitive : Object
+        // ctor
+        public Xcls_case_sensitive(Editor _owner )
         {
-            public Gtk.CheckButton el;
-            private Editor  _this;
+            _this = _owner;
+            _this.case_sensitive = this;
+            this.el = new Gtk.CheckButton();
 
+            // my vars (dec)
 
-                // my vars (def)
-
-            // ctor
-            public Xcls_case_sensitive(Editor _owner )
-            {
-                _this = _owner;
-                _this.case_sensitive = this;
-                this.el = new Gtk.CheckButton();
-
-                // my vars (dec)
-
-                // set gobject values
-                this.el.label = "Case Sensitive";
+            // set gobject values
+            this.el.label = "Case Sensitive";
 
-                // init method
+            // init method
 
-                {
-                       this.el.show();
-                }
+            {
+               this.el.show();
             }
-
-            // user defined functions
         }
 
-        public class Xcls_regex : Object
-        {
-            public Gtk.CheckButton el;
-            private Editor  _this;
+        // user defined functions
+    }
 
+    public class Xcls_regex : Object
+    {
+        public Gtk.CheckButton el;
+        private Editor  _this;
 
-                // my vars (def)
 
-            // ctor
-            public Xcls_regex(Editor _owner )
-            {
-                _this = _owner;
-                _this.regex = this;
-                this.el = new Gtk.CheckButton();
+            // my vars (def)
 
-                // my vars (dec)
+        // ctor
+        public Xcls_regex(Editor _owner )
+        {
+            _this = _owner;
+            _this.regex = this;
+            this.el = new Gtk.CheckButton();
+
+            // my vars (dec)
 
-                // set gobject values
-                this.el.label = "Regex";
+            // set gobject values
+            this.el.label = "Regex";
 
-                // init method
+            // init method
 
-                {
-                       this.el.show();
-                }
+            {
+               this.el.show();
             }
-
-            // user defined functions
         }
 
-        public class Xcls_multiline : Object
-        {
-            public Gtk.CheckButton el;
-            private Editor  _this;
+        // user defined functions
+    }
 
+    public class Xcls_multiline : Object
+    {
+        public Gtk.CheckButton el;
+        private Editor  _this;
 
-                // my vars (def)
 
-            // ctor
-            public Xcls_multiline(Editor _owner )
-            {
-                _this = _owner;
-                _this.multiline = this;
-                this.el = new Gtk.CheckButton();
+            // my vars (def)
 
-                // my vars (dec)
+        // ctor
+        public Xcls_multiline(Editor _owner )
+        {
+            _this = _owner;
+            _this.multiline = this;
+            this.el = new Gtk.CheckButton();
 
-                // set gobject values
-                this.el.label = "Multi-line (add \\n)";
-            }
+            // my vars (dec)
 
-            // user defined functions
+            // set gobject values
+            this.el.label = "Multi-line (add \\n)";
         }
 
+        // user defined functions
+    }
 
 
 
 
-    }
+
+}
index 4739c61..b7cb936 100644 (file)
@@ -194,14 +194,17 @@ public class FakeServerCache : Object
 
 public class FakeServer : Object
 {
-       WebKit.WebView view;
+       //WebKit.WebView view;
        
+       static WebKit.WebContext cx = null;
        public FakeServer(WebKit.WebView wkview)
        {
-               this.view = wkview;
-               
+               //this.view = wkview;
+               if (cx != null) {
+                       return;
+               }
                 
-               var cx = WebKit.WebContext.get_default();
+                cx = WebKit.WebContext.get_default();
                //var cx = this.view.get_context();
                cx.register_uri_scheme("xhttp",  serve);
                cx.register_uri_scheme("resources",  serve);
index 3e9a975..5d63044 100644 (file)
             "}",
             ""
            ],
-           "| void highlightErrorsJson" : [
-            " (string type, Json.Object obj) {",
-            "      Gtk.TextIter start;",
-            "     Gtk.TextIter end;   ",
-            "     ",
-            "     var buf =  this.el.get_buffer();",
-            "       var sbuf = (GtkSource.Buffer)buf;",
-            "        buf.get_bounds (out start, out end);",
-            "        ",
-            "        sbuf.remove_source_marks (start, end, type);",
-            "                 ",
-            "     ",
-            "     // we should highlight other types of errors..",
-            "    ",
-            "    if (!obj.has_member(type)) {",
-            "        GLib.debug(\"Return has no errors\\n\");",
-            "        return  ;",
-            "    }",
-            "    var err = obj.get_object_member(type);",
-            "    ",
-            "    if (_this.file == null) { ",
-            "\t",
-            "        return; // just in case the file has not loaded yet?",
-            "    }",
-            " ",
-            "",
-            "    var valafn = \"\";",
-            "      try {             ",
-            "           var  regex = new Regex(\"\\\\.bjs$\");",
-            "        ",
-            "         ",
-            "            valafn = regex.replace(_this.file.path,_this.file.path.length , 0 , \".vala\");",
-            "         } catch (GLib.RegexError e) {",
-            "            return;",
-            "        }   ",
-            "",
-            "   if (!err.has_member(valafn)) {",
-            "        GLib.debug(\"File path has no errors\\n\");",
-            "        return  ;",
-            "    }",
-            "    var lines = err.get_object_member(valafn);",
-            "    ",
-            "   ",
-            "    ",
-            "    var tlines = buf.get_line_count () +1;",
-            "    ",
-            "    lines.foreach_member((obj, line, node) => {",
-            "        ",
-            "             Gtk.TextIter iter;",
-            "    //        print(\"get inter\\n\");",
-            "            var eline = int.parse(line) -1  ;",
-            "            GLib.debug(\"GOT ERROR on line %s -- converted to %d\\n\", line,eline);",
-            "            ",
-            "            ",
-            "            if (eline > tlines || eline < 0) {",
-            "                return;",
-            "            }",
-            "            sbuf.get_iter_at_line( out iter, eline);",
-            "            //print(\"mark line\\n\");",
-            "            var msg  = type + \" on line: %d - %s\".printf(eline+1, valafn);",
-            "            var ar = lines.get_array_member(line);",
-            "            for (var i = 0 ; i < ar.get_length(); i++) {",
-            "\t\t    msg += (msg.length > 0) ? \"\\n\" : \"\";",
-            "\t\t    msg += ar.get_string_element(i);",
-            "\t    }",
-            "            ",
-            "            ",
-            "            sbuf.create_source_mark(msg, type, iter);",
-            "        } );",
-            "        return  ;",
-            "    ",
-            " ",
-            "",
-            "",
-            "}"
-           ],
            "| void loadFile" : [
             "( ) {",
             "    this.loading = true;",
             "    ",
             "    ((GtkSource.Buffer)(buf)) .set_language(lm.get_language(_this.file.language));",
             "  ",
-            "    ",
-            "    Gtk.TextIter start;",
-            "    Gtk.TextIter end;     ",
-            "        ",
-            "    sbuf.get_bounds (out start, out end);",
-            "    sbuf.remove_source_marks (start, end, null); // remove all marks..",
-            "    ",
-            "    ",
-            "    if (_this.main_window.windowstate.last_compile_result != null) {",
-            "        var obj = _this.main_window.windowstate.last_compile_result;",
-            "        this.highlightErrorsJson(\"ERR\", obj);",
-            "        this.highlightErrorsJson(\"WARN\", obj);",
-            "        this.highlightErrorsJson(\"DEPR\", obj);\t\t\t",
-            "    }",
-            "    // while (Gtk.events_pending()) {",
-            "     //   Gtk.main_iteration();",
-            "   // }",
+            "     ",
+            "   _this.main_window.windowstate.updateErrorMarksAll(); ",
+            "   ",
+            "  ",
             "    ",
             "    this.loading = false; ",
             "}",
     "   ",
     "}",
     ""
+   ],
+   "| void updateErrorMarks" : [
+    "(string category) {",
+    "\t",
+    " ",
+    "",
+    "\tvar buf = _this.buffer.el;",
+    "\tGtk.TextIter start;",
+    "\tGtk.TextIter end;     ",
+    "\tbuf.get_bounds (out start, out end);",
+    "",
+    "\tbuf.remove_source_marks (start, end, category);",
+    " ",
+    "\tGLib.debug(\"highlight errors\");\t\t ",
+    "",
+    "\t // we should highlight other types of errors..",
+    "",
+    " ",
+    "",
+    "\t ",
+    "\tif (_this.file == null) {",
+    "\t\tGLib.debug(\"file is null?\");",
+    "\t\treturn;",
+    "",
+    "\t}",
+    "\tvar ar = this.file.getErrors(category);",
+    "\tif (ar == null || ar.get_n_items() < 1) {",
+    "\t\tGLib.debug(\"higjlight %s has no errors\", category);",
+    "\t\treturn;",
+    "\t}",
+    " ",
+    "",
+    " ",
+    "\t",
+    "\tvar offset = 0;",
+    "\t ",
+    "",
+    "\tvar tlines = buf.get_line_count () +1;",
+    "\t",
+    " ",
+    "\t ",
+    "\tfor (var i = 0; i < ar.get_n_items();i++) {",
+    "\t\tvar err = (Palete.CompileError) ar.get_item(i);",
+    "\t\t",
+    "\t     Gtk.TextIter iter;",
+    "//        print(\"get inter\\n\");",
+    "\t    var eline = err.line - offset;",
+    "\t    GLib.debug(\"GOT ERROR on line %d -- converted to %d  (offset = %d)\",",
+    "\t    \terr.line ,eline, offset);",
+    "\t    ",
+    "\t    ",
+    "\t    if (eline > tlines || eline < 0) {",
+    "\t        return;",
+    "\t    }",
+    "\t   ",
+    "\t    ",
+    "\t    buf.get_iter_at_line( out iter, eline);",
+    "\t   ",
+    "\t   ",
+    "\t\tvar msg = \"Line: %d %s : %s\".printf(eline+1, err.category, err.msg);",
+    "\t    buf.create_source_mark( msg, err.category, iter);",
+    "\t    GLib.debug(\"set line %d to %s\", eline, msg);",
+    "\t    //this.marks.set(eline, msg);",
+    "\t}",
+    "\treturn ;",
+    "",
+    "",
+    "",
+    " ",
+    "",
+    "}"
    ]
   }
  ],
index ef0c8f3..830bd01 100644 (file)
         
             
              
+        }
+        public void updateErrorMarks (string category) {
+               
+         
+        
+               var buf = _this.buffer.el;
+               Gtk.TextIter start;
+               Gtk.TextIter end;     
+               buf.get_bounds (out start, out end);
+        
+               buf.remove_source_marks (start, end, category);
+         
+               GLib.debug("highlight errors");          
+        
+                // we should highlight other types of errors..
+        
+         
+        
+                
+               if (_this.file == null) {
+                       GLib.debug("file is null?");
+                       return;
+        
+               }
+               var ar = this.file.getErrors(category);
+               if (ar == null || ar.get_n_items() < 1) {
+                       GLib.debug("higjlight %s has no errors", category);
+                       return;
+               }
+         
+        
+         
+               
+               var offset = 0;
+                
+        
+               var tlines = buf.get_line_count () +1;
+               
+         
+                
+               for (var i = 0; i < ar.get_n_items();i++) {
+                       var err = (Palete.CompileError) ar.get_item(i);
+                       
+                    Gtk.TextIter iter;
+        //        print("get inter\n");
+                   var eline = err.line - offset;
+                   GLib.debug("GOT ERROR on line %d -- converted to %d  (offset = %d)",
+                       err.line ,eline, offset);
+                   
+                   
+                   if (eline > tlines || eline < 0) {
+                       return;
+                   }
+                  
+                   
+                   buf.get_iter_at_line( out iter, eline);
+                  
+                  
+                       var msg = "Line: %d %s : %s".printf(eline+1, err.category, err.msg);
+                   buf.create_source_mark( msg, err.category, iter);
+                   GLib.debug("set line %d to %s", eline, msg);
+                   //this.marks.set(eline, msg);
+               }
+               return ;
+        
+        
+        
+         
+        
         }
         public void scroll_to_line (int line) {
           // code preview...
                 
                 ((GtkSource.Buffer)(buf)) .set_language(lm.get_language(_this.file.language));
               
-                
-                Gtk.TextIter start;
-                Gtk.TextIter end;     
-                    
-                sbuf.get_bounds (out start, out end);
-                sbuf.remove_source_marks (start, end, null); // remove all marks..
-                
-                
-                if (_this.main_window.windowstate.last_compile_result != null) {
-                    var obj = _this.main_window.windowstate.last_compile_result;
-                    this.highlightErrorsJson("ERR", obj);
-                    this.highlightErrorsJson("WARN", obj);
-                    this.highlightErrorsJson("DEPR", obj);                     
-                }
-                // while (Gtk.events_pending()) {
-                 //   Gtk.main_iteration();
-               // }
+                 
+               _this.main_window.windowstate.updateErrorMarksAll(); 
+               
+              
                 
                 this.loading = false; 
             }
                 }
                 
             
-            }
-            public void highlightErrorsJson (string type, Json.Object obj) {
-                  Gtk.TextIter start;
-                 Gtk.TextIter end;   
-                 
-                 var buf =  this.el.get_buffer();
-                   var sbuf = (GtkSource.Buffer)buf;
-                    buf.get_bounds (out start, out end);
-                    
-                    sbuf.remove_source_marks (start, end, type);
-                             
-                 
-                 // we should highlight other types of errors..
-                
-                if (!obj.has_member(type)) {
-                    GLib.debug("Return has no errors\n");
-                    return  ;
-                }
-                var err = obj.get_object_member(type);
-                
-                if (_this.file == null) { 
-               
-                    return; // just in case the file has not loaded yet?
-                }
-             
-            
-                var valafn = "";
-                  try {             
-                       var  regex = new Regex("\\.bjs$");
-                    
-                     
-                        valafn = regex.replace(_this.file.path,_this.file.path.length , 0 , ".vala");
-                     } catch (GLib.RegexError e) {
-                        return;
-                    }   
-            
-               if (!err.has_member(valafn)) {
-                    GLib.debug("File path has no errors\n");
-                    return  ;
-                }
-                var lines = err.get_object_member(valafn);
-                
-               
-                
-                var tlines = buf.get_line_count () +1;
-                
-                lines.foreach_member((obj, line, node) => {
-                    
-                         Gtk.TextIter iter;
-                //        print("get inter\n");
-                        var eline = int.parse(line) -1  ;
-                        GLib.debug("GOT ERROR on line %s -- converted to %d\n", line,eline);
-                        
-                        
-                        if (eline > tlines || eline < 0) {
-                            return;
-                        }
-                        sbuf.get_iter_at_line( out iter, eline);
-                        //print("mark line\n");
-                        var msg  = type + " on line: %d - %s".printf(eline+1, valafn);
-                        var ar = lines.get_array_member(line);
-                        for (var i = 0 ; i < ar.get_length(); i++) {
-                           msg += (msg.length > 0) ? "\n" : "";
-                           msg += ar.get_string_element(i);
-                   }
-                        
-                        
-                        sbuf.create_source_mark(msg, type, iter);
-                    } );
-                    return  ;
-                
-             
-            
-            
             }
             public string toString () {
                Gtk.TextIter s;
index 337bf15..d43dd8f 100644 (file)
            "xtype" : "Label"
           },
           {
-           "# GLib.ListStore notices" : "null",
            "$ xns" : "Gtk",
            "Xcls_ValaCompileErrors popup" : "",
            "id" : "statusbar_errors",
            "listeners" : {
             "clicked" : [
              "() => {",
-             "    ",
-             "",
-             "    ",
-             "    if (this.popup == null) {",
-             "        this.popup = new Xcls_ValaCompileErrors();",
-             "        this.popup.window = _this;",
-             "        //this.popup.el.application = _this.el.application;",
-             "\t  //   this.popup.el.set_transient_for( _this.el );",
-             "       this.popup.el.set_parent(this.el);",
-             "    }",
-             "    if (_this.statusbar_compile_spinner.el.spinning) {",
-             "\t\tthis.popup.el.show();    \t",
-             "    \treturn;",
-             "\t}    ",
-             "    this.popup.show(this.notices, this.el);",
-             "    return;",
+             " ",
+             "\tif (this.popup == null) {",
+             "\t\treturn;",
+             "\t}",
+             "   ",
+             "    this.popup.show();",
+             "  ",
              "}"
             ]
            },
            "string label" : "0 Errors",
            "xtype" : "Button",
            "| void setNotices" : [
-            "(GLib.ListStore nots, int qty, int tf) {",
+            "(GLib.ListStore nots, GLib.ListStore fe ) {",
             "    ",
-            "     if (qty < 1 ) {",
+            "     if (nots.get_n_items() < 1 ) {",
             "    \tthis.el.hide();",
-            "    \tif (this.popup != null && this.popup.el.visible) {",
+            "    \tif (this.popup != null) {",
             "    \t\tthis.popup.el.hide();",
             "\t\t}",
             "    \treturn;",
             "    }",
             "    ",
             "    this.el.show();",
-            "    this.el.label = \"%d/%d Errors\".printf(tf,qty);",
-            "    this.notices = nots;",
-            "\tif (this.popup != null && this.popup.el.visible) {",
-            "\t\t this.popup.show(this.notices, this.el);",
+            "    this.el.label = \"%d/%d Errors\".printf((int)fe.get_n_items(),(int)nots.get_n_items());",
+            "",
+            "    ",
+            " ",
+            "\tif (this.popup == null) {",
+            "        this.popup = new Xcls_ValaCompileErrors();",
+            "        this.popup.window = _this;",
+            "      //    this.popup.el.set_transient_for( _this.el );",
+            "        this.popup.el.set_parent(this.el);",
             "    }",
+            "\tthis.popup.updateNotices(nots);",
+            "\t ",
             "}",
             ""
            ]
           },
           {
-           "# GLib.ListStore notices" : "null",
            "$ xns" : "Gtk",
            "Xcls_ValaCompileErrors popup" : "",
            "id" : "statusbar_warnings",
              "() => {",
              " ",
              "\tif (this.popup == null) {",
-             "        this.popup = new Xcls_ValaCompileErrors();",
-             "        this.popup.window = _this;",
-             "      //    this.popup.el.set_transient_for( _this.el );",
-             "        this.popup.el.set_parent(this.el);",
-             "    }",
-             "        if (_this.statusbar_compile_spinner.el.spinning) {",
-             "\t\tthis.popup.el.show();    \t",
-             "    \treturn;",
-             "\t}    ",
-             "    this.popup.show(this.notices, this.el);",
+             "\t\treturn;",
+             "\t}",
+             "   ",
+             "    this.popup.show();",
              "    return;",
              "}"
             ]
            "string label" : "0 Warnings",
            "xtype" : "Button",
            "| void setNotices" : [
-            "(GLib.ListStore nots, int qty, int tf) {",
+            "(GLib.ListStore nots, GLib.ListStore fe ) {",
             "    ",
-            "    if (qty < 1 ) {",
+            "     if (nots.get_n_items() < 1 ) {",
             "    \tthis.el.hide();",
-            "    \tif (this.popup != null && this.popup.el.visible) {",
+            "    \tif (this.popup != null) {",
             "    \t\tthis.popup.el.hide();",
             "\t\t}",
             "    \treturn;",
             "    }",
-            "    this.el.show();",
-            "    this.el.label = \"%d/%d Warnings\".printf(tf,qty);",
-            "     this.notices = nots;",
-            "    if (this.popup != null && this.popup.el.visible) {",
-            "\t\t this.popup.show(this.notices, this.el);",
-            "    }",
             "    ",
+            "    this.el.show();",
+            "    this.el.label = \"%d/%d Warnings\".printf((int)fe.get_n_items(),(int)nots.get_n_items());",
             "",
+            "    ",
+            " ",
+            "\tif (this.popup == null) {",
+            "        this.popup = new Xcls_ValaCompileErrors();",
+            "        this.popup.window = _this;",
+            "      //    this.popup.el.set_transient_for( _this.el );",
+            "        this.popup.el.set_parent(this.el);",
+            "    }",
+            "\tthis.popup.updateNotices(nots);",
+            "\t ",
             "}",
             ""
            ]
            "listeners" : {
             "clicked" : [
              "() => {",
-             "    ",
+             " ",
              "\tif (this.popup == null) {",
-             "        this.popup = new Xcls_ValaCompileErrors();",
-             "        this.popup.window = _this;",
-             "      //  this.popup.el.set_transient_for( _this.el );",
-             "        this.popup.el.set_parent(this.el);",
-             "    }",
-             "    if (_this.statusbar_compile_spinner.el.spinning) {",
-             "\t\tthis.popup.el.show();    \t",
-             "    \treturn;",
-             "\t}    ",
-             "    ",
-             "    this.popup.show(this.notices, this.el);",
-             "    return;",
+             "\t\treturn;",
+             "\t}",
+             "   ",
+             "    this.popup.show();",
+             "  ",
              "}"
             ]
            },
            "string label" : "0 Depricated",
            "xtype" : "Button",
            "| void setNotices" : [
-            "(GLib.ListStore nots, int qty, int tf) {",
-            "    if (qty < 1) {",
+            "",
+            "(GLib.ListStore nots, GLib.ListStore fe ) {",
+            "    ",
+            "     if (nots.get_n_items() < 1 ) {",
             "    \tthis.el.hide();",
-            "    \tif (this.popup != null && this.popup.el.visible) {",
-            "\t\t\t this.popup.el.hide();",
+            "    \tif (this.popup != null) {",
+            "    \t\tthis.popup.el.hide();",
             "\t\t}",
-            " ",
             "    \treturn;",
-            "\t}",
+            "    }",
             "    ",
             "    this.el.show();",
+            "    this.el.label = \"%d/%d Depricated\".printf((int)fe.get_n_items(),(int)nots.get_n_items());",
+            "",
             "    ",
-            "    this.el.label = \"%d/%d Depricated\".printf(tf,qty);",
-            "    this.notices = nots;",
-            "\tif (this.popup != null && this.popup.el.visible) {",
-            "\t\t this.popup.show(this.notices, this.el);",
+            " ",
+            "\tif (this.popup == null) {",
+            "        this.popup = new Xcls_ValaCompileErrors();",
+            "        this.popup.window = _this;",
+            "      //    this.popup.el.set_transient_for( _this.el );",
+            "        this.popup.el.set_parent(this.el);",
             "    }",
+            "\tthis.popup.updateNotices(nots);",
+            "\t ",
             "}",
             ""
            ]
              "\t    _this.windowstate.compile_results.el.show(); // show currently running.",
              "    \treturn;",
              "\t}",
-             "\tBuilderApplication.valacompilequeue.addFile( ",
-             "\t \t\t\t\t\tPalete.ValaCompileRequestType.RUN, ",
-             "\t \t\t\t\t\t_this.windowstate.file, \"\", true ) ;",
-             "",
+             "\t",
+             "\tvar req = new Palete.ValaCompileRequest(",
+             "\t\tPalete.ValaCompileRequestType.RUN,",
+             "\t\t_this.windowstate.file,",
+             "\t\tnull,",
+             "\t\tnull,",
+             "\t\t\"\"",
+             "\t);",
+             "\treq.run();",
+             "\t ",
              "\t_this.windowstate.compile_results.el.set_parent(this.el);",
              "\t_this.windowstate.compile_results.show(this.el,true);",
              "\t         ",
      "( ) => {",
      "\t Resources.singleton().disconnect(_this.statusbar.handler_id);",
      "\t ",
+     "\t ",
+     "\t this.windowstate.file.getLanguageServer().document_close(",
+     "\t \tthis.windowstate.file",
+     " \t);",
+     "\t ",
      "\t BuilderApplication.removeWindow(this);",
      "\t ",
      "\t if (BuilderApplication.windows.size  < 1) {",
-     "",
+     "\t\tthis.windowstate.file.getLanguageServer().exit();",
      "\t\tBuilderApplication.singleton(  null ).quit();",
      "\t }",
      "\treturn true;",
     "}"
    ],
    "| void updateErrors" : [
-    "(Palete.ValaCompileRequest? req) {",
+    "() {",
     "",
-    "\tif (req == null) {",
-    " ",
-    "\t    _this.statusbar_errors.el.hide();",
-    "\t\t_this.statusbar_warnings.el.hide();",
-    "\t\t_this.statusbar_depricated.el.hide();",
-    "\t\treturn;",
-    "\t}",
+    "",
+    " \tGLib.debug(\"updateErrors\");",
     "\t",
+    "\tvar pr = this.windowstate.project.getErrors(\"ERR\");",
     "\t",
     "\tthis.statusbar_errors.setNotices(",
-    "\t\treq.errorByType.get(\"ERR\"),",
-    "\t\treq.totalErrors(\"ERR\"),",
-    "\t\treq.totalErrors(\"ERR\", this.windowstate.file)",
+    "\t\tpr,",
+    "\t\tthis.windowstate.file.getErrors(\"ERR\")",
     "\t);",
+    "\t",
     "\tthis.statusbar_warnings.setNotices(",
-    "\t\treq.errorByType.get(\"WARN\"),",
-    "\t\treq.totalErrors(\"WARN\"),",
-    "\t\treq.totalErrors(\"WARN\", this.windowstate.file)",
+    "\t\tthis.windowstate.project.getErrors(\"WARN\"),",
+    "\t\tthis.windowstate.file.getErrors(\"WARN\")",
     "\t);",
     "\tthis.statusbar_depricated.setNotices(",
-    "\t\treq.errorByType.get(\"DEPR\"),",
-    "\t\treq.totalErrors(\"DEPR\"),",
-    "\t\treq.totalErrors(\"DEPR\", this.windowstate.file)",
+    "\t\tthis.windowstate.project.getErrors(\"DEPR\"),",
+    "\t\tthis.windowstate.file.getErrors(\"DEPR\")",
     "\t);",
-    "",
+    " ",
     "\t_this.statusbar_run.el.hide();",
     "",
-    "\tif (req.totalErrors(\"ERR\") < 1) {",
+    "\tif (pr.get_n_items() < 1) {",
     "\t\t_this.statusbar_run.el.show();",
-    "\t}",
+    "\t} ",
     "\t",
     "}"
    ]
index 76242bb..65636a6 100644 (file)
             this.el.close_request.connect( ( ) => {
                 Resources.singleton().disconnect(_this.statusbar.handler_id);
                 
+                
+                this.windowstate.file.getLanguageServer().document_close(
+                       this.windowstate.file
+               );
+                
                 BuilderApplication.removeWindow(this);
                 
                 if (BuilderApplication.windows.size  < 1) {
-            
+                       this.windowstate.file.getLanguageServer().exit();
                        BuilderApplication.singleton(  null ).quit();
                 }
                return true;
         }
 
         // user defined functions
-        public void updateErrors (Palete.ValaCompileRequest? req) {
+        public void updateErrors () {
         
-               if (req == null) {
-         
-                   _this.statusbar_errors.el.hide();
-                       _this.statusbar_warnings.el.hide();
-                       _this.statusbar_depricated.el.hide();
-                       return;
-               }
+        
+               GLib.debug("updateErrors");
                
+               var pr = this.windowstate.project.getErrors("ERR");
                
                this.statusbar_errors.setNotices(
-                       req.errorByType.get("ERR"),
-                       req.totalErrors("ERR"),
-                       req.totalErrors("ERR", this.windowstate.file)
+                       pr,
+                       this.windowstate.file.getErrors("ERR")
                );
+               
                this.statusbar_warnings.setNotices(
-                       req.errorByType.get("WARN"),
-                       req.totalErrors("WARN"),
-                       req.totalErrors("WARN", this.windowstate.file)
+                       this.windowstate.project.getErrors("WARN"),
+                       this.windowstate.file.getErrors("WARN")
                );
                this.statusbar_depricated.setNotices(
-                       req.errorByType.get("DEPR"),
-                       req.totalErrors("DEPR"),
-                       req.totalErrors("DEPR", this.windowstate.file)
+                       this.windowstate.project.getErrors("DEPR"),
+                       this.windowstate.file.getErrors("DEPR")
                );
-        
+         
                _this.statusbar_run.el.hide();
         
-               if (req.totalErrors("ERR") < 1) {
+               if (pr.get_n_items() < 1) {
                        _this.statusbar_run.el.show();
-               }
+               } 
                
         }
         public void initChildren () {
 
                 // my vars (def)
             public Xcls_ValaCompileErrors popup;
-            public GLib.ListStore notices;
 
             // ctor
             public Xcls_statusbar_errors(Xcls_MainWindow _owner )
                 this.el = new Gtk.Button();
 
                 // my vars (dec)
-                this.notices = null;
 
                 // set gobject values
                 this.el.icon_name = "dialog-error";
 
                 //listeners
                 this.el.clicked.connect( () => {
-                    
-                
-                    
-                    if (this.popup == null) {
-                        this.popup = new Xcls_ValaCompileErrors();
-                        this.popup.window = _this;
-                        //this.popup.el.application = _this.el.application;
-                         //   this.popup.el.set_transient_for( _this.el );
-                       this.popup.el.set_parent(this.el);
-                    }
-                    if (_this.statusbar_compile_spinner.el.spinning) {
-                               this.popup.el.show();           
-                       return;
-                       }    
-                    this.popup.show(this.notices, this.el);
-                    return;
+                 
+                       if (this.popup == null) {
+                               return;
+                       }
+                   
+                    this.popup.show();
+                  
                 });
             }
 
             // user defined functions
-            public void setNotices (GLib.ListStore nots, int qty, int tf) {
+            public void setNotices (GLib.ListStore nots, GLib.ListStore fe ) {
                 
-                 if (qty < 1 ) {
+                 if (nots.get_n_items() < 1 ) {
                        this.el.hide();
-                       if (this.popup != null && this.popup.el.visible) {
+                       if (this.popup != null) {
                                this.popup.el.hide();
                        }
                        return;
                 }
                 
                 this.el.show();
-                this.el.label = "%d/%d Errors".printf(tf,qty);
-                this.notices = nots;
-               if (this.popup != null && this.popup.el.visible) {
-                        this.popup.show(this.notices, this.el);
+                this.el.label = "%d/%d Errors".printf((int)fe.get_n_items(),(int)nots.get_n_items());
+            
+                
+             
+               if (this.popup == null) {
+                    this.popup = new Xcls_ValaCompileErrors();
+                    this.popup.window = _this;
+                  //    this.popup.el.set_transient_for( _this.el );
+                    this.popup.el.set_parent(this.el);
                 }
+               this.popup.updateNotices(nots);
+                
             }
         }
 
 
                 // my vars (def)
             public Xcls_ValaCompileErrors popup;
-            public GLib.ListStore notices;
 
             // ctor
             public Xcls_statusbar_warnings(Xcls_MainWindow _owner )
                 this.el = new Gtk.Button();
 
                 // my vars (dec)
-                this.notices = null;
 
                 // set gobject values
                 this.el.icon_name = "dialog-warning";
                 this.el.clicked.connect( () => {
                  
                        if (this.popup == null) {
-                        this.popup = new Xcls_ValaCompileErrors();
-                        this.popup.window = _this;
-                      //    this.popup.el.set_transient_for( _this.el );
-                        this.popup.el.set_parent(this.el);
-                    }
-                        if (_this.statusbar_compile_spinner.el.spinning) {
-                               this.popup.el.show();           
-                       return;
-                       }    
-                    this.popup.show(this.notices, this.el);
+                               return;
+                       }
+                   
+                    this.popup.show();
                     return;
                 });
             }
 
             // user defined functions
-            public void setNotices (GLib.ListStore nots, int qty, int tf) {
+            public void setNotices (GLib.ListStore nots, GLib.ListStore fe ) {
                 
-                if (qty < 1 ) {
+                 if (nots.get_n_items() < 1 ) {
                        this.el.hide();
-                       if (this.popup != null && this.popup.el.visible) {
+                       if (this.popup != null) {
                                this.popup.el.hide();
                        }
                        return;
                 }
-                this.el.show();
-                this.el.label = "%d/%d Warnings".printf(tf,qty);
-                 this.notices = nots;
-                if (this.popup != null && this.popup.el.visible) {
-                        this.popup.show(this.notices, this.el);
-                }
                 
+                this.el.show();
+                this.el.label = "%d/%d Warnings".printf((int)fe.get_n_items(),(int)nots.get_n_items());
             
+                
+             
+               if (this.popup == null) {
+                    this.popup = new Xcls_ValaCompileErrors();
+                    this.popup.window = _this;
+                  //    this.popup.el.set_transient_for( _this.el );
+                    this.popup.el.set_parent(this.el);
+                }
+               this.popup.updateNotices(nots);
+                
             }
         }
 
 
                 //listeners
                 this.el.clicked.connect( () => {
-                    
+                 
                        if (this.popup == null) {
-                        this.popup = new Xcls_ValaCompileErrors();
-                        this.popup.window = _this;
-                      //  this.popup.el.set_transient_for( _this.el );
-                        this.popup.el.set_parent(this.el);
-                    }
-                    if (_this.statusbar_compile_spinner.el.spinning) {
-                               this.popup.el.show();           
-                       return;
-                       }    
-                    
-                    this.popup.show(this.notices, this.el);
-                    return;
+                               return;
+                       }
+                   
+                    this.popup.show();
+                  
                 });
             }
 
             // user defined functions
-            public void setNotices (GLib.ListStore nots, int qty, int tf) {
-                if (qty < 1) {
+            public void setNotices (GLib.ListStore nots, GLib.ListStore fe ) {
+                
+                 if (nots.get_n_items() < 1 ) {
                        this.el.hide();
-                       if (this.popup != null && this.popup.el.visible) {
-                                this.popup.el.hide();
+                       if (this.popup != null) {
+                               this.popup.el.hide();
                        }
-             
                        return;
-               }
+                }
                 
                 this.el.show();
+                this.el.label = "%d/%d Depricated".printf((int)fe.get_n_items(),(int)nots.get_n_items());
+            
                 
-                this.el.label = "%d/%d Depricated".printf(tf,qty);
-                this.notices = nots;
-               if (this.popup != null && this.popup.el.visible) {
-                        this.popup.show(this.notices, this.el);
+             
+               if (this.popup == null) {
+                    this.popup = new Xcls_ValaCompileErrors();
+                    this.popup.window = _this;
+                  //    this.popup.el.set_transient_for( _this.el );
+                    this.popup.el.set_parent(this.el);
                 }
+               this.popup.updateNotices(nots);
+                
             }
         }
 
                            _this.windowstate.compile_results.el.show(); // show currently running.
                        return;
                        }
-                       BuilderApplication.valacompilequeue.addFile( 
-                                                               Palete.ValaCompileRequestType.RUN, 
-                                                               _this.windowstate.file, "", true ) ;
-                
+                       
+                       var req = new Palete.ValaCompileRequest(
+                               Palete.ValaCompileRequestType.RUN,
+                               _this.windowstate.file,
+                               null,
+                               null,
+                               ""
+                       );
+                       req.run();
+                        
                        _this.windowstate.compile_results.el.set_parent(this.el);
                        _this.windowstate.compile_results.show(this.el,true);
                                 
index 3bf4b55..5e4aeb3 100644 (file)
@@ -3,12 +3,12 @@
  "gen_extended" : false,
  "items" : [
   {
-   "# GLib.ListStore notices" : "",
    "# Xcls_MainWindow window" : "",
    "$ xns" : "Gtk",
    "* ctor" : "new Gtk.Popover()",
    "Gtk.PositionType position" : "Gtk.PositionType.TOP",
    "bool autohide" : true,
+   "bool loaded" : false,
    "id" : "ValaCompileErrors",
    "int height_request" : 800,
    "int width_request" : 900,
                "* prop" : "model",
                "id" : "model",
                "xtype" : "TreeListModel"
+              },
+              {
+               "$ xns" : "Gtk",
+               "* prop" : "sorter",
+               "items" : [
+                {
+                 "$ xns" : "Gtk",
+                 "* prop" : "sorter",
+                 "items" : [
+                  {
+                   "$ xns" : "Gtk",
+                   "* prop" : "expression",
+                   "GLib.Type this_type" : "typeof(Palete.CompileError)",
+                   "string property_name" : "linemsg",
+                   "xtype" : "PropertyExpression"
+                  }
+                 ],
+                 "xtype" : "StringSorter"
+                }
+               ],
+               "xtype" : "TreeListRowSorter"
               }
              ],
              "xtype" : "SortListModel",
                "\t",
                "\t",
                "\t//GLib.debug(\"change  %s to %s\", lbl.label, np.name);",
-               "\tlbl.label = np.line_msg;",
+               "\tlbl.label = np.linemsg;",
                "\t//lbl.tooltip_markup = np.to_property_option_tooltip();",
                "\t ",
                "    expand.set_hide_expander(  np.lines.n_items < 1);",
                "\texpand.set_list_row(lr);",
                " ",
                " \t// expand current file.",
-               " \tif (_this.window.windowstate.file.path == np.file.path) {",
-               " \t\tlr.expanded = true;",
-               "\t}",
+               " \t// this causes problems? - critical errors?",
+               " \t// maybe do it on show",
+               " \t//if (_this.window.windowstate.file.path == np.file.path &&",
+               " \t//\tnp.line < 0) {",
+               " \t//\tlr.expanded = true;",
+               " \t",
+               "\t//}",
                " \t ",
                " \t// bind image...",
                " \t",
              "\t}",
              "\t ",
              "\t ",
-             "    var fname  = ce.parent.file;",
+             "    var fname  = ce.file;",
              "  \tvar line = ce.line;  ",
-             "    GLib.debug(\"open %s @ %d\\n\", ce.parent.file.path, ce.line);",
+             "    GLib.debug(\"open %s @ %d\\n\", ce.file.path, ce.line);",
              "    ",
              "    ",
              "   var  bjsf = \"\";",
              "        _this.window.windowstate.fileViewOpen(jsr, true, line);",
              "        ",
              "        if (jsr.path == _this.window.windowstate.file.path) {",
-             "        \t_this.el.hide();",
-             "    \t}",
              "        ",
+             "    \t}",
+             "    \t_this.el.hide();",
              "        ",
              "        return;",
              "    ",
              "    }",
-             "    try {",
-             "\t\tvar pf = JsRender.JsRender.factory(\"PlainFile\", p, fname.path);",
-             "\t\t_this.window.windowstate.fileViewOpen(pf, true, line);",
-             "    } catch (JsRender.Error e) {}",
-             "    // try hiding the left nav..",
-             " ",
-             "    return;",
+             "  ",
+             "\tvar pf = p.getByPath(fname.path);",
+             "\t_this.el.hide();",
+             "\t_this.window.windowstate.fileViewOpen(pf, true, line);",
              "",
+             "    ",
              "}",
              ""
             ]
    ],
    "xtype" : "Popover",
    "| void show" : [
-    "( GLib.ListStore ls , Gtk.Widget onbtn) {",
-    "",
-    "    ",
+    "(   ) {",
+    "\tGLib.debug(\"errors  : show\");",
+    "\t",
+    "\tif (_this.model.el.get_n_items()  < 1) {",
+    "   ",
+    " \t    GLib.debug(\"errors  : none available\");",
+    "    \treturn;",
+    "\t}",
     " \t//this.el.present();",
     "    //this.el.popup();",
-    "    this.notices = ls;",
-    "   ",
+    "    ",
     "     //print(\"looking for %s\\n\", id);",
     "    // loop through parent childnre",
     "      ",
     "    ",
-    "      this.tree.el.hide(); //<< very important!!!",
+    "     ; //<< very important!!!",
     "      ",
     "   // store.set_sort_column_id(0,Gtk.SortType.ASCENDING);",
     " ",
     "    var  w = win.get_width();",
     "    var h = win.get_height();",
     "",
-    "  ",
-    "     ",
+    "   ",
     "    // left tree = 250, editor area = 500?",
     "    ",
     "    // min 450?",
     "    if (new_w > (w-100)) {",
     "        new_w = w-100;",
     "    }",
+    "    GLib.debug(\"set size\");",
     "    this.el.set_size_request( int.max(100, new_w), int.max(100, h-120));",
     " ",
     "",
     "\t//Gtk.Allocation rect;",
     "\t//onbtn.get_allocation(out rect);",
     "    //this.el.set_pointing_to(rect);",
-    "\tthis.el.present();",
+    "\t//this.el.present();",
+    "\t",
+    "\tGLib.debug(\"call popup\");",
     "    this.el.popup();",
+    "    // only need to load once.",
+    " \t//if (!this.loaded) {",
+    " \t\t ",
+    "\t\t//this.loaded = true;",
+    "\t //}",
+    "\t ",
+    "       ",
     "   ",
-    " ",
+    "   \t//if (expand != null) {",
+    "    //\t_this.compile_tree.el.expand_row(   store.get_path(expand) , true);",
+    "//\t}",
+    "    ",
+    " //   this.hpane.el.set_position( 0);",
+    "}",
+    ""
+   ],
+   "| void updateNotices" : [
+    "( GLib.ListStore? ls) {",
+    "\tGLib.debug(\"errors  : update\");",
+    "    if (ls == null || ls.get_n_items() < 1) {",
+    " \t    GLib.debug(\"errors  : none available\");",
+    "    \treturn;",
+    "\t}",
+    "\t",
+    "\tGLib.debug(\"Loading list into tree\");",
+    "\tthis.tree.el.hide();",
     "\tvar tm = new Gtk.TreeListModel(",
     "\t\tls, //..... << that's our store..",
     "\t\tfalse, // passthru",
     "\t\t\t return ((Palete.CompileError)item).lines;",
     "\t\t",
     "\t\t}",
+    "\t\t",
     "\t);",
     " ",
-    "    _this.model.el = tm;",
-    "    _this.sortmodel.el.set_model(tm);",
-    " ",
-    "         this.tree.el.show();   ",
-    "   ",
-    "   \t//if (expand != null) {",
-    "    //\t_this.compile_tree.el.expand_row(   store.get_path(expand) , true);",
-    "//\t}",
-    "    ",
-    " //   this.hpane.el.set_position( 0);",
-    "}",
-    ""
+    "\t_this.model.el = tm;",
+    "\t_this.sortmodel.el.set_model(tm);",
+    "\t this.tree.el.show();",
+    "}"
    ]
   }
  ],
index 295f01c..baac166 100644 (file)
@@ -20,7 +20,7 @@
 
             // my vars (def)
         public Xcls_MainWindow window;
-        public GLib.ListStore notices;
+        public bool loaded;
 
         // ctor
         public Xcls_ValaCompileErrors()
@@ -29,6 +29,7 @@
             this.el = new Gtk.Popover();
 
             // my vars (dec)
+            this.loaded = false;
 
             // set gobject values
             this.el.width_request = 900;
         }
 
         // user defined functions
-        public void show ( GLib.ListStore ls , Gtk.Widget onbtn) {
-        
-            
+        public void updateNotices ( GLib.ListStore? ls) {
+               GLib.debug("errors  : update");
+            if (ls == null || ls.get_n_items() < 1) {
+                   GLib.debug("errors  : none available");
+               return;
+               }
+               
+               GLib.debug("Loading list into tree");
+               this.tree.el.hide();
+               var tm = new Gtk.TreeListModel(
+                       ls, //..... << that's our store..
+                       false, // passthru
+                       false, // autexpand
+                       (item) => {
+                       
+                                return ((Palete.CompileError)item).lines;
+                       
+                       }
+                       
+               );
+         
+               _this.model.el = tm;
+               _this.sortmodel.el.set_model(tm);
+                this.tree.el.show();
+        }
+        public void show (   ) {
+               GLib.debug("errors  : show");
+               
+               if (_this.model.el.get_n_items()  < 1) {
+           
+                   GLib.debug("errors  : none available");
+               return;
+               }
                //this.el.present();
             //this.el.popup();
-            this.notices = ls;
-           
+            
              //print("looking for %s\n", id);
             // loop through parent childnre
               
             
-              this.tree.el.hide(); //<< very important!!!
+             ; //<< very important!!!
               
            // store.set_sort_column_id(0,Gtk.SortType.ASCENDING);
          
@@ -59,8 +89,7 @@
             var  w = win.get_width();
             var h = win.get_height();
         
-          
-             
+           
             // left tree = 250, editor area = 500?
             
             // min 450?
@@ -68,6 +97,7 @@
             if (new_w > (w-100)) {
                 new_w = w-100;
             }
+            GLib.debug("set size");
             this.el.set_size_request( int.max(100, new_w), int.max(100, h-120));
          
         
                //Gtk.Allocation rect;
                //onbtn.get_allocation(out rect);
             //this.el.set_pointing_to(rect);
-               this.el.present();
+               //this.el.present();
+               
+               GLib.debug("call popup");
             this.el.popup();
-           
-         
-               var tm = new Gtk.TreeListModel(
-                       ls, //..... << that's our store..
-                       false, // passthru
-                       false, // autexpand
-                       (item) => {
-                       
-                                return ((Palete.CompileError)item).lines;
-                       
-                       }
-               );
-         
-            _this.model.el = tm;
-            _this.sortmodel.el.set_model(tm);
-         
-                 this.tree.el.show();   
+            // only need to load once.
+               //if (!this.loaded) {
+                        
+                       //this.loaded = true;
+                //}
+                
+               
            
                //if (expand != null) {
             // _this.compile_tree.el.expand_row(   store.get_path(expand) , true);
                 // set gobject values
                 this.el.hexpand = true;
                 this.el.vexpand = true;
-                var child_2 = new Xcls_ColumnViewColumn8( _this );
+                var child_2 = new Xcls_ColumnViewColumn11( _this );
                 child_2.ref();
                 this.el.append_column ( child_2.el  );
-                var child_3 = new Xcls_GestureClick10( _this );
+                var child_3 = new Xcls_GestureClick13( _this );
                 child_3.ref();
                 this.el.add_controller(  child_3.el );
             }
                 _this = _owner;
                 _this.sortmodel = this;
                 new Xcls_model( _this );
-                this.el = new Gtk.SortListModel( _this.model.el, null );
+                var child_2 = new Xcls_TreeListRowSorter8( _this );
+                child_2.ref();
+                this.el = new Gtk.SortListModel( _this.model.el, child_2.el );
 
                 // my vars (dec)
 
             // user defined functions
         }
 
+        public class Xcls_TreeListRowSorter8 : Object
+        {
+            public Gtk.TreeListRowSorter el;
+            private Xcls_ValaCompileErrors  _this;
+
+
+                // my vars (def)
+
+            // ctor
+            public Xcls_TreeListRowSorter8(Xcls_ValaCompileErrors _owner )
+            {
+                _this = _owner;
+                var child_1 = new Xcls_StringSorter9( _this );
+                child_1.ref();
+                this.el = new Gtk.TreeListRowSorter( child_1.el );
+
+                // my vars (dec)
 
+                // set gobject values
+            }
 
-        public class Xcls_ColumnViewColumn8 : Object
+            // user defined functions
+        }
+        public class Xcls_StringSorter9 : Object
+        {
+            public Gtk.StringSorter el;
+            private Xcls_ValaCompileErrors  _this;
+
+
+                // my vars (def)
+
+            // ctor
+            public Xcls_StringSorter9(Xcls_ValaCompileErrors _owner )
+            {
+                _this = _owner;
+                var child_1 = new Xcls_PropertyExpression10( _this );
+                child_1.ref();
+                this.el = new Gtk.StringSorter( child_1.el );
+
+                // my vars (dec)
+
+                // set gobject values
+            }
+
+            // user defined functions
+        }
+        public class Xcls_PropertyExpression10 : Object
+        {
+            public Gtk.PropertyExpression el;
+            private Xcls_ValaCompileErrors  _this;
+
+
+                // my vars (def)
+
+            // ctor
+            public Xcls_PropertyExpression10(Xcls_ValaCompileErrors _owner )
+            {
+                _this = _owner;
+                this.el = new Gtk.PropertyExpression( typeof(Palete.CompileError), null, "linemsg" );
+
+                // my vars (dec)
+
+                // set gobject values
+            }
+
+            // user defined functions
+        }
+
+
+
+
+
+        public class Xcls_ColumnViewColumn11 : Object
         {
             public Gtk.ColumnViewColumn el;
             private Xcls_ValaCompileErrors  _this;
                 // my vars (def)
 
             // ctor
-            public Xcls_ColumnViewColumn8(Xcls_ValaCompileErrors _owner )
+            public Xcls_ColumnViewColumn11(Xcls_ValaCompileErrors _owner )
             {
                 _this = _owner;
-                var child_1 = new Xcls_SignalListItemFactory9( _this );
+                var child_1 = new Xcls_SignalListItemFactory12( _this );
                 child_1.ref();
                 this.el = new Gtk.ColumnViewColumn( "Compile Result", child_1.el );
 
 
             // user defined functions
         }
-        public class Xcls_SignalListItemFactory9 : Object
+        public class Xcls_SignalListItemFactory12 : Object
         {
             public Gtk.SignalListItemFactory el;
             private Xcls_ValaCompileErrors  _this;
                 // my vars (def)
 
             // ctor
-            public Xcls_SignalListItemFactory9(Xcls_ValaCompileErrors _owner )
+            public Xcls_SignalListItemFactory12(Xcls_ValaCompileErrors _owner )
             {
                 _this = _owner;
                 this.el = new Gtk.SignalListItemFactory();
                        
                        
                        //GLib.debug("change  %s to %s", lbl.label, np.name);
-                       lbl.label = np.line_msg;
+                       lbl.label = np.linemsg;
                        //lbl.tooltip_markup = np.to_property_option_tooltip();
                         
                     expand.set_hide_expander(  np.lines.n_items < 1);
                        expand.set_list_row(lr);
                  
                        // expand current file.
-                       if (_this.window.windowstate.file.path == np.file.path) {
-                               lr.expanded = true;
-                       }
+                       // this causes problems? - critical errors?
+                       // maybe do it on show
+                       //if (_this.window.windowstate.file.path == np.file.path &&
+                       //      np.line < 0) {
+                       //      lr.expanded = true;
+                       
+                       //}
                         
                        // bind image...
                        
         }
 
 
-        public class Xcls_GestureClick10 : Object
+        public class Xcls_GestureClick13 : Object
         {
             public Gtk.GestureClick el;
             private Xcls_ValaCompileErrors  _this;
                 // my vars (def)
 
             // ctor
-            public Xcls_GestureClick10(Xcls_ValaCompileErrors _owner )
+            public Xcls_GestureClick13(Xcls_ValaCompileErrors _owner )
             {
                 _this = _owner;
                 this.el = new Gtk.GestureClick();
                        }
                         
                         
-                    var fname  = ce.parent.file;
+                    var fname  = ce.file;
                        var line = ce.line;  
-                    GLib.debug("open %s @ %d\n", ce.parent.file.path, ce.line);
+                    GLib.debug("open %s @ %d\n", ce.file.path, ce.line);
                     
                     
                    var  bjsf = "";
                         _this.window.windowstate.fileViewOpen(jsr, true, line);
                         
                         if (jsr.path == _this.window.windowstate.file.path) {
-                               _this.el.hide();
-                       }
                         
+                       }
+                       _this.el.hide();
                         
                         return;
                     
                     }
-                    try {
-                               var pf = JsRender.JsRender.factory("PlainFile", p, fname.path);
-                               _this.window.windowstate.fileViewOpen(pf, true, line);
-                    } catch (JsRender.Error e) {}
-                    // try hiding the left nav..
-                 
-                    return;
+                  
+                       var pf = p.getByPath(fname.path);
+                       _this.el.hide();
+                       _this.window.windowstate.fileViewOpen(pf, true, line);
                 
+                    
                 });
             }
 
index e1e1a17..ae238ab 100644 (file)
             "\t\t",
             "\t\t}",
             "\t);",
+            "\tif (_this.selmodel.el == null) {",
+            "\t\treturn this.el;",
+            "\t}",
             "\t_this.selmodel.el.set_model(this.el);",
             "\treturn this.el;",
             "}"
            "label" : "Delete Element",
            "listeners" : {
             "clicked" : [
-             "  ( ) => {",
-             "    ",
-             "    print(\"ACTIVATE?\");",
-             "    ",
-             "  \t_this.LeftTreeMenu.el.hide();",
-             "     _this.model.deleteSelected();",
+             " ( ) => {",
+             "_this.LeftTreeMenu.el.hide();",
+             " _this.model.deleteSelected();",
+             "_this.changed();",
              "}"
             ]
            },
index f22c4d0..87dadcb 100644 (file)
                        
                        }
                );
+               if (_this.selmodel.el == null) {
+                       return this.el;
+               }
                _this.selmodel.el.set_model(this.el);
                return this.el;
             }
 
                 //listeners
                 this.el.clicked.connect( ( ) => {
-                    
-                    print("ACTIVATE?");
-                    
-                       _this.LeftTreeMenu.el.hide();
-                     _this.model.deleteSelected();
+                _this.LeftTreeMenu.el.hide();
+                 _this.model.deleteSelected();
+                _this.changed();
                 });
             }
 
index 8a05b79..506da32 100644 (file)
             "    ((GtkSource.Buffer)(buf)) .set_language(lm.get_language(_this.file.language));",
             "  ",
             "    ",
-            "    Gtk.TextIter start;",
-            "    Gtk.TextIter end;     ",
-            "        ",
-            "    sbuf.get_bounds (out start, out end);",
-            "    sbuf.remove_source_marks (start, end, null); // remove all marks..",
+            "    _this.main_window.windowstate.updateErrorMarksAll();",
             "    ",
+            "    // what does this do?",
             "     GLib.Timeout.add(500, () => {",
             "",
             "        print(\"RESORTING cursor to = %d\\n\", cpos);",
     "   ",
     "}",
     ""
+   ],
+   "| void updateErrorMarks" : [
+    "(string category) {",
+    "\t",
+    " ",
+    "",
+    "\tvar buf = _this.buffer.el;",
+    "\tGtk.TextIter start;",
+    "\tGtk.TextIter end;     ",
+    "\tbuf.get_bounds (out start, out end);",
+    "",
+    "\tbuf.remove_source_marks (start, end, category);",
+    " ",
+    "\tGLib.debug(\"highlight errors\");\t\t ",
+    "",
+    "\t // we should highlight other types of errors..",
+    "",
+    " ",
+    "",
+    "\t ",
+    "\tif (_this.file == null) {",
+    "\t\tGLib.debug(\"file is null?\");",
+    "\t\treturn;",
+    "",
+    "\t}",
+    "\tvar ar = this.file.getErrors(category);",
+    "\tif (ar == null || ar.get_n_items() < 1) {",
+    "\t\tGLib.debug(\"higjlight %s has no errors\", category);",
+    "\t\treturn;",
+    "\t}",
+    " ",
+    "",
+    " ",
+    "\t",
+    "\tvar offset = 0;",
+    "\t ",
+    "",
+    "\tvar tlines = buf.get_line_count () +1;",
+    "\t",
+    " ",
+    "\t ",
+    "\tfor (var i = 0; i < ar.get_n_items();i++) {",
+    "\t\tvar err = (Palete.CompileError) ar.get_item(i);",
+    "\t\t",
+    "\t     Gtk.TextIter iter;",
+    "//        print(\"get inter\\n\");",
+    "\t    var eline = err.line - offset;",
+    "\t    GLib.debug(\"GOT ERROR on line %d -- converted to %d  (offset = %d)\",",
+    "\t    \terr.line ,eline, offset);",
+    "\t    ",
+    "\t    ",
+    "\t    if (eline > tlines || eline < 0) {",
+    "\t        return;",
+    "\t    }",
+    "\t   ",
+    "\t    ",
+    "\t    buf.get_iter_at_line( out iter, eline);",
+    "\t   ",
+    "\t   ",
+    "\t\tvar msg = \"Line: %d %s : %s\".printf(eline+1, err.category, err.msg);",
+    "\t    buf.create_source_mark( msg, err.category, iter);",
+    "\t    GLib.debug(\"set line %d to %s\", eline, msg);",
+    "\t    //this.marks.set(eline, msg);",
+    "\t}",
+    "\treturn ;",
+    "",
+    "",
+    "",
+    " ",
+    "",
+    "}"
    ]
   }
  ],
index 22062d8..e8d16f4 100644 (file)
              
             
              
+        }
+        public void updateErrorMarks (string category) {
+               
+         
+        
+               var buf = _this.buffer.el;
+               Gtk.TextIter start;
+               Gtk.TextIter end;     
+               buf.get_bounds (out start, out end);
+        
+               buf.remove_source_marks (start, end, category);
+         
+               GLib.debug("highlight errors");          
+        
+                // we should highlight other types of errors..
+        
+         
+        
+                
+               if (_this.file == null) {
+                       GLib.debug("file is null?");
+                       return;
+        
+               }
+               var ar = this.file.getErrors(category);
+               if (ar == null || ar.get_n_items() < 1) {
+                       GLib.debug("higjlight %s has no errors", category);
+                       return;
+               }
+         
+        
+         
+               
+               var offset = 0;
+                
+        
+               var tlines = buf.get_line_count () +1;
+               
+         
+                
+               for (var i = 0; i < ar.get_n_items();i++) {
+                       var err = (Palete.CompileError) ar.get_item(i);
+                       
+                    Gtk.TextIter iter;
+        //        print("get inter\n");
+                   var eline = err.line - offset;
+                   GLib.debug("GOT ERROR on line %d -- converted to %d  (offset = %d)",
+                       err.line ,eline, offset);
+                   
+                   
+                   if (eline > tlines || eline < 0) {
+                       return;
+                   }
+                  
+                   
+                   buf.get_iter_at_line( out iter, eline);
+                  
+                  
+                       var msg = "Line: %d %s : %s".printf(eline+1, err.category, err.msg);
+                   buf.create_source_mark( msg, err.category, iter);
+                   GLib.debug("set line %d to %s", eline, msg);
+                   //this.marks.set(eline, msg);
+               }
+               return ;
+        
+        
+        
+         
+        
         }
         public void scroll_to_line (int line) {
            // code preview...
                 ((GtkSource.Buffer)(buf)) .set_language(lm.get_language(_this.file.language));
               
                 
-                Gtk.TextIter start;
-                Gtk.TextIter end;     
-                    
-                sbuf.get_bounds (out start, out end);
-                sbuf.remove_source_marks (start, end, null); // remove all marks..
+                _this.main_window.windowstate.updateErrorMarksAll();
                 
+                // what does this do?
                  GLib.Timeout.add(500, () => {
             
                     print("RESORTING cursor to = %d\n", cpos);
index 832c367..9aa3238 100644 (file)
@@ -157,6 +157,30 @@ public class WindowState : Object
                });
                 
        }
+       
+       public void updateErrorMarksAll() 
+       {
+               this.updateErrorMarks("ERR");
+               this.updateErrorMarks("WARN");
+               this.updateErrorMarks("DEPR");
+       
+       }
+       void updateErrorMarks(string cat) 
+       {
+               this.code_editor_tab.updateErrorMarks(cat);
+               switch(this.file.xtype) {
+                       case  "Roo":
+                               this.window_rooview.updateErrorMarks(cat);// foce scroll.
+                               return;
+                       case "Gtk":
+                               this.window_gladeview.updateErrorMarks(cat);
+                               return;
+                        default:
+                               return;
+               }
+       }
+       
+       
 
        public bool leftTreeBeforeChange()
        {
@@ -361,13 +385,7 @@ public class WindowState : Object
                        }
                        //this.left_tree.model.updateSelected();
                        this.file.save();
-                       if (this.file.project.xtype=="Gtk") {
-                                       BuilderApplication.valacompilequeue.addFile( 
-                                               Palete.ValaCompileRequestType.PROJECT, 
-                                               this.file, "", true ) ;
-                       
-                               //BuilderApplication.valasource.checkFileSpawn(this.file);
-                       }
+                        
                });
         
 
@@ -520,11 +538,7 @@ public class WindowState : Object
                        } else {
                                  this.window_gladeview.loadFile(this.left_tree.getActiveFile());
                        }
-                       if (this.file.project.xtype=="Gtk") {
-                               BuilderApplication.valacompilequeue.addFile( 
-                                               Palete.ValaCompileRequestType.PROJECT, 
-                                               this.file, "", false ) ;
-                       }
+                        
                        
                         // we do not need to call spawn... - as it's already called by the editor?
                         
@@ -640,7 +654,7 @@ public class WindowState : Object
                this.file = file;
                BuilderApplication.updateWindows();
                
-
+               file.getLanguageServer().document_open(file);
                        
                        
                if (file.xtype == "PlainFile") {
@@ -659,14 +673,11 @@ public class WindowState : Object
                         
 
                }
-               BuilderApplication.updateCompileResults();
-               if (file.project.xtype == "Gtk" && file.project.last_request == null ) {
-                               
-                       BuilderApplication.valacompilequeue.addFile( 
-                               Palete.ValaCompileRequestType.PROJECT, 
-                               this.file, "" , true) ;
-                        
-               }
+
+                
+
+
+
                this.gotoLine(line);
        
                var ctr= this.win.rooviewbox.el;
@@ -709,7 +720,8 @@ public class WindowState : Object
                        //this.win.editpane.el.set_position(this.win.editpane.el.max_position);
                }
                this.win.setTitle();
-                        
+               
+               BuilderApplication.updateCompileResults();       
 
        }
  
index c536094..f51972e 100644 (file)
@@ -10,7 +10,7 @@ namespace JsRender {
                
                public Dir(Project.Project project, string path) {
            
-               aconstruct( project, path);
+               base( project, path);
                this.xtype = "Dir";
                this.language = "";
                
@@ -40,6 +40,7 @@ namespace JsRender {
                public override string toGlade()  {return "";}
                public override string targetName()  {return "";}
                public override void loadItems() throws GLib.Error {}
+               public override string language_id() { return ""; }
     }
     
     
index 83de74d..dc43139 100644 (file)
@@ -27,7 +27,7 @@ namespace JsRender {
 
            public Gtk(Project.Project project, string path) {
            
-               aconstruct( project, path);
+               base( project, path);
                this.xtype = "Gtk";
                this.language = "vala";
                
@@ -167,6 +167,7 @@ namespace JsRender {
                // this.saveJS(); - disabled at present.. project settings will probably enable this later..
        
                this.saveVala();
+               this.getLanguageServer().document_save(this);
            }
                // ignore these calls.
            public override void saveHTML ( string html ) {}
@@ -269,7 +270,10 @@ namespace JsRender {
                {
                        return  NodeToGlade.mungeFile(this);
                }
-         
+               public   override string language_id() 
+               {
+                       return "vala";
+               }
 
        
 
index 3c44688..09e4f13 100644 (file)
@@ -76,7 +76,16 @@ namespace JsRender {
         
                public string title = "";  // a title.. ?? nickname.. ??? -
 
-               
+               private int _version = 1;   // should we increment this based on the node..?
+               public int version {
+                       get {
+                               return ++this._version; // increased on every call? - bit of a kludge until we do real versioning
+                       }
+                       private set {
+                               this._version = value;
+                       }
+                       
+               }
 
                public string permname;
                public string language;
@@ -104,11 +113,17 @@ namespace JsRender {
                
                public Gee.HashMap<string,string> transStrings; // map of md5 -> string.
                public  Gee.HashMap<string,string> namedStrings;
+               public  Gee.HashMap<string, GLib.ListStore> errorsByType;
+               
+               
 
                public signal void changed (Node? node, string source); 
                
                 
                public signal void compile_notice(string type, string file, int line, string message);
+               
+
+               
                /**
                 * UI componenets
                 * 
@@ -119,10 +134,11 @@ namespace JsRender {
                
                //abstract JsRender(Project.Project project, string path); 
                
-               public void aconstruct(Project.Project project, string path)
+               protected JsRender(Project.Project project, string path)
                {
                    
                        //this.cn = new GLib.List<JsRender>();
+                       GLib.debug("new jsrender %s", path);
                        this.path = path;
                        this.project = project;
                        this.hasParent = false;
@@ -154,6 +170,11 @@ namespace JsRender {
 
                        this.doubleStringProps = new Gee.ArrayList<string>();
                        this.childfiles = new GLib.ListStore(typeof(JsRender));
+                       this.errorsByType  = new Gee.HashMap<string, GLib.ListStore>();
+
+                       if (this.relpath == "src/Lsp.vala") {
+                               GLib.debug("got testing lsp");
+                       }
 
                }
                
@@ -691,6 +712,28 @@ namespace JsRender {
                
                }
                
+               public string to_url()
+               {
+                       return File.new_for_path (this.targetName()).get_uri ();
+               }
+               public Palete.LanguageClient? getLanguageServer()
+               {
+                       
+                       return this.project.getLanguageServer(this.language_id());
+               
+               }
+               public GLib.ListStore getErrors(string n)
+               {
+                       var ls = this.errorsByType.get(n);
+                       if (ls == null) {
+                               ls = new GLib.ListStore(typeof(Palete.CompileError));
+                               this.errorsByType.set(n, ls );
+                       }
+                       return ls;
+               }
+               
+               
+               public abstract string language_id();
                public abstract void save();
                public abstract void saveHTML(string html);
                public abstract string toSource() ;
index c54a9b2..29f8284 100644 (file)
@@ -21,7 +21,7 @@ namespace JsRender {
 
         public PlainFile(Project.Project project, string path) {
         
-            aconstruct( project, path);
+            base( project, path);
             this.xtype = "PlainFile";
             this.content_type = "text/plain";
             
@@ -158,6 +158,18 @@ namespace JsRender {
                return this.path;
        }
 
+
+               public   override string language_id() 
+               {
+                       switch(this.file_ext) {
+                               case "js": return "javascript";
+                               case "vala": return "vala";
+                               case "php": return "php";
+                               case "css": return "css";
+                               case "sql": return "sql";
+                               default: return "???";
+                       }
+               }
                
 
        }
index e62bbee..582984d 100644 (file)
@@ -25,7 +25,7 @@ namespace JsRender {
         
         public Roo(Project.Roo project, string path) 
         {
-            aconstruct( project, path);
+            base( project, path);
  
             this.xtype = "Roo";
              this.language = "js";
@@ -406,7 +406,7 @@ namespace JsRender {
                        if (xinc.size > 0 ) {
                                for(var i = 0; i < xinc.size; i++) {
                                        print("check xinclude:  %s\n", xinc.get(i));
-                                       var sf = this.project.getByName(xinc.get(i));
+                                       var sf = this.project.getByRelPath(xinc.get(i));
                                        if (sf == null) {
                                                print("Failed to find file by name?\n");
                                                continue;
@@ -799,6 +799,10 @@ namespace JsRender {
                {
                        return "Roo files do not convert to glade";
                }
+               public   override string language_id() 
+               {
+                       return "javascript";
+               }
      
     }
 }
diff --git a/src/Lsp.vala b/src/Lsp.vala
new file mode 100644 (file)
index 0000000..b5c4f00
--- /dev/null
@@ -0,0 +1,1376 @@
+/* protocol.vala
+ *
+ * Copyright 2017-2019 Ben Iofel <ben@iofel.me>
+ * Copyright 2017-2020 Princeton Ferro <princetonferro@gmail.com>
+ * Copyright 2020 Sergii Fesenko <s.fesenko@outlook.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+namespace Lsp {
+    /**
+     * Defines how the host (editor) should sync document changes to the language server.
+     */
+    [CCode (default_value = "LSP_TEXT_DOCUMENT_SYNC_KIND_Unset")]
+    public enum TextDocumentSyncKind {
+        Unset = -1,
+        /**
+         * Documents should not be synced at all.
+         */
+        None = 0,
+        /**
+         * Documents are synced by always sending the full content of the document.
+         */
+        Full = 1,
+        /**
+         * Documents are synced by sending the full content on open. After that only incremental
+         * updates to the document are sent.
+         */
+        Incremental = 2
+    }
+
+    public  enum DiagnosticSeverity {
+        Unset = 0,
+        /**
+         * Reports an error.
+         */
+        Error = 1,
+        /**
+         * Reports a warning.
+         */
+        Warning = 2,
+        /**
+         * Reports an information.
+         */
+        Information = 3,
+        /**
+         * Reports a hint.
+         */
+        Hint = 4
+        
+    }
+
+    public  class Position : Object, Gee.Comparable<Position> {
+        /**
+         * Line position in a document (zero-based).
+         */
+        public uint line { get; set; default = -1; }
+
+        /**
+         * Character offset on a line in a document (zero-based). Assuming that the line is
+         * represented as a string, the `character` value represents the gap between the
+         * `character` and `character + 1`.
+         *
+         * If the character value is greater than the line length it defaults back to the
+         * line length.
+         */
+        public uint character { get; set; default = -1; }
+
+        public int compare_to (Position other) {
+            return line > other.line ? 1 :
+                (line == other.line ?
+                 (character > other.character ? 1 :
+                  (character == other.character ? 0 : -1)) : -1);
+        }
+
+        public string to_string () {
+            return @"$line:$character";
+        }
+
+        public Position.from_libvala (Vala.SourceLocation sloc) {
+            line = sloc.line - 1;
+            character = sloc.column;
+        }
+
+        public Position dup () {
+            return this.translate ();
+        }
+
+        public Position translate (int dl = 0, int dc = 0) {
+            return new Position () {
+                line = this.line + dl,
+                character = this.character + dc
+            };
+        }
+    }
+
+    public class Range : Object, Gee.Hashable<Range>, Gee.Comparable<Range> {
+        /**
+         * The range's start position.
+         */
+        public Position start { get; set; }
+
+        /**
+         * The range's end position.
+         */
+        public Position end { get; set; }
+
+        private string? filename;
+
+        public string to_string () { return (filename != null ? @"$filename:" : "") + @"$start -> $end"; }
+
+        public Range.from_pos (Position pos) {
+            this.start = pos;
+            this.end = pos.dup ();
+        }
+
+        public Range.from_sourceref (Vala.SourceReference sref) {
+            this.start = new Position.from_libvala (sref.begin);
+            this.end = new Position.from_libvala (sref.end);
+            this.start.character -= 1;
+            this.filename = sref.file.filename;
+        }
+
+        public uint hash () {
+            return this.to_string ().hash ();
+        }
+
+        public bool equal_to (Range other) { return this.to_string () == other.to_string (); }
+
+        public int compare_to (Range other) {
+            return start.compare_to (other.start);
+        }
+
+        /**
+         * Return a new range that includes `this` and `other`.
+         */
+        public Range union (Range other) {
+            var range = new Range () {
+                start = start.compare_to (other.start) < 0 ? start : other.start,
+                end = end.compare_to (other.end) < 0 ? other.end : end,
+            };
+            if (filename == other.filename)
+                range.filename = filename;
+            return range;
+        }
+
+        public bool contains (Position pos) {
+            return start.compare_to (pos) <= 0 && pos.compare_to (end) <= 0;
+        }
+    }
+
+    public class Diagnostic : Object {
+        /**
+         * The range at which the message applies.
+         */
+        public Range range { get; set; }
+
+        /**
+         * The diagnostic's severity. Can be omitted. If omitted it is up to the
+         * client to interpret diagnostics as error, warning, info or hint.
+         */
+        public DiagnosticSeverity severity { get; set; }
+
+        /**
+         * The diagnostic's code. Can be omitted.
+         */
+        public string? code { get; set; }
+
+        /**
+         * A human-readable string describing the source of this
+         * diagnostic, e.g. 'typescript' or 'super lint'.
+         */
+        public string? source { get; set; }
+
+        /**
+         * The diagnostic's message.
+         */
+        public string message { get; set; }
+        
+        
+        public string category {
+               get { 
+                       switch(this.severity) {
+
+                               case DiagnosticSeverity.Error : 
+                                       return "ERR";
+                               case DiagnosticSeverity.Warning : 
+                                       return this.message.contains("deprecated") ? "DEPR" : "WARN";
+                               default : 
+                                       return "WARN";
+                       }
+               }
+               private set {}
+               
+        }
+    }
+
+    /**
+     * An event describing a change to a text document. If range and rangeLength are omitted
+     * the new text is considered to be the full content of the document.
+     */
+    public class TextDocumentContentChangeEvent : Object {
+        public Range? range    { get; set; }
+        public int rangeLength { get; set; }
+        public string text     { get; set; }
+    }
+
+    public enum MessageType {
+        /**
+         * An error message.
+         */
+        Error = 1,
+        /**
+         * A warning message.
+         */
+        Warning = 2,
+        /**
+         * An information message.
+         */
+        Info = 3,
+        /**
+         * A log message.
+         */
+        Log = 4
+    }
+
+    public class TextDocumentIdentifier : Object {
+        public string uri { get; set; }
+    }
+
+    public class VersionedTextDocumentIdentifier : TextDocumentIdentifier {
+        /**
+         * The version number of this document. If a versioned text document identifier
+         * is sent from the server to the client and the file is not open in the editor
+         * (the server has not received an open notification before) the server can send
+         * `null` to indicate that the version is known and the content on disk is the
+         * master (as speced with document content ownership).
+         *
+         * The version number of a document will increase after each change, including
+         * undo/redo. The number doesn't need to be consecutive.
+         */
+        public int version { get; set; default = -1; }
+    }
+
+    public class TextDocumentPositionParams : Object {
+        public TextDocumentIdentifier textDocument { get; set; }
+        public Position position { get; set; }
+    }
+
+    public class ReferenceParams : TextDocumentPositionParams {
+        public class ReferenceContext : Object {
+            public bool includeDeclaration { get; set; }
+        }
+        public ReferenceContext? context { get; set; }
+    }
+
+    public class Location : Object {
+        public string uri { get; set; }
+        public Range range { get; set; }
+
+        public Location.from_sourceref (Vala.SourceReference sref) {
+            this (sref.file.filename, new Range.from_sourceref (sref));
+        }
+
+        public Location (string filename, Range range) {
+            this.uri = File.new_for_commandline_arg (filename).get_uri ();
+            this.range = range;
+        }
+    }
+
+    [CCode (default_value = "LSP_DOCUMENT_HIGHLIGHT_KIND_Text")]
+    public enum DocumentHighlightKind {
+        Text = 1,
+        Read = 2,
+        Write = 3
+    }
+
+    public class DocumentHighlight : Object {
+        public Range range { get; set; }
+        public DocumentHighlightKind kind { get; set; }
+    }
+
+    public class DocumentSymbolParams: Object {
+        public TextDocumentIdentifier textDocument { get; set; }
+    }
+
+    public class DocumentSymbol : Object, Json.Serializable {
+        private Vala.SourceReference? _source_reference;
+        public string name { get; set; }
+        public string? detail { get; set; }
+        public SymbolKind kind { get; set; }
+        public bool deprecated { get; set; }
+        private Range? _initial_range;
+        public Range range {
+            owned get {
+                if (_initial_range == null)
+                    _initial_range = new Range.from_sourceref (children.first ()._source_reference);
+                
+                return children.fold<Range> ((child, current_range) => current_range.union (child.range), _initial_range);
+            }
+        }
+        public Range selectionRange { get; set; }
+        public Gee.List<DocumentSymbol> children { get; private set; default = new Gee.LinkedList<DocumentSymbol> (); }
+        public string? parent_name;
+
+        private DocumentSymbol () {}
+
+        /**
+         * @param type the data type containing this symbol, if there was one (not available for Namespaces, for example)
+         * @param sym the symbol
+         */
+         /*
+        public DocumentSymbol.from_vala_symbol (Vala.DataType? type, Vala.Symbol sym, SymbolKind kind) {
+            this.parent_name = sym.parent_symbol != null ? sym.parent_symbol.name : null;
+            this._initial_range = new Range.from_sourceref (sym.source_reference);
+            if (sym is Vala.Subroutine) {
+                var sub = (Vala.Subroutine) sym;
+                var body_sref = sub.body != null ? sub.body.source_reference : null;
+                // debug ("subroutine %s found (body @ %s)", sym.get_full_name (),
+                //         body_sref != null ? body_sref.to_string () : null);
+                if (body_sref != null && (body_sref.begin.line < body_sref.end.line ||
+                                          body_sref.begin.line == body_sref.end.line && body_sref.begin.pos <= body_sref.end.pos)) {
+                    this._initial_range = this._initial_range.union (new Range.from_sourceref (body_sref));
+                }
+            }
+            this.name = sym.name;
+            this.detail = Vls.CodeHelp.get_symbol_representation (type, sym, null, false);
+            this.kind = kind;
+            this.selectionRange = new Range.from_sourceref (sym.source_reference);
+            this.deprecated = sym.version.deprecated;
+        }
+       */
+        public new void Json.Serializable.set_property (ParamSpec pspec, Value value) {
+            base.set_property (pspec.get_name (), value);
+        }
+
+        public new Value Json.Serializable.get_property (ParamSpec pspec) {
+            Value val = Value (pspec.value_type);
+            base.get_property (pspec.get_name (), ref val);
+            return val;
+        }
+
+        public unowned ParamSpec? find_property (string name) {
+            return this.get_class ().find_property (name);
+        }
+
+        public Json.Node serialize_property (string property_name, Value value, ParamSpec pspec) {
+            if (property_name != "children")
+                return default_serialize_property (property_name, value, pspec);
+            var node = new Json.Node (Json.NodeType.ARRAY);
+            node.init_array (new Json.Array ());
+            var array = node.get_array ();
+            foreach (var child in children)
+                array.add_element (Json.gobject_serialize (child));
+            return node;
+        }
+
+        public bool deserialize_property (string property_name, out Value value, ParamSpec pspec, Json.Node property_node) {
+            error ("deserialization not supported");
+        }
+    }
+
+    public class SymbolInformation : Object {
+        public string name { get; set; }
+        public SymbolKind kind { get; set; }
+        public Location location { get; set; }
+        public string? containerName { get; set; }
+
+        public SymbolInformation.from_document_symbol (DocumentSymbol dsym, string uri) {
+            this.name = dsym.name;
+            this.kind = dsym.kind;
+            this.location = new Location (uri, dsym.range);
+            this.containerName = dsym.parent_name;
+        }
+    }
+
+    [CCode (default_value = "LSP_SYMBOL_KIND_Variable")]
+    public enum SymbolKind {
+        File = 1,
+        Module = 2,
+        Namespace = 3,
+        Package = 4,
+        Class = 5,
+        Method = 6,
+        Property = 7,
+        Field = 8,
+        Constructor = 9,
+        Enum = 10,
+        Interface = 11,
+        Function = 12,
+        Variable = 13,
+        Constant = 14,
+        String = 15,
+        Number = 16,
+        Boolean = 17,
+        Array = 18,
+        Object = 19,
+        Key = 20,
+        Null = 21,
+        EnumMember = 22,
+        Struct = 23,
+        Event = 24,
+        Operator = 25,
+        TypeParameter = 26
+    }
+
+       public class CompletionList : Object, Json.Serializable {
+        public bool isIncomplete { get; set; }
+        public Gee.List<CompletionItem> items { get; private set; default = new Gee.LinkedList<CompletionItem> (); }
+
+        public new void Json.Serializable.set_property (ParamSpec pspec, Value value) {
+            base.set_property (pspec.get_name (), value);
+        }
+
+        public new Value Json.Serializable.get_property (ParamSpec pspec) {
+            Value val = Value(pspec.value_type);
+            base.get_property (pspec.get_name (), ref val);
+            return val;
+        }
+
+        public unowned ParamSpec? find_property (string name) {
+            return this.get_class ().find_property (name);
+        }
+
+        public Json.Node serialize_property (string property_name, Value value, ParamSpec pspec) {
+            if (property_name != "items")
+                return default_serialize_property (property_name, value, pspec);
+            var node = new Json.Node (Json.NodeType.ARRAY);
+            node.init_array (new Json.Array ());
+            var array = node.get_array ();
+            foreach (var child in items)
+                array.add_element (Json.gobject_serialize (child));
+            return node;
+        }
+
+        public bool deserialize_property (string property_name, out Value value, ParamSpec pspec, Json.Node property_node) {
+            error ("deserialization not supported");
+        }
+    }
+
+    [CCode (default_value = "LSP_COMPLETION_TRIGGER_KIND_Invoked")]
+    public enum CompletionTriggerKind {
+        /**
+            * Completion was triggered by typing an identifier (24x7 code
+            * complete), manual invocation (e.g Ctrl+Space) or via API.
+            */
+        Invoked = 1,
+
+        /**
+            * Completion was triggered by a trigger character specified by
+            * the `triggerCharacters` properties of the `CompletionRegistrationOptions`.
+            */
+        TriggerCharacter = 2,
+
+        /**
+            * Completion was re-triggered as the current completion list is incomplete.
+            */
+        TriggerForIncompleteCompletions = 3
+    }
+
+    public class CompletionContext : Object {
+        public CompletionTriggerKind triggerKind { get; set;}
+        public string? triggerCharacter { get; set; }
+    }
+
+    public class CompletionParams : TextDocumentPositionParams {
+        /**
+         * The completion context. This is only available if the client specifies
+         * to send this using `ClientCapabilities.textDocument.completion.contextSupport === true`
+         */
+        public CompletionContext? context { get; set; }
+    }
+
+    public enum CompletionItemTag {
+        // Render a completion as obsolete, usually using a strike-out.
+        Deprecated = 1,
+    }
+
+    [CCode (default_value = "LSP_INSERT_TEXT_FORMAT_PlainText")]
+    public enum InsertTextFormat {
+        /**
+         * The primary text to be inserted is treated as a plain string.
+         */
+        PlainText = 1,
+
+        /**
+        * The primary text to be inserted is treated as a snippet.
+        *
+        * A snippet can define tab stops and placeholders with `$1`, `$2`
+        * and `${3:foo}`. `$0` defines the final tab stop, it defaults to
+        * the end of the snippet. Placeholders with equal identifiers are linked,
+        * that is typing in one will update others too.
+        */
+        Snippet = 2,
+    }
+
+    public class CompletionItem : Object, Gee.Hashable<CompletionItem>, Json.Serializable {
+        public string label { get; set; }
+        public CompletionItemKind kind { get; set; }
+        public string detail { get; set; }
+        public MarkupContent? documentation { get; set; }
+        public bool deprecated { get; set; }
+        public Gee.List<CompletionItemTag> tags { get; private set; default = new Gee.ArrayList<CompletionItemTag> (); }
+        public string? insertText { get; set; }
+        public InsertTextFormat insertTextFormat { get; set; default = InsertTextFormat.PlainText; }
+        private uint _hash;
+
+        private CompletionItem () {}
+
+        public CompletionItem.keyword (string keyword, string? insert_text = null, string? documentation = null) {
+            this.label = keyword;
+            this.kind = CompletionItemKind.Keyword;
+            this.insertText = insert_text;
+            if (insert_text != null && (insert_text.contains ("$0") || insert_text.contains ("${0")))
+                this.insertTextFormat = InsertTextFormat.Snippet;
+            if (documentation != null)
+                this.documentation = new MarkupContent.from_plaintext (documentation);
+            this._hash = @"$label $kind".hash ();
+        }
+
+        /**
+         * A completion suggestion from an existing Vala symbol.
+         * 
+         * @param instance_type the parent data type of data type of the expression where this symbol appears, or null
+         * @param sym the symbol itself
+         * @param scope the scope to display this in
+         * @param kind the kind of completion to display
+         * @param documentation the documentation to display
+         * @param label_override if non-null, override the displayed symbol name with this
+         */
+         /*
+        public CompletionItem.from_symbol (Vala.DataType? instance_type, Vala.Symbol sym, Vala.Scope? scope,
+            CompletionItemKind kind,
+            Vls.DocComment? documentation, string? label_override = null) {
+            this.label = label_override ?? sym.name;
+            this.kind = kind;
+            this.detail = Vls.CodeHelp.get_symbol_representation (instance_type, sym, scope, true, null, label_override, false);
+            this._hash = @"$label $kind".hash ();
+
+            if (documentation != null)
+                this.documentation = new MarkupContent.from_markdown (documentation.body);
+
+            var version = sym.get_attribute ("Version");
+            if (version != null && (version.get_bool ("deprecated") || version.get_string ("deprecated_since") != null)) {
+                this.tags.add (CompletionItemTag.Deprecated);
+                this.deprecated = true;
+            }public
+        }
+               */
+        /**
+         * A completion suggestion from a data type and a synthetic symbol name.
+         *
+         * @param symbol_type       the data type of the symbol
+         * @param symbol_name       the name of the synthetic symbol
+         * @param scope             the scope that this completion item is displayed in, or null
+         * @param kind              the type of completion to display
+         * @param documentation     the documentation for this symbol, or null
+         */
+         /*
+        public CompletionItem.from_synthetic_symbol (Vala.DataType symbol_type, string symbol_name, Vala.Scope? scope,
+                                                     CompletionItemKind kind, Vls.DocComment? documentation) {
+            this.label = symbol_name;
+            this.kind = kind;
+            this.detail = @"$(Vls.CodeHelp.get_symbol_representation (symbol_type, null, scope, true, null, null, false)) $symbol_name";
+            this._hash = @"$label $kind".hash ();
+
+            if (documentation != null)
+                this.documentation = new MarkupContent.from_markdown (documentation.body);
+        }
+        */
+               /*
+        public CompletionItem.from_unimplemented_symbol (Vala.Symbol sym, 
+                                                         string label, CompletionItemKind kind,
+                                                         string insert_text,
+                                                         Vls.DocComment? documentation) {
+            this.label = label;
+            this.kind = kind;
+            this.insertText = insert_text;
+            if (insert_text.contains ("$0") || insert_text.contains ("${0"))
+                this.insertTextFormat = InsertTextFormat.Snippet;
+            this._hash = @"$label $kind".hash ();
+            if (documentation != null)
+                this.documentation = new MarkupContent.from_markdown (documentation.body);
+        }
+        */
+
+        public uint hash () {
+            return this._hash;
+        }
+
+        public bool equal_to (CompletionItem other) {
+            return other.label == this.label && other.kind == this.kind;
+        }
+
+        public new void Json.Serializable.set_property (ParamSpec pspec, Value value) {
+            base.set_property (pspec.get_name (), value);
+        }
+
+        public new Value Json.Serializable.get_property (ParamSpec pspec) {
+            Value val = Value(pspec.value_type);
+            base.get_property (pspec.get_name (), ref val);
+            return val;
+        }
+
+        public unowned ParamSpec? find_property (string name) {
+            return this.get_class ().find_property (name);
+        }
+
+        public Json.Node serialize_property (string property_name, Value value, ParamSpec pspec) {
+            if (property_name != "tags")
+                return default_serialize_property (property_name, value, pspec);
+
+            var node = new Json.Node (Json.NodeType.ARRAY);
+            node.init_array (new Json.Array ());
+            var array = node.get_array ();
+            foreach (var tag in this.tags) {
+                array.add_int_element (tag);
+            }
+
+            return node;
+        }
+        public bool deserialize_property (string property_name, out Value value, ParamSpec pspec, Json.Node property_node) 
+        {
+               if (property_name != "tags") {
+                return default_deserialize_property (property_name, out value, pspec, property_node);
+            }
+            if (property_node.get_node_type () != Json.NodeType.ARRAY) {
+                warning ("unexpected property node type for 'arguments' %s", property_node.get_node_type ().to_string ());
+                return false;
+            }
+
+            var arguments = new Gee.ArrayList<CompletionItemTag>();
+
+            property_node.get_array ().foreach_element ((array, index, element) => {
+                try {
+                    arguments.add ((CompletionItemTag) Json.gvariant_deserialize (element, null).get_int32() );
+                } catch (Error e) {
+                    warning ("argument %u to command could not be deserialized: %s", index, e.message);
+                }
+            });
+
+            value.set_boxed (arguments);
+            return true;
+       }
+    }
+
+    public class MarkupContent : Object {
+        public string kind { get; set; }
+        public string value { get; set; }
+
+        private MarkupContent () {}
+
+        /**
+         * Create a MarkupContent with plain text.
+         */
+        public MarkupContent.from_plaintext (string doc) {
+            this.kind = "plaintext";
+            this.value = doc;
+        }
+
+        /**
+         * Create a MarkupContent with markdown text.
+         */
+        public MarkupContent.from_markdown (string doc) {
+            this.kind = "markdown";
+            this.value = doc;
+        }
+    }
+    
+    [CCode (default_value = "LSP_COMPLETION_ITEM_KIND_Text")]
+    public enum CompletionItemKind {
+        Text = 1,
+        Method = 2,
+        Function = 3,
+        Constructor = 4,
+        Field = 5,
+        Variable = 6,
+        Class = 7,
+        Interface = 8,
+        Module = 9,
+        Property = 10,
+        Unit = 11,
+        Value = 12,
+        Enum = 13,
+        Keyword = 14,
+        Snippet = 15,
+        Color = 16,
+        File = 17,
+        Reference = 18,
+        Folder = 19,
+        EnumMember = 20,
+        Constant = 21,
+        Struct = 22,
+        Event = 23,
+        Operator = 24,
+        TypeParameter = 25
+    }
+    
+    /**
+     * Capabilities of the client/editor for `textDocument/documentSymbol`
+     */
+    public class DocumentSymbolCapabilities : Object {
+        public bool hierarchicalDocumentSymbolSupport { get; set; }
+    }
+
+    /**
+     * Capabilities of the client/editor for `textDocument/rename`
+     */
+    public class RenameClientCapabilities : Object {
+        public bool prepareSupport { get; set; }
+    }
+
+    /**
+     * Capabilities of the client/editor pertaining to language features.
+     */
+    public class TextDocumentClientCapabilities : Object {
+        public DocumentSymbolCapabilities documentSymbol { get; set; default = new DocumentSymbolCapabilities ();}
+        public RenameClientCapabilities rename { get; set; default = new RenameClientCapabilities (); }
+    }
+
+    /**
+     * Capabilities of the client/editor.
+     */
+    public class ClientCapabilities : Object {
+        public TextDocumentClientCapabilities textDocument { get; set; default = new TextDocumentClientCapabilities (); }
+    }
+
+    public class InitializeParams : Object {
+        public int processId { get; set; }
+        public string? rootPath { get; set; }
+        public string? rootUri { get; set; }
+        public ClientCapabilities capabilities { get; set; default = new ClientCapabilities (); }
+    }
+
+    public class SignatureInformation : Object, Json.Serializable {
+        public string label { get; set; }
+        public MarkupContent documentation { get; set; }
+
+        public Gee.List<ParameterInformation> parameters { get; private set; default = new Gee.LinkedList<ParameterInformation> (); }
+
+        public new void Json.Serializable.set_property (ParamSpec pspec, Value value) {
+            base.set_property (pspec.get_name (), value);
+        }
+
+        public new Value Json.Serializable.get_property (ParamSpec pspec) {
+            Value val = Value(pspec.value_type);
+            base.get_property (pspec.get_name (), ref val);
+            return val;
+        }
+
+        public unowned ParamSpec? find_property (string name) {
+            return this.get_class ().find_property (name);
+        }
+
+        public Json.Node serialize_property (string property_name, Value value, ParamSpec pspec) {
+            if (property_name != "parameters")
+                return default_serialize_property (property_name, value, pspec);
+            var node = new Json.Node (Json.NodeType.ARRAY);
+            node.init_array (new Json.Array ());
+            var array = node.get_array ();
+            foreach (var child in parameters)
+                array.add_element (Json.gobject_serialize (child));
+            return node;
+        }
+
+        public bool deserialize_property (string property_name, out Value value, ParamSpec pspec, Json.Node property_node) {
+            error ("deserialization not supported");
+        }
+    }
+
+    public class SignatureHelp : Object, Json.Serializable {
+        public Gee.Collection<SignatureInformation> signatures { get; set; default = new Gee.ArrayList<SignatureInformation> (); }
+        public int activeSignature { get; set; }
+        public int activeParameter { get; set; }
+
+        public Json.Node serialize_property (string property_name, Value value, ParamSpec pspec) {
+            if (property_name != "signatures")
+                return default_serialize_property (property_name, value, pspec);
+
+            var node = new Json.Node (Json.NodeType.ARRAY);
+            node.init_array (new Json.Array ());
+            var array = node.get_array ();
+            foreach (var child in signatures)
+                array.add_element (Json.gobject_serialize (child));
+            return node;
+        }
+
+        public bool deserialize_property (string property_name, out Value value, ParamSpec pspec, Json.Node property_node) {
+            error ("deserialization not supported");
+        }
+    }
+
+    public class ParameterInformation : Object {
+        public string label { get; set; }
+        public MarkupContent documentation { get; set; }
+    }
+
+   public  class MarkedString : Object {
+        public string language { get; set; }
+        public string value { get; set; }
+    }
+
+    public class Hover : Object, Json.Serializable {
+        public Gee.List<MarkedString> contents { get; set; default = new Gee.ArrayList<MarkedString> (); }
+        public Range range { get; set; }
+
+        public new void Json.Serializable.set_property (ParamSpec pspec, Value value) {
+            base.set_property (pspec.get_name (), value);
+        }
+
+        public new Value Json.Serializable.get_property (ParamSpec pspec) {
+            Value val = Value(pspec.value_type);
+            base.get_property (pspec.get_name (), ref val);
+            return val;
+        }
+
+        public unowned ParamSpec? find_property (string name) {
+            return this.get_class ().find_property (name);
+        }
+
+        public Json.Node serialize_property (string property_name, Value value, ParamSpec pspec) {
+            if (property_name != "contents")
+                return default_serialize_property (property_name, value, pspec);
+            var node = new Json.Node (Json.NodeType.ARRAY);
+            node.init_array (new Json.Array ());
+            var array = node.get_array ();
+            foreach (var child in contents) {
+                if (child.language != null)
+                    array.add_element (Json.gobject_serialize (child));
+                else
+                    array.add_element (new Json.Node (Json.NodeType.VALUE).init_string (child.value));
+            }
+            return node;
+        }
+
+        public bool deserialize_property (string property_name, out Value value, ParamSpec pspec, Json.Node property_node) {
+            error ("deserialization not supported");
+        }
+    }
+
+    /**
+     * A textual edit applicable to a text document.
+     */
+    public class TextEdit : Object {
+        /**
+         * The range of the text document to be manipulated. To insert
+         * text into a document create a range where ``start === end``.
+         */
+        public Range range { get; set; }
+
+        /**
+         * The string to be inserted. For delete operations use an
+         * empty string.
+         */
+        public string newText { get; set; }
+
+        public TextEdit (Range range, string new_text = "") {
+            this.range = range;
+            this.newText = new_text;
+        }
+    }
+
+    /** 
+     * Describes textual changes on a single text document. The text document is
+     * referred to as a {@link VersionedTextDocumentIdentifier} to allow clients to
+     * check the text document version before an edit is applied. A
+     * {@link TextDocumentEdit} describes all changes on a version ``Si`` and after they are
+     * applied move the document to version ``Si+1``. So the creator of a
+     * {@link TextDocumentEdit} doesn’t need to sort the array of edits or do any kind
+     * of ordering. However the edits must be non overlapping.
+     */
+    public class TextDocumentEdit : Object, Json.Serializable {
+        /**
+         * The text document to change.
+         */
+        public VersionedTextDocumentIdentifier textDocument { get; set; }
+
+        /**
+         * The edits to be applied.
+         */
+        public Gee.ArrayList<TextEdit> edits { get; set; default = new Gee.ArrayList<TextEdit> (); }
+
+        public TextDocumentEdit (VersionedTextDocumentIdentifier text_document) {
+            this.textDocument = text_document;
+        }
+
+        public Json.Node serialize_property (string property_name, GLib.Value value, GLib.ParamSpec pspec) {
+            if (property_name != "edits")
+                return default_serialize_property (property_name, value, pspec);
+            
+            var node = new Json.Node (Json.NodeType.ARRAY);
+            node.init_array (new Json.Array ());
+            var array = node.get_array ();
+            foreach (var text_edit in edits) {
+                array.add_element (Json.gobject_serialize (text_edit));
+            }
+            return node;
+        }
+
+        public bool deserialize_property (string property_name, out GLib.Value value, GLib.ParamSpec pspec, Json.Node property_node) {
+            error ("deserialization not supported");
+        }
+    }
+
+    public abstract class CommandLike : Object, Json.Serializable {
+        /**
+         * The identifier of the actual command handler.
+         */
+        public string command { get; set; }
+
+        /**
+         * Arguments that the command handler should be invoked with.
+         */
+        public Array<Variant>? arguments { get; set; }
+
+        public Json.Node serialize_property (string property_name, GLib.Value value, GLib.ParamSpec pspec) {
+            if (property_name != "arguments" || arguments == null)
+                return default_serialize_property (property_name, value, pspec);
+
+            var array = new Json.Array ();
+            for (int i = 0; i < arguments.length; i++)
+                array.add_element (Json.gvariant_serialize (arguments.index (i)));
+
+            var node = new Json.Node (Json.NodeType.ARRAY);
+            node.set_array (array);
+            return node;
+        }
+
+        public bool deserialize_property (string property_name, out GLib.Value value, GLib.ParamSpec pspec, Json.Node property_node) {
+            if (property_name == "arguments") {
+                value = Value (typeof (Array));
+                if (property_node.get_node_type () != Json.NodeType.ARRAY) {
+                    warning ("unexpected property node type for 'arguments' %s", property_node.get_node_type ().to_string ());
+                    return false;
+                }
+
+                var arguments = new Array<Variant> ();
+
+                property_node.get_array ().foreach_element ((array, index, element) => {
+                    try {
+                        arguments.append_val (Json.gvariant_deserialize (element, null));
+                    } catch (Error e) {
+                        warning ("argument %u to command could not be deserialized: %s", index, e.message);
+                    }
+                });
+
+                value.set_boxed (arguments);
+                return true;
+            } else if (property_name == "command") {
+                // workaround for json-glib < 1.5.2 (Ubuntu 20.04 / eOS 6)
+                if (property_node.get_value_type () != typeof (string)) {
+                    value = "";
+                    warning ("unexpected property node type for 'commands' %s", property_node.get_node_type ().to_string ());
+                    return false;
+                }
+
+                value = property_node.get_string ();
+                return true;
+            } else {
+                return default_deserialize_property (property_name, out value, pspec, property_node);
+            }
+        }
+    }
+
+    public class ExecuteCommandParams : CommandLike {
+    }
+
+    /**
+     * Represents a reference to a command. Provides a title which will be used
+     * to represent a command in the UI. Commands are identified by a string
+     * identifier. The recommended way to handle commands is to implement their
+     * execution on the server side if the client and server provides the
+     * corresponding capabilities. Alternatively the tool extension code could
+     * handle the command. The protocol currently doesn’t specify a set of
+     * well-known commands.
+     */
+    public class Command : CommandLike {
+        /**
+         * The title of the command, like `save`.
+         */
+        public string title { get; set; }
+    }
+
+    /**
+     * A code lens represents a command that should be shown along with
+     * source text, like the number of references, a way to run tests, etc.
+     *
+     * A code lens is _unresolved_ when no command is associated to it. For
+     * performance reasons the creation of a code lens and resolving should be done
+     * in two stages.
+     */
+    public class CodeLens : Object {
+        /**
+         * The range in which this code lens is valid. Should only span a single
+         * line.
+         */
+        public Range range { get; set; }
+
+        /**
+         * The command this code lens represents.
+         */
+        public Command? command { get; set; }
+    }
+    
+    public class DocumentRangeFormattingParams : Object {
+        public TextDocumentIdentifier textDocument { get; set; }
+        public Range? range { get; set; }
+        public FormattingOptions options { get; set; }
+    }
+
+    public class FormattingOptions : Object {
+        public uint tabSize { get; set; }
+        public bool insertSpaces { get; set; }
+        public bool trimTrailingWhitespace { get; set; }
+        public bool insertFinalNewline { get; set; }
+        public bool trimFinalNewlines { get; set; }
+    }
+
+    public class CodeActionParams : Object {
+        public TextDocumentIdentifier textDocument { get; set; }
+        public Range range { get; set; }
+        public CodeActionContext context { get; set; }
+    }
+
+
+    public class CodeActionContext : Object, Json.Serializable {
+        public Gee.List<Diagnostic> diagnostics { get; set; default = new Gee.ArrayList<Diagnostic> (); }
+        public string[]? only { get; set; }
+/*
+        public bool deserialize_property (string property_name, out Value value, ParamSpec pspec, Json.Node property_node) {
+            if (property_name != "diagnostics")
+                return default_deserialize_property (property_name, out value, pspec, property_node);
+            var diags = new Gee.ArrayList<Diagnostic> ();
+            property_node.get_array ().foreach_element ((array, index, element) => {
+                try {
+                    diags.add (Vls.Util.parse_variant<Diagnostic> (Json.gvariant_deserialize (element, null)));
+                } catch (Error e) {
+                    warning ("argument %u could not be deserialized: %s", index, e.message);
+                }
+            });
+            value = diags;
+            return true;
+        }
+        */
+    }
+
+
+       public class Diagnostics : Object, Json.Serializable 
+       {
+               public string uri { get; set; }
+
+               public int version  { get; set; default = 0; }
+        public Gee.ArrayList<Diagnostic>? diagnostics { get; set; }
+                
+               public string filename { 
+                       owned get {
+                               return File.new_for_uri (this.uri).get_path();
+                       }
+                       private set {}
+               }
+               
+               public bool deserialize_property (string property_name, out GLib.Value val, GLib.ParamSpec pspec, Json.Node property_node) {
+                       if (property_name == "diagnostics") {
+                               var diags =  new Gee.ArrayList<Diagnostic> ();
+                               if (property_node.get_node_type () != Json.NodeType.ARRAY) {
+                                       val = diags;
+                                       warning ("unexpected property node type for 'arguments' %s", property_node.get_node_type ().to_string ());
+                                       return false;
+                               }
+
+                               
+
+                               property_node.get_array ().foreach_element ((array, index, element) => {
+                                        
+                                               diags.add (Json.gobject_deserialize (typeof (Lsp.Diagnostic), element) as Diagnostic );
+                                        
+                                               //warning ("argument %u to command could not be deserialized: %s", index, e.message);
+                                        
+                               });
+                               val = diags;
+                                
+                               return true;
+                       }   
+                        
+                       return default_deserialize_property (property_name, out val, pspec, property_node);
+                        
+               }
+
+               
+       }
+
+
+   public  class CodeAction : Object, Json.Serializable {
+        public string title { get; set; }
+        public string? kind { get; set; }
+        public Gee.Collection<Diagnostic>? diagnostics { get; set; }
+        public bool isPreferred { get; set; }
+        public WorkspaceEdit? edit { get; set; }
+        public Command? command { get; set; }
+        public Object? data { get; set; }
+
+        protected void add_diagnostic (Diagnostic diag) {
+            if (diagnostics == null)
+                diagnostics = new Gee.ArrayList<Diagnostic> ();
+            diagnostics.add (diag);
+        }
+
+        public override Json.Node serialize_property (string property_name, GLib.Value value, GLib.ParamSpec pspec) {
+            if (property_name != "diagnostics")
+                return default_serialize_property (property_name, value, pspec);
+
+            var array = new Json.Array ();
+            if (diagnostics != null)
+                foreach (var text_edit in diagnostics)
+                    array.add_element (Json.gobject_serialize (text_edit));
+            return new Json.Node.alloc ().init_array (array);
+        }
+    }
+
+    public class WorkspaceEdit : Object, Json.Serializable {
+        public Gee.List<TextDocumentEdit>? documentChanges { get; set; }
+
+        public Json.Node serialize_property (string property_name, GLib.Value value, GLib.ParamSpec pspec) {
+            if (property_name != "documentChanges")
+                return default_serialize_property (property_name, value, pspec);
+
+            var node = new Json.Node (Json.NodeType.ARRAY);
+            node.init_array (new Json.Array ());
+            if (documentChanges != null) {
+                var array = node.get_array ();
+                foreach (var text_edit in documentChanges) {
+                    array.add_element (Json.gobject_serialize (text_edit));
+                }
+            }
+            return node;
+        }
+    }
+
+    [Flags]
+    public enum SymbolTags {
+        NONE,
+        DEPRECATED
+    }
+
+    public class CallHierarchyItem : Object, Json.Serializable {
+        public string name { get; set; }
+        public SymbolKind kind { get; set; }
+        public SymbolTags tags { get; set; }
+        public string? detail { get; set; }
+        public string uri { get; set; }
+        public Range range { get; set; }
+        public Range selectionRange { get; set; }
+
+        public override Json.Node serialize_property (string property_name, GLib.Value value, GLib.ParamSpec pspec) {
+            if (property_name != "tags")
+                return default_serialize_property (property_name, value, pspec);
+            var array = new Json.Array ();
+            if (SymbolTags.DEPRECATED in tags)
+                array.add_int_element (SymbolTags.DEPRECATED);
+            return new Json.Node.alloc ().init_array (array);
+        }
+/*
+        public CallHierarchyItem.from_symbol (Vala.Symbol symbol) {
+            this.name = symbol.get_full_name ();
+            if (symbol is Vala.Method) {
+                if (symbol.parent_symbol is Vala.Namespace)
+                    this.kind = SymbolKind.Function;
+                else
+                    this.kind = SymbolKind.Method;
+            } else if (symbol is Vala.Signal) {
+                this.kind = SymbolKind.Event;
+            } else if (symbol is Vala.Constructor) {
+                this.kind = SymbolKind.Constructor;
+            } else {
+                this.kind = SymbolKind.Method;
+            }
+            var version = symbol.get_attribute ("Version");
+            if (version != null && (version.get_bool ("deprecated") || version.get_string ("deprecated_since") != null)) {
+                this.tags |= SymbolTags.DEPRECATED;
+            }
+            this.detail = Vls.CodeHelp.get_symbol_representation (null, symbol, null, true);
+            this.uri = File.new_for_commandline_arg (symbol.source_reference.file.filename).get_uri ();
+            this.range = new Range.from_sourceref (symbol.source_reference);
+            if (symbol.comment != null)
+                this.range = new Range.from_sourceref (symbol.comment.source_reference).union (this.range);
+            if (symbol is Vala.Subroutine && ((Vala.Subroutine)symbol).body != null)
+                this.range = new Range.from_sourceref (((Vala.Subroutine)symbol).body.source_reference).union (this.range);
+            this.selectionRange = new Range.from_sourceref (symbol.source_reference);
+        }
+        */
+    }
+
+    public class CallHierarchyIncomingCall : Json.Serializable, Object {
+        /**
+         * The method that calls the query method.
+         */
+        public CallHierarchyItem from { get; set; }
+
+        /**
+         * The ranges at which the query method is called by `from`.
+         */
+        public Gee.ArrayList<Range> fromRanges { get; set; default = new Gee.ArrayList<Range> (); }
+
+        public override Json.Node serialize_property (string property_name, GLib.Value value, GLib.ParamSpec pspec) {
+            if (property_name == "from")
+                return default_serialize_property (property_name, value, pspec);
+            var array = new Json.Array ();
+            foreach (var range in fromRanges)
+                array.add_element (Json.gobject_serialize (range));
+            return new Json.Node.alloc ().init_array (array);
+        }
+    }
+
+    public class CallHierarchyOutgoingCall : Json.Serializable, Object {
+        /**
+         * The method that the query method calls.
+         */
+        public CallHierarchyItem to { get; set; }
+
+        /**
+         * The ranges at which the method is called by the query method.
+         */
+        public Gee.ArrayList<Range> fromRanges { get; set; default = new Gee.ArrayList<Range> (); }
+
+        public override Json.Node serialize_property (string property_name, GLib.Value value, GLib.ParamSpec pspec) {
+            if (property_name == "to")
+                return default_serialize_property (property_name, value, pspec);
+            var array = new Json.Array ();
+            foreach (var range in fromRanges)
+                array.add_element (Json.gobject_serialize (range));
+            return new Json.Node.alloc ().init_array (array);
+        }
+    }
+
+    public class InlayHintParams : Json.Serializable, Object {
+        public TextDocumentIdentifier textDocument { get; set; }
+        public Range range { get; set; }
+    }
+
+    public enum InlayHintKind {
+        UNSET,
+        TYPE,
+        PARAMETER
+    }
+
+    public class InlayHint : Object {
+        public Position position { get; set; }
+        public string label { get; set; }
+        public InlayHintKind kind { get; set; }
+        public string? tooltip { get; set; }
+        public bool paddingLeft { get; set; }
+        public bool paddingRight { get; set; }
+    }
+
+   public  class TypeHierarchyItem : Object, Json.Serializable {
+        /**
+         * The name of this item
+         */
+        public string name { get; set; }
+
+        /**
+         * The kind of this item
+         */
+        public SymbolKind kind { get; set; }
+
+        /**
+         * Tags for this item
+         */
+        public SymbolTags tags { get; set; }
+
+        /**
+         * More detail for this item, e.g. the signature of a function.
+         */
+        public string? detail { get; set; }
+
+        /**
+         * The resource identifier of this item.
+         */
+        public string uri { get; set; }
+
+        /**
+         * The range enclosing this symbol not including leading/trailing
+         * whitespace, but everything else, e.g. comments and code.
+         */
+        public Range range { get; set; }
+
+        /**
+         * The range that should be selected and revealed when this symbol
+         * is being picked, e.g. the name of a function. Must be contained
+         * by {@link TypeHierarchyItem.range}
+         */
+        public Range selectionRange { get; set; }
+
+        private TypeHierarchyItem () {}
+/*
+        public TypeHierarchyItem.from_symbol (Vala.TypeSymbol symbol) {
+            this.name = symbol.get_full_name ();
+            if (symbol is Vala.Class)
+                this.kind = SymbolKind.Class;
+            else if (symbol is Vala.Delegate)
+                this.kind = SymbolKind.Interface;
+            else if (symbol is Vala.Enum)
+                this.kind = SymbolKind.Enum;
+            else if (symbol is Vala.ErrorCode)
+                this.kind = SymbolKind.EnumMember;
+            else if (symbol is Vala.ErrorDomain)
+                this.kind = SymbolKind.Enum;
+            else if (symbol is Vala.Interface)
+                this.kind = SymbolKind.Interface;
+            else if (symbol is Vala.Struct)
+                this.kind = SymbolKind.Struct;
+            else if (symbol is Vala.TypeParameter)
+                this.kind = SymbolKind.TypeParameter;
+            else {
+                this.kind = SymbolKind.Module;
+                warning ("unexpected symbol kind in type hierarchy: `%s'", symbol.type_name);
+            }
+
+            var version = symbol.get_attribute ("Version");
+            if (version != null && (version.get_bool ("deprecated") || version.get_string ("deprecated_since") != null)) {
+                this.tags |= SymbolTags.DEPRECATED;
+            }
+            this.detail = Vls.CodeHelp.get_symbol_representation (null, symbol, null, true);
+            this.uri = File.new_for_commandline_arg (symbol.source_reference.file.filename).get_uri ();
+            this.range = new Range.from_sourceref (symbol.source_reference);
+            this.selectionRange = this.range;
+
+            // widen range to include all members
+            if (symbol is Vala.ObjectTypeSymbol) {
+                foreach (var member in ((Vala.ObjectTypeSymbol)symbol).get_members ()) {
+                    if (member.source_reference != null)
+                        this.range = this.range.union (new Range.from_sourceref (member.source_reference));
+                }
+            } else if (symbol is Vala.Enum) {
+                foreach (var member in ((Vala.Enum)symbol).get_values ()) {
+                    if (member.source_reference != null)
+                        this.range = this.range.union (new Range.from_sourceref (member.source_reference));
+                }
+                foreach (var method in ((Vala.Enum)symbol).get_methods ()) {
+                    if (method.source_reference != null)
+                        this.range = this.range.union (new Range.from_sourceref (method.source_reference));
+                }
+            } else if (symbol is Vala.ErrorDomain) {
+                foreach (var member in ((Vala.ErrorDomain)symbol).get_codes ()) {
+                    if (member.source_reference != null)
+                        this.range = this.range.union (new Range.from_sourceref (member.source_reference));
+                }
+                foreach (var method in ((Vala.ErrorDomain)symbol).get_methods ()) {
+                    if (method.source_reference != null)
+                        this.range = this.range.union (new Range.from_sourceref (method.source_reference));
+                }
+            } else if (symbol is Vala.Struct) {
+                foreach (var field in ((Vala.Struct)symbol).get_fields ()) {
+                    if (field.source_reference != null)
+                        this.range = this.range.union (new Range.from_sourceref (field.source_reference));
+                }
+                foreach (var method in ((Vala.Struct)symbol).get_methods ()) {
+                    if (method.source_reference != null)
+                        this.range = this.range.union (new Range.from_sourceref (method.source_reference));
+                }
+            }
+        }
+        */
+    }
+}
\ No newline at end of file
index 7c08df7..82465d6 100644 (file)
@@ -14,6 +14,7 @@ int main (string[] args) {
        var app =  BuilderApplication.singleton(  args);
          
     Gtk.init ();
+    GtkSource.init();
  
        
        // not sure why this was done?? - it caused crash bugs on gtk_Box_gadget so removed critical.
index 0c53e8d..2d5836a 100644 (file)
@@ -149,6 +149,8 @@ roobuilder_PKGS = --pkg glib-2.0  \
                --pkg gobject-introspection-1.0 \
                --pkg libsoup-3.0 \
                --pkg roojspacker-1.4 \
+               --pkg  jsonrpc-glib-1.0 \
+               --pkg gio-unix-2.0 \
                $(roobuilder_LIBVALA) \
                $(roobuilder_GDA) \
                $(roobuilder_WEBKKIT) \
@@ -187,8 +189,10 @@ BUIDERPALETE =  Palete/Gir.vala \
                Palete/CompletionProvider.vala \
                Palete/CompileError.vala \      
                Palete/ValaCompileRequest.vala \
-               Palete/ValaCompileQueue.vala \
                Palete/Javascript.vala \
+               Palete/LanguageClient.vala \
+               Palete/LanguageClientVala.vala \
+               Palete/LanguageClientDummy.vala \
                $(roobuilder_CODEGEN)
                
 #              c/jscore_object_call_as_function.c \
@@ -233,6 +237,7 @@ roobuilder_SOURCES =  Application.vala \
                Main.vala \
                Spawn.vala \
                Resources.vala  \
+               Lsp.vala  \
                $(BUIDERJSRENDER) \
                $(BUIDERPALETE) \
                $(BUIDERPROJECT) \
index f78d7e8..ef8fcea 100644 (file)
@@ -13,14 +13,48 @@ namespace Palete {
                public JsRender.JsRender file = null;
                public string title = "";
                
-               public GLib.ListStore lines;
+               public GLib.ListStore lines { get; set ; }  // so it triggers updates?
 
-               public CompileError? parent = null;
-               public string category;
-               public string msg;
+               //public CompileError? parent = null;
+               public string category = "";
+               public string msg = "";
                public  int line { get; set; default = -1; }
 
-               public CompileError.new_line(CompileError parent, int line, string msg) 
+               
+               public CompileError.new_jserror(JsRender.JsRender file, string category, int line, string msg) 
+               {
+                       this.lines = new GLib.ListStore(typeof(CompileError));
+                       this.line = line;
+                       this.msg = msg;
+                       this.file = file;
+                       this.category = category;
+                        
+               
+               }
+
+               public CompileError.new_from_diagnostic(JsRender.JsRender file, Lsp.Diagnostic diag) 
+               {
+                       this.file = file;
+                       this.category = diag.category;
+                       this.line = (int) diag.range.start.line;
+                       this.msg = diag.message;   
+                       this.lines = new GLib.ListStore(typeof(CompileError));
+                       GLib.debug("new error %s : %d  %s %s", file.path, this.line, this.category, this.msg);
+                       
+                       
+                       
+               }
+               
+               public CompileError.new_from_file(JsRender.JsRender file, string category) 
+               {
+                       this.file = file;
+                       this.category = category;
+                       this.lines = file.getErrors(category);
+                       this.title =  file.relpath + " (" + lines.get_n_items().to_string() + ")";
+               }
+
+/*
+               public CompileError.new_line(CompileError? parent, int line, string msg) 
                {
                        this.lines = new GLib.ListStore(typeof(CompileError));
                        this.parent = parent;
@@ -31,10 +65,6 @@ namespace Palete {
                         
                
                }
-               
-               
-
-
                public CompileError.new_file(JsRender.JsRender file, Json.Object jlines, string category) 
                {
                        this.file = file;
@@ -59,28 +89,35 @@ namespace Palete {
             });
               
                }
-               
+               */
                public string file_line { // sorting?
                        set {}
                        owned get { 
-                               return this.parent == null ? this.file.relpath : 
+                               return this.line == -1 ? this.file.relpath : 
                                        (this.file.relpath + ":" + this.line.to_string("%09d")); 
                        }
                }
-               public string line_msg {
+               public string linemsg {
                        set {}
                        owned  get {
-                               return this.parent == null ? 
+                               return this.line == -1 ? 
                                         GLib.Markup.escape_text( this.file.relpath + "(" +  this.lines.n_items.to_string() + ")") :                    
                                         GLib.Markup.escape_text(this.line.to_string() + ": " + this.msg);
                        }
                }
-               
-               
+               
+               public bool hasErrors() {
+                       return this.lines.get_n_items() > 0;
+               }
+               
+               /*
+                
                public static void parseCompileResults (ValaCompileRequest req, Json.Object tree)
                {
-                       req.errorByFile = new Gee.HashMap<string,GLib.ListStore>();
-                       req.errorByType = new Gee.HashMap<string,GLib.ListStore>();
+                       //req.errorByFile = new Gee.HashMap<string,GLib.ListStore>();
+                       //req.errorByType = new Gee.HashMap<string,GLib.ListStore>();
+                       
+                       
 
                        req.errorByType.set("ERR",  new GLib.ListStore(typeof(CompileError)));
                        req.errorByType.set("WARN",  new GLib.ListStore(typeof(CompileError)));
@@ -92,6 +129,7 @@ namespace Palete {
                        
                         
                }
+       
                
                public static void jsonToListStoreProp(ValaCompileRequest req, string prop, Json.Object tree)
                {
@@ -135,7 +173,7 @@ namespace Palete {
                    req.errorByType.set(prop,ls);
                    
                }
-               
+                       
        // only used by javascript /roo errors..
                public static GLib.ListStore jsonToListStore(Project.Project project, Json.Object tree)
                {
@@ -158,7 +196,7 @@ namespace Palete {
           
                
                }
-        
+        */
                
        }
        
index f71cb43..74cca1f 100644 (file)
@@ -1,18 +1,25 @@
  
-using Gtk;
+//using Gtk;
 
 // not sure why - but extending Gtk.SourceCompletionProvider seems to give an error..
 namespace Palete {
 
     public class CompletionProvider : Object, GtkSource.CompletionProvider
     {
+
+               public JsRender.JsRender file {
+                       get { return this.editor.file; }
+                       private set {}
+               }
                public Editor editor; 
                //public WindowState windowstate;
                public CompletionModel model;
+               global::Gtk.StringFilter filter;
 
                public CompletionProvider(Editor editor)
                {
                    this.editor  = editor;
+                
                   // this.windowstate = null; // not ready until the UI is built.
                    
                }
@@ -29,17 +36,19 @@ namespace Palete {
                
                public  void activate (GtkSource.CompletionContext context, GtkSource.CompletionProposal proposal)
                {
+                       GLib.debug("compelte activate");
                        var  p = (CompletionProposal) proposal;
-                       TextMark end_mark = null;
-                       TextIter begin, end;
+                       global::Gtk.TextMark end_mark = null;
+                       global::Gtk.TextIter begin, end;
 
                        if (!context.get_bounds(out begin, out end)) {
                                return;
                        }  
                        var buffer = begin.get_buffer();
                
-                       var  word = p.get_typed_text();
+                       var  word = p.label;
                        var len = -1;
+                       
 
                        /* If the insertion cursor is within a word and the trailing characters
                         * of the word match the suffix of the proposal, then limit how much
@@ -53,7 +62,9 @@ namespace Palete {
 
                                if (word_end.forward_word_end ()) {
                                        var text = end.get_slice(word_end);
-
+                                       if (text.length > word.length) {
+                                               return;
+                                       }
                                        if (word.has_suffix (text)) {
                                                //g_assert (strlen (word) >= strlen (text));
                                                len = word.length - text.length;
@@ -80,70 +91,67 @@ namespace Palete {
 
                public  void display (GtkSource.CompletionContext context, GtkSource.CompletionProposal proposal, GtkSource.CompletionCell cell)
                {
+                       GLib.debug("compelte display");
                        var col = cell.get_column();
-                       //var p = (CompletionProposal) proposal;
+                       
+                       var p = (CompletionProposal) proposal;
                        switch(col) {
                                case GtkSource.CompletionColumn.TYPED_TEXT:
-                                       cell.set_icon_name("completion-snippet-symbolic");
+                                       cell.set_text(p.label);
                                        break;
                                case GtkSource.CompletionColumn.ICON:
-                                       cell.set_text(cell.text);
+                                       cell.set_icon_name("completion-snippet-symbolic");
                                        break;
                                case  GtkSource.CompletionColumn.COMMENT:
-                                       cell.set_text(cell.text);
+                                       cell.set_text(p.info);
                                        break;
                                case GtkSource.CompletionColumn.DETAILS:
-                                       cell.set_text(cell.text);
+                                       cell.set_text(p.text);
                                        break;
                                default:
-                                       cell.set_text(cell.text);
+                                       cell.set_text(null);
                                        break;
                        }       
                }
 
-               public  async GLib.ListModel populate_async (GtkSource.CompletionContext context, GLib.Cancellable? cancelleble)
+               
+        
+               internal  async GLib.ListModel populate_async (GtkSource.CompletionContext context, GLib.Cancellable? cancellable)
                {
+                       GLib.debug("pupoulate async");
+
+                       global::Gtk.TextIter begin, end;
+                       Lsp.CompletionList res;
+                       if (context.get_bounds (out begin, out end)) {
+                               yield this.file.getLanguageServer().completion(this.file, end.get_line(), end.get_line_offset(), 1, out res);
+                       } else {
+                               res = null;
+                       }
+                       this.model = new CompletionModel(this, context, res, cancellable); 
+                       var word = context.get_word();
                        
-                       this.model = new CompletionModel(this, context, cancelleble); 
-                       return this.model;
+                       
+                       var expression = new global::Gtk.PropertyExpression(typeof(CompletionProposal), null, "label");
+                       this.filter = new global::Gtk.StringFilter(expression);
+                       this.filter.set_search( word);
+                       var  filter_model = new global::Gtk.FilterListModel(this.model, this.filter); 
+                       filter.match_mode = global::Gtk.StringFilterMatchMode.PREFIX;
+                       filter_model.set_incremental(true);
+                       return filter_model; 
+                       
+                        
                        
                }
 
-               public  void refilter (GtkSource.CompletionContext context, GLib.ListModel in_model)
+               internal  void refilter (GtkSource.CompletionContext context, GLib.ListModel in_model)
                {
  
-                       //GtkFilterListModel *filter_model = NULL;
-                       //G//tkExpression *expression = NULL;
-                       //GtkStringFilter *filter = NULL;
-                       //GListModel *replaced_model = NULL;
-                       //char *word;
-
-                       var model = in_model;
+                       GLib.debug("pupoulate refilter");
+        
 
                        var word = context.get_word();
-                       if (model is FilterListModel) { 
-                               model = model.get_model ();
-                       }
-
-                       if (!this.model.can_filter(word)) {
-                               this.model.cancel(); 
-                               var replaced_model = new CompletionModel(this, context, this.model.cancellable);
-                               context.set_proposals_for_provider(this, replaced_model);
-                               
-                               context.set_proposals_for_provider(this, replaced_model);
-                               return;
-                       }
-                        
-                       var expression = new PropertyExpression(typeof(CompletionProposal), null, "word");
-                       var filter = new StringFilter(expression);
-                       filter.set_search( word);
-                       var  filter_model = new FilterListModel(in_model, filter); 
-                       filter_model.set_incremental(true);
-                       context.set_proposals_for_provider(this, filter_model); 
+                       this.filter.set_search(word);
                 
-
                
                }
 
@@ -178,31 +186,25 @@ namespace Palete {
                Gee.ArrayList<CompletionProposal> items;
                string search;
                int minimum_word_size = 2;
-               public Cancellable cancellable;
                
-               public CompletionModel(CompletionProvider provider, GtkSource.CompletionContext context, Cancellable cancellable)
+               public Cancellable? cancellable;
+               
+               public CompletionModel(CompletionProvider provider, GtkSource.CompletionContext context, Lsp.CompletionList? res, Cancellable? cancellable)
                {
                        this.provider = provider;
                        this.cancellable = cancellable;
                        this.items = new Gee.ArrayList<CompletionProposal>();
-                       this.search = context.get_word();
-                   if (this.search.length < this.minimum_word_size) {
-                           return;
-                   }
-                   var prov  =  this.provider;
-                       
-                       if (prov.editor.window.windowstate == null) {
-                               GLib.debug("Warning - provider windowstate not set?");
-                               return;
-                       }
-                   // now do our magic..
-                   this.items = prov.editor.window.windowstate.file.palete().suggestComplete(
-                           prov.editor.window.windowstate.file,
-                           prov.editor.node,
-                           prov.editor.prop,
-                           this.search
-                   ); 
-               
+                       
+                       var word = context.get_word();
+                       GLib.debug("looking for %s", word);
+                       this.search = word;
+                       if (res != null) {
+                               foreach(var comp in res.items) {
+                                        
+                                       this.items.add(new CompletionProposal(comp));   
+                                       
+                               }
+                       }
                    print("GOT %d results\n", (int) items.size); 
                        // WHY TWICE?
                    if (this.items.size < this.minimum_word_size) {
@@ -242,11 +244,14 @@ namespace Palete {
                        /* If the new word starts with our initial word, then we can simply
                         * refilter outside this model using a GtkFilterListModel.
                         */
+                        
                         return word.has_prefix(this.search); 
                }
                public void  cancel ()
                {
-                       this.cancellable.cancel();
+                       if (this.cancellable != null) {
+                               this.cancellable.cancel();
+                       }
                }
 
 
@@ -255,15 +260,18 @@ namespace Palete {
        public class CompletionProposal : Object, GtkSource.CompletionProposal 
        {
                
-               string label;
+               public string label { get; set; default = ""; }
                
-               public string text;
-               string info;
-               public CompletionProposal(string label, string text, string info)
+               public string text  { get; set; default = ""; }
+               public string info  { get; set; default = ""; }
+               public CompletionProposal(Lsp.CompletionItem ci) //string label, string text, string info)
                {
-                       this.text = text;
-                       this.label = label;
-                       this.info = info;
+                       
+                       
+                       this.text = ci.detail == null ? "" : ci.detail ;
+                       this.label = ci.label;
+                       this.info = ci.documentation == null ? "": ci.documentation.value;
+                       GLib.debug("SET: text=%s, label = %s; info =%s", ci.detail, ci.label, "to long..");
                }
                
        }
index 9d17b09..53873b2 100644 (file)
@@ -673,6 +673,8 @@ namespace Palete {
                ) { 
                        
                        var ret =  new Gee.ArrayList<CompletionProposal>();
+                       return ret;
+                       /*
                        // completion rules??
                        
                        // make sure data is loaded
@@ -911,6 +913,7 @@ namespace Palete {
                        
                        
                        return ret;
+                       */
                }
                
                
index ead9852..4edd521 100644 (file)
@@ -78,7 +78,7 @@ namespace Palete {
                        
 
                }
-               public Json.Object validate(string code, string fn)
+               public void validate(string code, JsRender.JsRender file)
                {
  
                        JSC.Exception? ex;
@@ -87,40 +87,21 @@ namespace Palete {
                        //GLib.debug("Check syntax %s", code);
                        
                        ctx.check_syntax(code, code.length, JSC.CheckSyntaxMode.SCRIPT, "", 1 ,out ex);
-                
+                   var ar = file.getErrors("ERR");
+                       ar.remove_all();
                        if (ex == null) {
-                               return new Json.Object(); // this.compressionErrors(code, fn); << to slow on large files?
-                       
+                               return ; // this.compressionErrors(code, fn); << to slow on large files?
                                 
                        }
  
-                       //GLib.debug("got error %d %s", (int)ex.get_line_number() , ex.get_message() );
-                       var ar  = new Json.Array();
-                       ar.add_string_element(ex.get_message());
+                       //GLib.debug("go        t error %d %s", (int)ex.get_line_number() , ex.get_message() );
                        
-                       
-
-                       var line_to_err =  new Json.Object();
 
-                       line_to_err.set_array_member(ex.get_line_number().to_string(), ar);
-                       var file_to_line =   new Json.Object();
-                       file_to_line.set_object_member(fn, line_to_err);
-                       var ret =  new Json.Object();
-                       ret.set_object_member("ERR", file_to_line);
+                       var ret = new CompileError.new_jserror(file, "ERR", (int) ex.get_line_number(), ex.get_message());
+                        
+                       ar.append(ret);
                        
-                       /*
-                       var g = new Json.Generator ();
-
-                       g.pretty = true;
-                       g.indent = 2;
-                       var n = new Json.Node(Json.NodeType.OBJECT);
-                       n.set_object(ret);
-                       g.set_root (n);
-
-                       GLib.debug("got %s", g.to_data (null));
-                       */
-                       return ret;
+                        
                        
                }
                
diff --git a/src/Palete/LanguageClient.vala b/src/Palete/LanguageClient.vala
new file mode 100644 (file)
index 0000000..d3dd092
--- /dev/null
@@ -0,0 +1,350 @@
+/**
+  generic interface to language server
+  ?? first of will be for vala... but later?
+  based on gvls-client-jsonrpc (loosly)
+  and vala-language-server
+
+*/
+
+namespace Palete {
+
+
+       public abstract class LanguageClient :   Jsonrpc.Server {
+       
+               public Project.Project project;
+               private GLib.SubprocessLauncher launcher;
+               private GLib.Subprocess subprocess;
+               private IOStream subprocess_stream;
+           public Jsonrpc.Client? jsonrpc_client = null;
+               
+               protected LanguageClient(Project.Project project)
+               {
+                       // extend versions will proably call initialize to start and connect to server.
+                       this.project = project;
+                       
+               
+               }
+                
+               public bool initProcess(string process_path)
+               {
+                       this.launcher = new GLib.SubprocessLauncher (SubprocessFlags.STDIN_PIPE | SubprocessFlags.STDOUT_PIPE);
+                       this.launcher.set_environ(GLib.Environ.get());
+                       try {
+                               this.subprocess = launcher.spawnv ({ process_path });
+                               var input_stream = this.subprocess.get_stdout_pipe ();
+                               var output_stream = this.subprocess.get_stdin_pipe ();
+                               if (input_stream is GLib.UnixInputStream && output_stream is GLib.UnixOutputStream) {
+                                       // set nonblocking
+                                       if (!GLib.Unix.set_fd_nonblocking(((GLib.UnixInputStream)input_stream).fd, true)
+                                        || !GLib.Unix.set_fd_nonblocking (((GLib.UnixOutputStream)output_stream).fd, true)) 
+                                        {
+                                                GLib.debug("could not set pipes to nonblocking");
+                                           return false;
+                                   }
+                           }
+                           this.subprocess_stream = new SimpleIOStream (input_stream, output_stream);
+                       this.accept_io_stream ( this.subprocess_stream);
+                       } catch (GLib.Error e) {
+                               GLib.debug("subprocess startup error %s", e.message);           
+                               return false;
+               }
+            return true;
+        }
+        
+               /**
+               utility method to build variant based queries
+               */
+               public Variant buildDict (...) {
+                       var builder = new GLib.VariantBuilder (new GLib.VariantType ("a{sv}"));
+                       var l = va_list ();
+                       while (true) {
+                               string? key = l.arg ();
+                               if (key == null) {
+                                       break;
+                               }
+                               Variant val = l.arg ();
+                               builder.add ("{sv}", key, val);
+                       }
+                       return builder.end ();
+               }
+                
+               public override void client_accepted (Jsonrpc.Client client) 
+               {
+                       if (this.jsonrpc_client == null) {
+                               this.jsonrpc_client = client;
+                               
+                               GLib.debug("client accepted connection - calling init server");
+                                
+
+                               this.jsonrpc_client.notification.connect((method, paramz) => {
+                                       this.onNotification(method, paramz);
+                               });
+                                
+                               this.jsonrpc_client.failed.connect(() => {
+                                       GLib.debug("language server server has failed");
+                               });
+
+                               this.initialize_server ();
+                       } 
+                                        
+                        
+               }
+               public bool isReady()
+               {
+                       if (!this.initialized) {
+                               GLib.debug("Server has not been initialized");
+                               return false;
+                       }
+                       if (this.sent_shutdown) {
+                               GLib.debug("Server has been started its shutting down process");
+                               return false;
+                       }
+                       return true;
+               }
+               
+               
+               public abstract  void initialize_server();
+               
+               //public abstract   void  initialize_server()  ;
+                
+               protected bool initialized = false;
+               bool sent_shutdown = false;
+               
+               
+               public void onNotification(string method, Variant? return_value)
+               {
+                       switch (method) {
+                               case "textDocument/publishDiagnostics":
+                                       this.onDiagnostic(return_value);
+                                       return;
+                               default: 
+                                       break;
+                                
+                       }
+                       GLib.debug("got notification %s : %s",  method , Json.to_string (Json.gvariant_serialize (return_value), true));
+                       
+               }
+               
+               /***
+               
+               */
+               public void onDiagnostic(Variant? return_value) 
+               {
+                       var dg = Json.gobject_deserialize (typeof (Lsp.Diagnostics), Json.gvariant_serialize (return_value)) as Lsp.Diagnostics; 
+                       var f = this.project.getByPath(dg.filename);
+                       if (f == null) {
+                               GLib.debug("no file %s", dg.uri);
+                               return;
+                       }
+                       foreach(var v in f.errorsByType.values) {
+                               v.remove_all();
+                       }
+                       foreach(var diag in dg.diagnostics) {
+                               var ce = new CompileError.new_from_diagnostic(f, diag);
+                               if (!f.errorsByType.has_key(ce.category)) {
+                                       f.errorsByType.set(ce.category, new  GLib.ListStore(typeof(CompileError)));
+                               }
+                               f.errorsByType.get(ce.category).append(ce);
+                       }
+                       f.project.updateErrorsforFile(f);
+                       
+               }
+               
+               public void document_open (JsRender.JsRender file)  
+               {
+                       if (!this.isReady()) {
+                               return;
+                       }
+                       GLib.debug ("LS sent open");                     
+                       try {
+                               this.jsonrpc_client.send_notification (
+                                       "textDocument/didOpen",
+                                       this.buildDict (
+                                               textDocument : this.buildDict (
+                                                       uri: new Variant.string (file.to_url()),
+                                                       languageId :  new Variant.string (file.language_id()),
+                                                       version :  new GLib.Variant.uint64 ( (uint64) file.version),
+                                                       text : new Variant.string (file.toSource())
+                                               )
+                                       ),
+                                       null
+                               );
+                       } catch( GLib.Error  e) {
+                               GLib.debug ("LS sent open err %s", e.message);
+                       }
+
+               }
+               
+               public   void document_save (JsRender.JsRender file)  
+       {
+                       if (!this.isReady()) {
+                               return;
+                       }
+                               GLib.debug ("LS send save");
+                        try {
+                                 this.jsonrpc_client.send_notification  (
+                                       "textDocument/didChange",
+                                       this.buildDict (  
+                                               textDocument : this.buildDict (    ///TextDocumentItem;
+                                                       uri: new GLib.Variant.string (file.to_url())
+                                                       
+                                               )
+                                       ),
+                                       null 
+                               );
+                       } catch( GLib.Error  e) {
+                               GLib.debug ("LS sent save err %s", e.message);
+                       }
+
+         
+       }
+               public   void document_close (JsRender.JsRender file) 
+       {
+                       if (!this.isReady()) {
+                               return;
+                       }
+                                                       GLib.debug ("LS send close");
+                       try {
+                                 this.jsonrpc_client.send_notification  (
+                                       "textDocument/didChange",
+                                       this.buildDict (  
+                                               textDocument : this.buildDict (    ///TextDocumentItem;
+                                                       uri: new GLib.Variant.string (file.to_url())
+                                                       
+                                               )
+                                       ),
+                                       null  
+                               );
+                       } catch( GLib.Error  e) {
+                               GLib.debug ("LS sent close err %s", e.message);
+                       }
+
+         
+       }
+               public    void document_change (JsRender.JsRender file)  
+       {
+                       if (!this.isReady()) {
+                               return;
+                       }
+                       GLib.debug ("LS send change");
+                       var ar = new Json.Array();
+                       var obj = new Json.Object();
+                       obj.set_string_member("text", file.toSource());
+                       ar.add_object_element(obj);
+                       var node = new Json.Node(Json.NodeType.ARRAY);
+                       node.set_array(ar);
+                        try {
+                               this.jsonrpc_client.send_notification (
+                                       "textDocument/didChange",
+                                       this.buildDict (  
+                                               textDocument : this.buildDict (    ///TextDocumentItem;
+                                                       uri: new GLib.Variant.string (file.to_url()),
+                                                       version :  new GLib.Variant.uint64 ( (uint64) file.version) 
+                                               ),
+                                               contentChanges : Json.gvariant_deserialize (node, null)
+                                               
+                                       ),
+                                       null 
+                               );
+                       } catch( GLib.Error  e) {
+                               GLib.debug ("LS sent close err %s", e.message);
+                       }
+
+         
+       }
+               public   void exit () throws GLib.Error 
+               {
+                       if (!this.isReady()) {
+                               return;
+                       }
+                       this.sent_shutdown  = true;
+                
+                         this.jsonrpc_client.send_notification_async (
+                               "exit",
+                               null,
+                               null 
+                       );
+                       
+               }
+               public async void shutdown () throws GLib.Error 
+               {
+                       if (!this.isReady()) {
+                               return;
+                       }
+                       this.sent_shutdown  = true;
+                       Variant? return_value;
+                       yield this.jsonrpc_client.call_async (
+                               "shutdown",
+                               null,
+                               null,
+                               out return_value
+                       );
+                       GLib.debug ("LS replied with %s", Json.to_string (Json.gvariant_serialize (return_value), true));               
+               }
+               //public async  ??/symbol (string symbol) throws GLib.Error {
+               
+               // and now for the important styff..
+               
+               /*
+               
+               @triggerType 1 = typing or ctl-spac, 2 = tiggercharactres?  3= inside completion?
+               */
+                public async void completion (JsRender.JsRender file, int line, int offset , int triggerType = 1, out Lsp.CompletionList? ret) throws GLib.Error 
+                {
+                       /* partial_result_token ,  work_done_token   context = null) */
+                       GLib.debug("get completion %s @ %d:%d", file.relpath, line, offset);
+                       
+                       ret = null;
+                   if (!this.isReady()) {
+                               return;
+                       }
+                       Variant? return_value;
+                       yield this.jsonrpc_client.call_async (
+                               "textDocument/completion",
+                               this.buildDict (  
+                                       context : this.buildDict (    ///CompletionContext;
+                                               triggerKind: new GLib.Variant.int32 (triggerType) 
+                                       //      triggerCharacter :  new GLib.Variant.string ("")
+                                       ),
+                                       textDocument : this.buildDict (    ///TextDocumentItem;
+                                               uri: new GLib.Variant.string (file.to_url()),
+                                               version :  new GLib.Variant.uint64 ( (uint64) file.version) 
+                                       ), 
+                                       position :  this.buildDict ( 
+                                               line :  new GLib.Variant.uint64 ( (uint64) line) ,
+                                               character :  new GLib.Variant.uint64 ( (uint64) offset) 
+                                       )
+                               ),
+                               null,
+                               out return_value
+                       );
+                       
+                       
+                       //GLib.debug ("LS replied with %s", Json.to_string (Json.gvariant_serialize (return_value), true));                                     
+                       var json = Json.gvariant_serialize (return_value);
+                       var ar = json.get_array();
+
+                       if (ar == null) {
+                               ret = Json.gobject_deserialize (typeof (Lsp.CompletionList), json) as Lsp.CompletionList; 
+                               return;
+                       }  
+                       ret = new Lsp.CompletionList(); 
+                       for(var i = 0; i < ar.get_length(); i++ ) {
+                               var add= Json.gobject_deserialize ( typeof (Lsp.CompletionItem),  ar.get_element(i)) as Lsp.CompletionItem;
+                               ret.items.add( add);
+                                        
+                       }
+                                 
+                       
+               
+
+               }
+               //CompletionListInfo.itmems.parse_varient  or CompletionListInfo.parsevarient
+
+
+               
+       }
+}
diff --git a/src/Palete/LanguageClientDummy.vala b/src/Palete/LanguageClientDummy.vala
new file mode 100644 (file)
index 0000000..f540d4f
--- /dev/null
@@ -0,0 +1,19 @@
+
+namespace Palete {
+       public class LanguageClientDummy: LanguageClient {
+       
+       
+               public LanguageClientDummy(Project.Project project)
+               {
+                       // extend versions will proably call initialize to start and connect to server.
+                       base(project);
+                       
+               
+               }
+                public override   void  initialize_server()   {
+                       GLib.debug("initialize dummy server");                  
+               }
+       
+       }
+       
+}
\ No newline at end of file
diff --git a/src/Palete/LanguageClientVala.vala b/src/Palete/LanguageClientVala.vala
new file mode 100644 (file)
index 0000000..5a9327f
--- /dev/null
@@ -0,0 +1,38 @@
+
+namespace Palete {
+       public class LanguageClientVala : LanguageClient {
+       
+       
+               public LanguageClientVala(Project.Project project)
+               {
+                       // extend versions will proably call initialize to start and connect to server.
+                       base(project);
+                       
+                       this.initProcess("/usr/bin/vala-language-server");
+                       
+               
+               }
+                public override   void  initialize_server()   {
+                       try {
+                               Variant? return_value;
+                                   this.jsonrpc_client.call (
+                                   "initialize",
+                                   this.buildDict (
+                                       processId: new Variant.int32 ((int32) Posix.getpid ()),
+                                       rootPath: new Variant.string (this.project.path),
+                                       rootUri: new Variant.string (File.new_for_path (this.project.path).get_uri ())
+                                   ),
+                                   null,
+                                   out return_value
+                               );
+                               GLib.debug ("LS replied with %s", Json.to_string (Json.gvariant_serialize (return_value), true));
+                               this.initialized = true;
+                       } catch (GLib.Error e) {
+                               GLib.debug ("LS replied with error %s", e.message);
+                       }
+                       
+               }
+       
+       }
+       
+}
\ No newline at end of file
index 82515c3..e0b9131 100644 (file)
@@ -381,6 +381,8 @@ namespace Palete {
                ) { 
                        
                        var ret =  new Gee.ArrayList<CompletionProposal>();
+                       return ret;
+                       /*
                        // completion rules??
                        
                        // Roo......
@@ -566,6 +568,7 @@ namespace Palete {
                        
                        
                        return ret;
+                       */
                }
                
                
index a66f21d..ce91997 100644 (file)
@@ -4,7 +4,7 @@
 */
 namespace Palete {
        
-       public class ValaCompileQueue : Object 
+       public class ValaCompileQueueX : Object 
        {
        
                ValaCompileRequest? next_request = null;
@@ -23,13 +23,13 @@ namespace Palete {
                
                
                
-               public ValaCompileQueue()
+               public ValaCompileQueueX()
                {
                        //start timeout for compiler.
                        
                }
                
-               public void addFile(  ValaCompileRequestType reqtype, JsRender.JsRender file , string alt_code, bool force) 
+               public void addFileX(  ValaCompileRequestType reqtype, JsRender.JsRender file , string alt_code, bool force) 
                {
                        var add = new ValaCompileRequest(
                                reqtype,
@@ -53,7 +53,7 @@ namespace Palete {
                }
                
                
-               public void addProp( ValaCompileRequestType requestType,
+               public void addPropX( ValaCompileRequestType requestType,
                        JsRender.JsRender file,
                        JsRender.Node node,
                        JsRender.NodeProp prop,
@@ -172,7 +172,7 @@ namespace Palete {
                public void onCompileComplete(ValaCompileRequest req)
                {
                        this.cur_request = null;
-                       req.file.project.last_request = req; // technically it should update compile group.
+                       //req.file.project.last_request = req; // technically it should update compile group.
                        this.last_request = req;
                        this.showSpinner(false);
                        // update errors
index 3a5a562..19beca5 100644 (file)
@@ -9,7 +9,7 @@ namespace Palete {
                RUN
        }
                
-       public class ValaCompileRequest : Object
+       public class ValaCompileRequest  : Object
        {
                ValaCompileRequestType requestType;
                
@@ -19,7 +19,7 @@ namespace Palete {
                string alt_code = "";
                string tmpfile = "";
                Spawn? compiler  = null;
-               ValaCompileQueue? queue = null;
+       ///     ValaCompileQueue? queue = null;
  
                
        
@@ -27,7 +27,7 @@ namespace Palete {
                public Gee.HashMap<string,GLib.ListStore>? errorByFile  = null;
                        
        
-               public ValaCompileRequest(
+               public ValaCompileRequest (
                        ValaCompileRequestType requestType,
                        JsRender.JsRender file ,
                        JsRender.Node? node,
@@ -107,9 +107,9 @@ namespace Palete {
                        return true;
                }
                
-               public bool run(ValaCompileQueue queue)
+               public bool run()
                {
-                       this.queue = queue;
+                       //this.queue = queue;
                        if ( this.target() == "") {
                                GLib.debug("missing target");
                                this.onCompileFail();
@@ -196,7 +196,7 @@ namespace Palete {
                        this.compiler.isZombie();
                        GLib.debug("compile got %s", output);
                        if (output == "") {
-                               this.queue.onCompileFail();
+                               BuilderApplication.showSpinner(false);
                                return;
                        }
                        
@@ -208,12 +208,12 @@ namespace Palete {
                                var node = pa.get_root();
 
                                if (node.get_node_type () != Json.NodeType.OBJECT) {
-                                       this.queue.onCompileFail();
+                                       BuilderApplication.showSpinner(false);
                                        return;
                                }
                                var ret = node.get_object ();   
-                               CompileError.parseCompileResults(this,ret);
-                               this.queue.onCompileComplete(this);
+                               //CompileError.parseCompileResults(this,ret);
+                               BuilderApplication.showSpinner(false);
                                
                        
                                
@@ -221,12 +221,12 @@ namespace Palete {
                                
                        } catch (GLib.Error e) {
                                GLib.debug("parsing output got error %s", e.message);
-                               this.queue.onCompileFail();
+                               BuilderApplication.showSpinner(false);
                                return;
                                
                        }
                        if (this.requestType == ValaCompileRequestType.RUN) {
-                               this.queue.execResult(this);
+                               this.execResult();
                        }
                }
                 
@@ -262,21 +262,109 @@ namespace Palete {
                        return ret;
                }
                
-               public void runJavascript(ValaCompileQueue queue)
+               public void runJavascript( )
                {
-                       this.queue = queue;
+                       //this.queue = queue;
                 
                        var contents = this.alt_code == "" ? this.file.toSourceCode() : this.generateTempContents();
                        
-                       var ret = Javascript.singleton().validate(contents, this.file.targetName());
-                
-                       CompileError.parseCompileResults(this,ret);
-                       this.queue.onCompileComplete(this);
+                       Javascript.singleton().validate(contents, this.file );
+                       
+                       
+                        
+                       BuilderApplication.showSpinner(false);
+                       BuilderApplication.updateCompileResults();
+                       
+                       //this.queue.onCompileComplete(this);
                                
                         
                  // see pack file (from palete/palete..palete_palete_javascriptHasCompressionErrors.)
                  
                }
+               public void killChildren(int pid)
+               {
+                       if (pid < 1) {
+                               return;
+                       }
+                       var cn = "/proc/%d/task/%d/children".printf(pid,pid);
+                       if (!FileUtils.test(cn, GLib.FileTest.EXISTS)) {
+                               GLib.debug("%s doesnt exist - killing %d", cn, pid);
+                               Posix.kill(pid, 9);
+                               return;
+                       }
+                       string cpids = "";
+                       try {
+                               FileUtils.get_contents(cn, out cpids);
+                       
+
+                               if (cpids.length > 0) {
+                                       this.killChildren(int.parse(cpids));
+                               }
+
+                       } catch (GLib.FileError e) {
+                               // skip
+                       }
+                       GLib.debug("killing %d", pid);  
+                       Posix.kill(pid, 9);
+               }
+               
+               int terminal_pid = 0;
+               public void execResult()
+               {
+                               
+                       this.killChildren(this.terminal_pid);
+                       this.terminal_pid = 0;
+                         
+                       var exe = this.target();
+                       var pr = (Project.Gtk) this.file.project;
+                       var cg =  pr.compilegroups.get(exe);
+                       
+                       if (!GLib.FileUtils.test(exe, GLib.FileTest.EXISTS)) {
+                               print("Missing output file: %s\n",exe);
+                               return;
+                       }
+                       var gdb_cfg= pr.path + "/build/.gdb-script";
+                       if (!GLib.FileUtils.test(gdb_cfg, GLib.FileTest.EXISTS)) {
+                               pr.writeFile("build/.gdb-script", "set debuginfod enabled off\nr");
+                       }
+                       
+                       
+                       
+                       string[] args = "/usr/bin/gnome-terminal --disable-factory --wait -- /usr/bin/gdb -x".split(" ");
+
+                       args+= gdb_cfg;
+                       args += exe;
+                       if (cg.execute_args.length > 0) {
+                               args+= "--args";
+                               var aa = cg.execute_args.split(" ");
+                               for (var i =0; i < aa.length; i++) {
+                                       args += aa[i];
+                               }
+                       }
+
+                 
+                   
+                   // should be home directory...
+                   
+                   
+                   try {
+                   
+                       var exec = new Spawn(pr.path , args);
+                       exec.env = GLib.Environ.get();
+                        
+                       exec.detach = true;
+                               exec.run(); 
+
+                               this.terminal_pid = exec.pid;
+                               GLib.debug("Child PID = %d", this.terminal_pid);
+                               
+                   } catch(GLib.Error e) {
+                               GLib.debug("Failed to spawn: %s", e.message);
+                               return;
+                       }
+                       
+               }
                
        } 
                
index b44208d..a502648 100644 (file)
@@ -207,7 +207,32 @@ namespace Project
                {
                        return this.pathsMatching("vapi", false);
                }
+               
+               
+                
+               public override Palete.LanguageClient getLanguageServer(string lang)
+               {
+                       if (this.language_servers.has_key(lang)) {
+                               return this.language_servers.get(lang);
+                       }
+                       switch( lang ) {
+                               case "vala":
+                                       this.language_servers.set(lang, new Palete.LanguageClientVala(this));
+                                       break;
+                               default :
+                                        return this.language_servers.get("dummy");
+                                        
+                               }
+                               return this.language_servers.get(lang);
+               
+               }
+                
+                
+                
                 
+                
+                
+                // ------------------  new project stufff
                public override void initialize()
                {
                        string[] dirs = {
@@ -367,10 +392,10 @@ namespace Project
  
                        
                
- public override void   initDatabase()
-    {
-         // nOOP
-    }
               public override void   initDatabase()
+               {
+                    // nOOP
+               }
        }
         
    
index 361648b..d10c23a 100644 (file)
@@ -83,7 +83,12 @@ namespace Project {
                 
                private bool is_scanned = false; 
                public  Gee.HashMap<string,Palete.GirObject> gir_cache = null; // used by Gir ??? is this used by Roo?
-                public Palete.ValaCompileRequest last_request = null;
+               //public Palete.ValaCompileRequest last_request = null; // depricated?
+               public Gee.HashMap<string,GLib.ListStore>? errorsByType = null;
+               
+               
+               protected Gee.HashMap<string,Palete.LanguageClient> language_servers;
                
                protected Project (string path) {
                        
@@ -96,8 +101,9 @@ namespace Project {
                        //XObject.extend(this, cfg);
                        //this.files = { }; 
                        this.path = path;
-                        
-                       
+                       this.language_servers = new Gee.HashMap<string,Palete.LanguageClient>();
+                       this.language_servers.set("dummy", new Palete.LanguageClientDummy(this));
+                       this.errorsByType = new  Gee.HashMap<string,GLib.ListStore>();
                        
                }
                 
@@ -116,7 +122,7 @@ namespace Project {
                                try {
                                        dir.make_directory();
                                } catch(GLib.Error e) {
-                                       GLib.error("could not make builder directory");
+                                       GLib.error("could not make builder directory %s", e.message);
                                }
                                return;
                        }
@@ -595,10 +601,10 @@ namespace Project {
         
         
         
-               public JsRender.JsRender? getByName(string name)
+               public JsRender.JsRender? getByRelPath(string relpath)
                {
                        foreach(var f in this.files.values) {
-                               if (f.name == name) {
+                               if (f.relpath == relpath || f.relTargetName() == relpath) {
                                        return f;
                                }
                        };
@@ -611,7 +617,7 @@ namespace Project {
                 
                        // keys are not paths...
                        foreach(var f in this.files.values) {
-                               GLib.debug("check %s = %s ? %s", path, f.path, f.targetName());
+                               //GLib.debug("check %s = %s ? %s", path, f.path, f.targetName());
                                if (f.path == path || f.targetName() == path) {
                                        return f;
                                }
@@ -987,6 +993,50 @@ namespace Project {
                        return ret;
                }
                
+               public void updateErrorsforFile(JsRender.JsRender f) 
+               {
+                       var n = this.updateErrorsByType(f, "WARN");
+                       n += this.updateErrorsByType(f, "ERR");
+                       n += this.updateErrorsByType(f, "DEPR");
+                       
+                       if (n > 0) {
+                               BuilderApplication.updateCompileResults();
+                       }
+                       
+               }
+               public int  updateErrorsByType(JsRender.JsRender f, string n) 
+               {
+                       var ls = this.getErrors(n);
+                       
+                       // remove thie file from the list.      
+                       for(var i =0; i < ls.get_n_items(); i++) {
+                               var ce = ls.get_item(i) as Palete.CompileError;
+                               if (ce.file.path == f.path) {
+                                       ls.remove(i);
+                                       break;
+                               }
+                       }
+                       var add = new Palete.CompileError.new_from_file(f, n);
+                       if (add.hasErrors()) {
+                               ls.append(add);
+                               return 1;
+                       }
+                       return 0;
+               }
+               public GLib.ListStore getErrors(string n)
+               {
+                       var ls = this.errorsByType.get(n);
+                       if (ls == null) {
+                               ls = new GLib.ListStore(typeof(Palete.CompileError));
+                               this.errorsByType.set(n, ls );
+                       }
+                       return ls;
+               }
+               
+               
+               public abstract Palete.LanguageClient  getLanguageServer(string lang);
+               
+               
                public abstract void onSave(); // write meson?
                public abstract void initDatabase();
                public abstract void initialize(); // for new projects (make dirs?);
index 04de676..1c5dec4 100644 (file)
@@ -86,6 +86,11 @@ public class Project.Roo : Project {
                 // nope
        }
 
+       public override Palete.LanguageClient getLanguageServer(string lang)
+       {
+                 return this.language_servers.get("dummy");
+       }
+
 }
  
  
\ No newline at end of file