From: Alan Knowles Date: Sun, 28 Jan 2024 12:43:41 +0000 (+0800) Subject: Fix #7991 - better updateing of error status and char position of errors X-Git-Tag: release-5.0.2~23 X-Git-Url: http://git.roojs.org/?p=roobuilder;a=commitdiff_plain;h=042e9d4a0fbdacac933b2a2df0625b7ba4bd7674 Fix #7991 - better updateing of error status and char position of errors --- diff --git a/debian/changelog b/debian/changelog index dc0d47b88..91557a466 100644 --- a/debian/changelog +++ b/debian/changelog @@ -6,7 +6,8 @@ roobuilder (5.0.2) UNRELEASED; urgency=medium * Changing property key now triggers save/language server * Fixed sending wrong 'save' to language-server (caused LS to crash) * Fixed Gtkview - uses toSource(), rather than file.get_contents() - + * Fixed updating of errors (should only update changed error mark or tree item)) + -- Alan Knowles Sun, 28 Jan 2024 06:54:56 +0800 diff --git a/src/Application.vala b/src/Application.vala index 93bf147e4..cfe0fe03a 100644 --- a/src/Application.vala +++ b/src/Application.vala @@ -684,9 +684,9 @@ flutter-project - was try and read flutter data (but desnt work.) public static void updateCompileResults( ) { - queue_update_compile_countdown = 4; // 1 second after last call. + queue_update_compile_countdown = 2; // 1 second after last call. if (queue_update_compile_id == 0) { - queue_update_compile_id = GLib.Timeout.add(250, () => { + queue_update_compile_id = GLib.Timeout.add(100, () => { if (queue_update_compile_countdown < 0) { return true; } diff --git a/src/Builder4/Editor.bjs b/src/Builder4/Editor.bjs index 9b3979cd9..730bc8c5a 100644 --- a/src/Builder4/Editor.bjs +++ b/src/Builder4/Editor.bjs @@ -10,6 +10,7 @@ "# Xcls_MainWindow window" : "null", "# bool dirty" : false, "# bool pos" : false, + "# int last_error_counter" : 0, "# int pos_root_x" : "", "# int pos_root_y" : "", "# string activeEditor" : "\"\"", @@ -632,6 +633,7 @@ " _this.dirty = false;", " this.el.grab_focus();", " _this.save_button.el.sensitive = false;", + " _this.last_error_counter = -1;", "}" ] } @@ -1065,7 +1067,7 @@ "}" ], "| void updateErrorMarks" : [ - "(string category) {", + "() {", "\t", " ", "", @@ -1074,7 +1076,8 @@ "\tGtk.TextIter end; ", "\tbuf.get_bounds (out start, out end);", "", - "\tbuf.remove_source_marks (start, end, category);", + "\t", + "", " ", "\t//GLib.debug(\"highlight errors\");\t\t ", "", @@ -1095,52 +1098,66 @@ "\t\treturn;", "", "\t}", - "\tvar ar = this.file.getErrors(category);", - "\tif (ar == null || ar.get_n_items() < 1) {", + "\tvar ar = this.file.getErrors();", + "\tif (ar.size < 1) {", + "\t\tbuf.remove_source_marks (start, end, null);", + "\t\tthis.last_error_counter = file.error_counter ;", "\t\t//GLib.debug(\"highlight %s : %s has no errors\", this.file.relpath, category);", "\t\treturn;", "\t}", - " ", + "\t", "", - " ", + " // basicaly check if there is no change, then we do not do any update..", + " // we can do this by just using an error counter?", + " // if that's changed then we will do an update, otherwise dont bother.", + "\t ", "\t", "\tvar offset = 0;", - "\t ", + "\tvar hoffset = 0;", "", "\tvar tlines = buf.get_line_count () +1;", "\t", "\tif (_this.prop != null) {", "\t\t// this still seems flaky...", - "\t\t", + "", "\t\ttlines = _this.prop.end_line;", "\t\toffset = _this.prop.start_line;", + "\t\thoffset = _this.node.node_pad.length;", + "\t\t", "\t\t ", - "\t}", - "\t ", - "\tfor (var i = 0; i < ar.get_n_items();i++) {", - "\t\tvar err = (Palete.CompileError) ar.get_item(i);", + "\t} else {", + "\t\t// no update...", + "\t\tif (this.last_error_counter == file.error_counter) {", "\t\t", + "\t\t\treturn;", + "\t\t}", + "\t", + "\t}", + "\tbuf.remove_source_marks (start, end, null);", + "\tforeach(var diag in ar) { ", "\t Gtk.TextIter iter;", "// print(\"get inter\\n\");", - "\t var eline = err.line - offset;", + "\t var eline = (int)diag.range.start.line - offset;", + "\t //var eline = diag.range.end_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 continue;", "\t }", "\t ", "\t ", - "\t buf.get_iter_at_line( out iter, eline);", + "\t buf.get_iter_at_line_offset( out iter, eline, (int)diag.range.start.character - hoffset);", "\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\tvar msg = \"Line: %d %s : %s\".printf(eline+1, diag.category, diag.message);", + "\t buf.create_source_mark( msg, diag.category, iter);", "\t // GLib.debug(\"set line %d to %s\", eline, msg);", "\t //this.marks.set(eline, msg);", "\t}", - "\treturn ;", + "\tthis.last_error_counter = file.error_counter ;", "", "", "", diff --git a/src/Builder4/Editor.vala b/src/Builder4/Editor.vala index 6a3b20e9c..027d2418b 100644 --- a/src/Builder4/Editor.vala +++ b/src/Builder4/Editor.vala @@ -32,6 +32,7 @@ public class Editor : Object public bool dirty; public int pos_root_y; public bool pos; + public int last_error_counter; public GtkSource.SearchContext searchcontext; public int last_search_end; public signal void save (); @@ -50,6 +51,7 @@ public class Editor : Object this.window = null; this.dirty = false; this.pos = false; + this.last_error_counter = 0; this.searchcontext = null; this.last_search_end = 0; this.file = null; @@ -240,7 +242,7 @@ public class Editor : Object } - public void updateErrorMarks (string category) { + public void updateErrorMarks () { @@ -249,7 +251,8 @@ public class Editor : Object Gtk.TextIter end; buf.get_bounds (out start, out end); - buf.remove_source_marks (start, end, category); + + //GLib.debug("highlight errors"); @@ -270,52 +273,66 @@ public class Editor : Object return; } - var ar = this.file.getErrors(category); - if (ar == null || ar.get_n_items() < 1) { + var ar = this.file.getErrors(); + if (ar.size < 1) { + buf.remove_source_marks (start, end, null); + this.last_error_counter = file.error_counter ; //GLib.debug("highlight %s : %s has no errors", this.file.relpath, category); return; } - + - + // basicaly check if there is no change, then we do not do any update.. + // we can do this by just using an error counter? + // if that's changed then we will do an update, otherwise dont bother. + var offset = 0; - + var hoffset = 0; var tlines = buf.get_line_count () +1; if (_this.prop != null) { // this still seems flaky... - + tlines = _this.prop.end_line; offset = _this.prop.start_line; + hoffset = _this.node.node_pad.length; + - } - - for (var i = 0; i < ar.get_n_items();i++) { - var err = (Palete.CompileError) ar.get_item(i); + } else { + // no update... + if (this.last_error_counter == file.error_counter) { + return; + } + + } + buf.remove_source_marks (start, end, null); + foreach(var diag in ar) { Gtk.TextIter iter; // print("get inter\n"); - var eline = err.line - offset; + var eline = (int)diag.range.start.line - offset; + //var eline = diag.range.end_line - offset; //GLib.debug("GOT ERROR on line %d -- converted to %d (offset = %d)", // err.line ,eline, offset); if (eline > tlines || eline < 0) { - return; + + continue; } - buf.get_iter_at_line( out iter, eline); + buf.get_iter_at_line_offset( out iter, eline, (int)diag.range.start.character - hoffset); - var msg = "Line: %d %s : %s".printf(eline+1, err.category, err.msg); - buf.create_source_mark( msg, err.category, iter); + var msg = "Line: %d %s : %s".printf(eline+1, diag.category, diag.message); + buf.create_source_mark( msg, diag.category, iter); // GLib.debug("set line %d to %s", eline, msg); //this.marks.set(eline, msg); } - return ; + this.last_error_counter = file.error_counter ; @@ -776,6 +793,7 @@ public class Editor : Object _this.dirty = false; this.el.grab_focus(); _this.save_button.el.sensitive = false; + _this.last_error_counter = -1; } } public class Xcls_buffer : Object diff --git a/src/Builder4/GtkView.bjs b/src/Builder4/GtkView.bjs index 1184e246d..d48b32a98 100644 --- a/src/Builder4/GtkView.bjs +++ b/src/Builder4/GtkView.bjs @@ -32,6 +32,7 @@ "bool hexpand" : true, "bool vexpand" : true, "id" : "GtkView", + "int last_error_counter" : 0, "int last_search_end" : 0, "items" : [ { @@ -882,15 +883,17 @@ " if (file.tree == null) {", " return;", " }", + " this.last_error_counter = -1;", " this.notebook.el.page = 0;// gtk preview ", " ", " ", " ", " this.file = file; ", " this.sourceview.loadFile();", + " ", " this.searchcontext = null;", - " ", - "", + " this.last_error_counter = -1;", + "\t\tthis.updateErrorMarks();", " if (this.lastObj != null) {", " this.container.el.remove(this.lastObj);", " }", @@ -926,19 +929,7 @@ " this.createThumb();", " ", " \t ", - " return;/*", - "\tvar x = new JsRender.NodeToGtk((Project.Gtk) file.project, file.tree);", - " var obj = x.munge() as Gtk.Widget;", - " this.lastObj = null;", - "\tif (obj == null) {", - " \treturn;", - "\t}", - "\tthis.lastObj = obj;", - " ", - " this.container.el.append(obj);", - " obj.show();", - " ", - " */", + " ", " ", "}", " " @@ -968,7 +959,7 @@ "" ], "| void updateErrorMarks" : [ - "(string category) {", + "() {", "\t", " ", "", @@ -977,7 +968,7 @@ "\tGtk.TextIter end; ", "\tbuf.get_bounds (out start, out end);", "", - "\tbuf.remove_source_marks (start, end, category);", + "", " ", "\tGLib.debug(\"highlight errors\");\t\t ", "", @@ -991,12 +982,17 @@ "\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);", + "\tvar ar = this.file.getErrors();", + "\tif (ar.size < 1) {", + "\t\tbuf.remove_source_marks (start, end, null);", + "\t\tthis.last_error_counter = file.error_counter ;", + "\t\tGLib.debug(\"higjlight has no errors\");", "\t\treturn;", "\t}", - " ", + " \tif (this.last_error_counter == file.error_counter) {", + "\t\treturn;", + "\t}", + "\t", "", " ", "\t ", @@ -1005,15 +1001,13 @@ "\t", " ", "\t ", - "\tfor (var i = 0; i < ar.get_n_items();i++) {", - "\t\tvar err = (Palete.CompileError) ar.get_item(i);", + "\tbuf.remove_source_marks (start, end, null);", + "\tforeach(var diag in ar) { ", + "\t", "\t\t", "\t Gtk.TextIter iter;", "// print(\"get inter\\n\");", - "\t var eline = err.line + 1;", - "\t GLib.debug(\"GOT ERROR on line %d -- converted to %d \",", - "\t \terr.line ,eline);", - "\t ", + "\t var eline = (int)diag.range.start.line ;", "\t ", "\t if (eline > tlines || eline < 0) {", "\t return;", @@ -1023,12 +1017,13 @@ "\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 ", + "\t\tvar msg = \"Line: %d %s : %s\".printf(eline+1, diag.category, diag.message);", + "\t buf.create_source_mark( msg, diag.category, iter);", "\t GLib.debug(\"set line %d to %s\", eline, msg);", "\t //this.marks.set(eline, msg);", "\t}", - "\treturn ;", + "\tthis.last_error_counter = file.error_counter ;", "", "", "", diff --git a/src/Builder4/GtkView.vala b/src/Builder4/GtkView.vala index 44304406d..d7a1ee937 100644 --- a/src/Builder4/GtkView.vala +++ b/src/Builder4/GtkView.vala @@ -34,6 +34,7 @@ public class Xcls_GtkView : Object public Gtk.CssProvider css; public Xcls_MainWindow main_window; public GtkSource.SearchContext searchcontext; + public int last_error_counter; public int last_search_end; public JsRender.JsRender file; @@ -45,6 +46,7 @@ public class Xcls_GtkView : Object // my vars (dec) this.lastObj = null; + this.last_error_counter = 0; this.last_search_end = 0; this.file = null; @@ -82,15 +84,17 @@ public class Xcls_GtkView : Object if (file.tree == null) { return; } + this.last_error_counter = -1; this.notebook.el.page = 0;// gtk preview this.file = file; this.sourceview.loadFile(); + this.searchcontext = null; - - + this.last_error_counter = -1; + this.updateErrorMarks(); if (this.lastObj != null) { this.container.el.remove(this.lastObj); } @@ -126,19 +130,7 @@ public class Xcls_GtkView : Object this.createThumb(); - return;/* - var x = new JsRender.NodeToGtk((Project.Gtk) file.project, file.tree); - var obj = x.munge() as Gtk.Widget; - this.lastObj = null; - if (obj == null) { - return; - } - this.lastObj = obj; - - this.container.el.append(obj); - obj.show(); - - */ + } public void highlightNodeAtLine (int ln) { @@ -328,7 +320,7 @@ public class Xcls_GtkView : Object } - public void updateErrorMarks (string category) { + public void updateErrorMarks () { @@ -337,7 +329,7 @@ public class Xcls_GtkView : Object Gtk.TextIter end; buf.get_bounds (out start, out end); - buf.remove_source_marks (start, end, category); + GLib.debug("highlight errors"); @@ -351,12 +343,17 @@ public class Xcls_GtkView : Object return; } - var ar = this.file.getErrors(category); - if (ar == null || ar.get_n_items() < 1) { - GLib.debug("higjlight %s has no errors", category); + var ar = this.file.getErrors(); + if (ar.size < 1) { + buf.remove_source_marks (start, end, null); + this.last_error_counter = file.error_counter ; + GLib.debug("higjlight has no errors"); return; } - + if (this.last_error_counter == file.error_counter) { + return; + } + @@ -365,15 +362,13 @@ public class Xcls_GtkView : Object - for (var i = 0; i < ar.get_n_items();i++) { - var err = (Palete.CompileError) ar.get_item(i); + buf.remove_source_marks (start, end, null); + foreach(var diag in ar) { + Gtk.TextIter iter; // print("get inter\n"); - var eline = err.line + 1; - GLib.debug("GOT ERROR on line %d -- converted to %d ", - err.line ,eline); - + var eline = (int)diag.range.start.line ; if (eline > tlines || eline < 0) { return; @@ -383,12 +378,13 @@ public class Xcls_GtkView : Object 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); + + var msg = "Line: %d %s : %s".printf(eline+1, diag.category, diag.message); + buf.create_source_mark( msg, diag.category, iter); GLib.debug("set line %d to %s", eline, msg); //this.marks.set(eline, msg); } - return ; + this.last_error_counter = file.error_counter ; diff --git a/src/Builder4/MainWindow.bjs b/src/Builder4/MainWindow.bjs index 53ac0f249..1ffe5b1a6 100644 --- a/src/Builder4/MainWindow.bjs +++ b/src/Builder4/MainWindow.bjs @@ -516,7 +516,7 @@ "string label" : "0 Errors", "xtype" : "Button", "| void setNotices" : [ - "(GLib.ListStore nots, GLib.ListStore fe ) {", + "(GLib.ListStore nots, int ferrors ) {", " BuilderApplication.showSpinner(\"\");", " if (nots.get_n_items() < 1 ) {", " \tthis.el.hide();", @@ -527,7 +527,7 @@ " }", " ", " this.el.show();", - " this.el.label = \"%d/%d Errors\".printf((int)fe.get_n_items(),(int)nots.get_n_items());", + " this.el.label = \"%d/%d Errors\".printf(ferrors,(int)nots.get_n_items());", "", " ", " ", @@ -565,7 +565,7 @@ "string label" : "0 Warnings", "xtype" : "Button", "| void setNotices" : [ - "(GLib.ListStore nots, GLib.ListStore fe ) {", + "(GLib.ListStore nots, int ferrs ) {", " ", " if (nots.get_n_items() < 1 ) {", " \tthis.el.hide();", @@ -576,7 +576,7 @@ " }", " ", " this.el.show();", - " this.el.label = \"%d/%d Warnings\".printf((int)fe.get_n_items(),(int)nots.get_n_items());", + " this.el.label = \"%d/%d Warnings\".printf(ferrs,(int)nots.get_n_items());", "", " ", " ", @@ -615,7 +615,7 @@ "xtype" : "Button", "| void setNotices" : [ "", - "(GLib.ListStore nots, GLib.ListStore fe ) {", + "(GLib.ListStore nots, int ferrs ) {", " ", " if (nots.get_n_items() < 1 ) {", " \tthis.el.hide();", @@ -626,7 +626,7 @@ " }", " ", " 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(ferrs,(int)nots.get_n_items());", "", " ", " ", @@ -858,18 +858,18 @@ "\t", "\tthis.statusbar_errors.setNotices(", "\t\tpr,", - "\t\tthis.windowstate.file.getErrors(\"ERR\")", + "\t\tthis.windowstate.file.getErrorsTotal(\"ERR\")", "\t);", "\t", "\tthis.statusbar_warnings.setNotices(", "\t\tthis.windowstate.project.getErrors(\"WARN\"),", - "\t\tthis.windowstate.file.getErrors(\"WARN\")", + "\t\tthis.windowstate.file.getErrorsTotal(\"WARN\")", "\t);", "\tthis.statusbar_depricated.setNotices(", "\t\tthis.windowstate.project.getErrors(\"DEPR\"),", - "\t\tthis.windowstate.file.getErrors(\"DEPR\")", + "\t\tthis.windowstate.file.getErrorsTotal(\"DEPR\")", "\t);", - " ", + "", "\t_this.statusbar_run.el.hide();", "", "\tif (pr.get_n_items() < 1) {", diff --git a/src/Builder4/MainWindow.vala b/src/Builder4/MainWindow.vala index 665be5f83..ed15fc2f8 100644 --- a/src/Builder4/MainWindow.vala +++ b/src/Builder4/MainWindow.vala @@ -111,18 +111,18 @@ public class Xcls_MainWindow : Object this.statusbar_errors.setNotices( pr, - this.windowstate.file.getErrors("ERR") + this.windowstate.file.getErrorsTotal("ERR") ); this.statusbar_warnings.setNotices( this.windowstate.project.getErrors("WARN"), - this.windowstate.file.getErrors("WARN") + this.windowstate.file.getErrorsTotal("WARN") ); this.statusbar_depricated.setNotices( this.windowstate.project.getErrors("DEPR"), - this.windowstate.file.getErrors("DEPR") + this.windowstate.file.getErrorsTotal("DEPR") ); - + _this.statusbar_run.el.hide(); if (pr.get_n_items() < 1) { @@ -1277,7 +1277,7 @@ public class Xcls_MainWindow : Object } // user defined functions - public void setNotices (GLib.ListStore nots, GLib.ListStore fe ) { + public void setNotices (GLib.ListStore nots, int ferrors ) { BuilderApplication.showSpinner(""); if (nots.get_n_items() < 1 ) { this.el.hide(); @@ -1288,7 +1288,7 @@ public class Xcls_MainWindow : Object } this.el.show(); - this.el.label = "%d/%d Errors".printf((int)fe.get_n_items(),(int)nots.get_n_items()); + this.el.label = "%d/%d Errors".printf(ferrors,(int)nots.get_n_items()); @@ -1339,7 +1339,7 @@ public class Xcls_MainWindow : Object } // user defined functions - public void setNotices (GLib.ListStore nots, GLib.ListStore fe ) { + public void setNotices (GLib.ListStore nots, int ferrs ) { if (nots.get_n_items() < 1 ) { this.el.hide(); @@ -1350,7 +1350,7 @@ public class Xcls_MainWindow : Object } this.el.show(); - this.el.label = "%d/%d Warnings".printf((int)fe.get_n_items(),(int)nots.get_n_items()); + this.el.label = "%d/%d Warnings".printf(ferrs,(int)nots.get_n_items()); @@ -1402,7 +1402,7 @@ public class Xcls_MainWindow : Object } // user defined functions - public void setNotices (GLib.ListStore nots, GLib.ListStore fe ) { + public void setNotices (GLib.ListStore nots, int ferrs ) { if (nots.get_n_items() < 1 ) { this.el.hide(); @@ -1413,7 +1413,7 @@ public class Xcls_MainWindow : Object } 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(ferrs,(int)nots.get_n_items()); diff --git a/src/Builder4/WindowRooView.bjs b/src/Builder4/WindowRooView.bjs index 22823176d..e9da027dc 100644 --- a/src/Builder4/WindowRooView.bjs +++ b/src/Builder4/WindowRooView.bjs @@ -12,6 +12,7 @@ "bool hexpand" : true, "bool vexpand" : true, "id" : "WindowRooView", + "int last_error_counter" : 0, "int last_search_end" : 0, "items" : [ { @@ -1576,6 +1577,8 @@ " this.view.renderJS(true);", " this.notebook.el.page = 0;// gtk preview ", " this.sourceview.loadFile(); ", + " this.last_error_counter = -1;", + " this.updateErrorMarks();", "}", " ", " " @@ -1611,7 +1614,7 @@ "" ], "| void updateErrorMarks" : [ - "(string category) {", + "() {", "\t", " ", "", @@ -1620,7 +1623,7 @@ "\tGtk.TextIter end; ", "\tbuf.get_bounds (out start, out end);", "", - "\tbuf.remove_source_marks (start, end, category);", + "", " ", "\tGLib.debug(\"highlight errors\");\t\t ", "", @@ -1634,46 +1637,48 @@ "\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);", + "\tvar ar = this.file.getErrors();", + "\tif (ar.size < 1) {", + "\t\tbuf.remove_source_marks (start, end, null);", + "\t\tthis.last_error_counter = file.error_counter ;", + "\t\tGLib.debug(\"higjlight has no errors\");", "\t\treturn;", "\t}", - " ", + " \tif (this.last_error_counter == file.error_counter) {", + "\t\treturn;", + "\t}", + "\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);", + "\tbuf.remove_source_marks (start, end, null);", + "\tforeach(var diag in ar) { ", + "\t", "\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 var eline = (int)diag.range.start.line + 1;", "\t ", "\t if (eline > tlines || eline < 0) {", "\t return;", "\t }", "\t ", "\t ", - "\t buf.get_iter_at_line( out iter, eline);", + "\t buf.get_iter_at_line_offset( out iter, eline, (int)diag.range.start.character);", + "\t ", "\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\tvar msg = \"Line: %d %s : %s\".printf(eline+1, diag.category, diag.message);", + "\t buf.create_source_mark( msg, diag.category, iter);", "\t GLib.debug(\"set line %d to %s\", eline, msg);", "\t //this.marks.set(eline, msg);", "\t}", - "\treturn ;", + "\tthis.last_error_counter = file.error_counter ;", "", "", "", diff --git a/src/Builder4/WindowRooView.vala b/src/Builder4/WindowRooView.vala index 1ea8faad9..bdb59cf26 100644 --- a/src/Builder4/WindowRooView.vala +++ b/src/Builder4/WindowRooView.vala @@ -35,6 +35,7 @@ public class Xcls_WindowRooView : Object // my vars (def) public Gtk.Widget lastObj; public Xcls_MainWindow main_window; + public int last_error_counter; public int last_search_end; public GtkSource.SearchContext searchcontext; public JsRender.JsRender file; @@ -47,6 +48,7 @@ public class Xcls_WindowRooView : Object // my vars (dec) this.lastObj = null; + this.last_error_counter = 0; this.last_search_end = 0; this.file = null; @@ -64,6 +66,8 @@ public class Xcls_WindowRooView : Object this.view.renderJS(true); this.notebook.el.page = 0;// gtk preview this.sourceview.loadFile(); + this.last_error_counter = -1; + this.updateErrorMarks(); } public void highlightNodeAtLine (int ln) { @@ -242,7 +246,7 @@ public class Xcls_WindowRooView : Object } - public void updateErrorMarks (string category) { + public void updateErrorMarks () { @@ -251,7 +255,7 @@ public class Xcls_WindowRooView : Object Gtk.TextIter end; buf.get_bounds (out start, out end); - buf.remove_source_marks (start, end, category); + GLib.debug("highlight errors"); @@ -265,46 +269,48 @@ public class Xcls_WindowRooView : Object return; } - var ar = this.file.getErrors(category); - if (ar == null || ar.get_n_items() < 1) { - GLib.debug("higjlight %s has no errors", category); + var ar = this.file.getErrors(); + if (ar.size < 1) { + buf.remove_source_marks (start, end, null); + this.last_error_counter = file.error_counter ; + GLib.debug("higjlight has no errors"); return; } - + if (this.last_error_counter == file.error_counter) { + 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); + buf.remove_source_marks (start, end, null); + foreach(var diag in ar) { + 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); - + var eline = (int)diag.range.start.line + 1; if (eline > tlines || eline < 0) { return; } - buf.get_iter_at_line( out iter, eline); + buf.get_iter_at_line_offset( out iter, eline, (int)diag.range.start.character); + - var msg = "Line: %d %s : %s".printf(eline+1, err.category, err.msg); - buf.create_source_mark( msg, err.category, iter); + var msg = "Line: %d %s : %s".printf(eline+1, diag.category, diag.message); + buf.create_source_mark( msg, diag.category, iter); GLib.debug("set line %d to %s", eline, msg); //this.marks.set(eline, msg); } - return ; + this.last_error_counter = file.error_counter ; diff --git a/src/Builder4/WindowState.vala b/src/Builder4/WindowState.vala index 31680356e..f3ea8c8ab 100644 --- a/src/Builder4/WindowState.vala +++ b/src/Builder4/WindowState.vala @@ -167,13 +167,13 @@ public class WindowState : Object } void updateErrorMarks(string cat) { - this.code_editor_tab.updateErrorMarks(cat); + this.code_editor_tab.updateErrorMarks(); switch(this.file.xtype) { case "Roo": - this.window_rooview.updateErrorMarks(cat);// foce scroll. + this.window_rooview.updateErrorMarks();// foce scroll. return; case "Gtk": - this.window_gladeview.updateErrorMarks(cat); + this.window_gladeview.updateErrorMarks(); return; default: return; diff --git a/src/JsRender/JsRender.vala b/src/JsRender/JsRender.vala index 29d8df1f5..ee229276e 100644 --- a/src/JsRender/JsRender.vala +++ b/src/JsRender/JsRender.vala @@ -116,9 +116,11 @@ namespace JsRender { public Gee.HashMap transStrings; // map of md5 -> string. public Gee.HashMap namedStrings; - public Gee.HashMap errorsByType; - - + //public Gee.HashMap errorsByType; + private Gee.ArrayList errors; + public int error_counter { + get; private set; default = 0; + } public signal void changed (Node? node, string source); @@ -191,8 +193,8 @@ namespace JsRender { this.doubleStringProps = new Gee.ArrayList(); this.childfiles = new GLib.ListStore(typeof(JsRender)); - this.errorsByType = new Gee.HashMap(); - + //this.errorsByType = new Gee.HashMap(); + this.errors = new Gee.ArrayList((a,b) => { return a.equals(b); }); @@ -745,14 +747,71 @@ namespace JsRender { return this.project.getLanguageServer(this.language_id()); } - public GLib.ListStore getErrors(string n) + + public void updateErrors(Gee.ArrayList new_errors) { - var ls = this.errorsByType.get(n); - if (ls == null) { - ls = new GLib.ListStore(typeof(Palete.CompileError)); - this.errorsByType.set(n, ls ); + var oc = this.error_counter; + var skip = new Gee.ArrayList((a,b) => { return a.equals(b); }); + var rem = new Gee.ArrayList((a,b) => { return a.equals(b); }); + foreach(var old in this.errors) { + if (new_errors.contains(old)) { + skip.add(old); + continue; + } + rem.add(old); + } - return ls; + foreach(var old in rem) { + this.removeError(old); + } + foreach(var err in new_errors) { + if (skip.contains(err)) { + continue; + } + this.addError(err); + } + if (oc != this.error_counter) { + BuilderApplication.updateCompileResults(); + } + + } + + + + public Gee.ArrayList getErrors() + { + return this.errors; + } + + private void addError(Lsp.Diagnostic diag) + { + + GLib.debug("ADD Error %s", diag.to_string()); + this.errors.add(diag); + this.project.addError(this, diag); + + this.error_counter++; + + } + + public void removeError(Lsp.Diagnostic diag) + { + GLib.debug("REMOVE Error %s", diag.to_string()); + this.errors.remove(diag); + this.project.removeError(this, diag); + this.error_counter++; + } + public int getErrorsTotal(string category) + { + var ret = 0; + foreach(var diag in this.errors) { + if (diag.category == category) { + ret++; + } + } + return ret; + + } diff --git a/src/Lsp.vala b/src/Lsp.vala index 7288f72a2..d13b91634 100644 --- a/src/Lsp.vala +++ b/src/Lsp.vala @@ -106,6 +106,16 @@ namespace Lsp { } public class Range : Object, Gee.Hashable, Gee.Comparable { + + public Range.simple(uint line, uint pos) { + var p = new Position () { + line = line, + character = pos + }; + this.start = p; + this.end = p; + + } /** * The range's start position. */ @@ -165,6 +175,16 @@ namespace Lsp { } public class Diagnostic : Object { + + public Diagnostic.simple ( int line, int character, string message) + { + this.message = message; + this.severity = DiagnosticSeverity.Error; + this.range = new Range.simple(line, character ); + + + + } /** * The range at which the message applies. */ @@ -210,8 +230,12 @@ namespace Lsp { } public bool equals(Lsp.Diagnostic o) { return this.range.equals(o.range) && this.severity == o.severity && this.message == o.message; - } + public string to_string() + { + return "%s : %d - %s".printf(this.category, (int) this.range.start.line , this.message); + } + } /** @@ -338,7 +362,7 @@ namespace Lsp { // 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)) { + val = GLib.Value (typeof(Gee.ArrayList)); 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)); } } @@ -380,7 +404,7 @@ namespace Lsp { if (property_name != "children") { return default_deserialize_property (property_name, out value, pspec, property_node); } - value = GLib.Value (GLib.Type.BOXED); + value = GLib.Value (typeof(Gee.ArrayList)); 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; @@ -396,7 +420,7 @@ namespace Lsp { }); - value.set_boxed (arguments); + value.set_object (arguments); return true; } } @@ -665,7 +689,7 @@ namespace Lsp { if (property_name != "tags") { return default_deserialize_property (property_name, out value, pspec, property_node); } - value = GLib.Value (GLib.Type.BOXED); + value = GLib.Value (typeof(Gee.ArrayList)); 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; @@ -681,7 +705,7 @@ namespace Lsp { } }); - value.set_boxed (arguments); + value.set_object (arguments); return true; } } @@ -971,7 +995,7 @@ namespace Lsp { public bool deserialize_property (string property_name, out GLib.Value value, GLib.ParamSpec pspec, Json.Node property_node) { if (property_name == "arguments") { - value = GLib.Value (GLib.Type.BOXED); + value = GLib.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; @@ -1090,6 +1114,13 @@ namespace Lsp { public class Diagnostics : Object, Json.Serializable { + public Diagnostics() + { + this.diagnostics = new Gee.ArrayList((a,b) => { + return a.equals(b); + }); + } + public string uri { get; set; } public int version { get; set; default = 0; } @@ -1104,9 +1135,12 @@ namespace Lsp { 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 (); + val = GLib.Value (typeof(Gee.ArrayList)); + var diags = new Gee.ArrayList ((a,b) => { + return a.equals(b); + }); if (property_node.get_node_type () != Json.NodeType.ARRAY) { - val = diags; + val.set_object(diags); warning ("unexpected property node type for 'arguments' %s", property_node.get_node_type ().to_string ()); return false; } @@ -1120,7 +1154,7 @@ namespace Lsp { //warning ("argument %u to command could not be deserialized: %s", index, e.message); }); - val = diags; + val.set_object(diags); return true; } diff --git a/src/Palete/CompileError.vala b/src/Palete/CompileError.vala index e33935d39..954ff0a78 100644 --- a/src/Palete/CompileError.vala +++ b/src/Palete/CompileError.vala @@ -3,6 +3,13 @@ Object to handle compiler errors so they can be passed off to trees. +There are a few things we do with diagnostics +a) the popup list with a tree of file => { errors} for each type +b) the syntax highlighting. + + + + */ namespace Palete { @@ -19,7 +26,7 @@ namespace Palete { public string category = ""; public string msg = ""; public int line { get; set; default = -1; } - + public Lsp.Diagnostic? diag = null; public CompileError.new_jserror(JsRender.JsRender file, string category, int line, string msg) { @@ -39,6 +46,7 @@ namespace Palete { this.line = (int) diag.range.start.line; this.msg = diag.message; this.lines = new GLib.ListStore(typeof(CompileError)); + this.diag = diag; //GLib.debug("new error %s : %d %s %s", file.path, this.line, this.category, this.msg); @@ -49,47 +57,10 @@ namespace Palete { { 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; - this.line = line; - this.msg = msg; - this.file = parent.file; - this.category = parent.category; - - - } - public CompileError.new_file(JsRender.JsRender file, Json.Object jlines, string category) - { - this.file = file; - this.category = category; - this.title = file.relpath + " (" + jlines.get_size().to_string() + ")"; - - this.lines = new GLib.ListStore(typeof(CompileError)); - - jlines.foreach_member((obja, line, nodea) => { - var msg = ""; - var ar = jlines.get_array_member(line); - - - - for (var i = 0 ; i < ar.get_length(); i++) { - msg += (msg.length > 0) ? "\n" : ""; - msg += ar.get_string_element(i); - } - this.lines.append(new CompileError.new_line(this, int.parse(line) ,msg)); - - - }); - + this.title = file.relpath + " (" + lines.get_n_items().to_string() + ")"; } - */ + public string file_line { // sorting? set {} owned get { @@ -109,94 +80,8 @@ namespace Palete { public bool hasErrors() { return this.lines.get_n_items() > 0; } - - /* - - public static void parseCompileResults (ValaCompileRequest req, Json.Object tree) - { - //req.errorByFile = new Gee.HashMap(); - //req.errorByType = new Gee.HashMap(); - - - - req.errorByType.set("ERR", new GLib.ListStore(typeof(CompileError))); - req.errorByType.set("WARN", new GLib.ListStore(typeof(CompileError))); - req.errorByType.set("DEPR", new GLib.ListStore(typeof(CompileError))); - - jsonToListStoreProp(req, "WARN", tree); - jsonToListStoreProp(req, "ERR", tree); - jsonToListStoreProp(req, "DEPR", tree); - - - } - - - public static void jsonToListStoreProp(ValaCompileRequest req, string prop, Json.Object tree) - { - var project = req.file.project; - var ls = new GLib.ListStore(typeof(CompileError)); - if (!tree.has_member(prop)) { - GLib.debug("Files with %s : 0", prop); - req.errorByType.set(prop,ls); - return; - } - var res = tree.get_object_member(prop); - res.foreach_member((obj, file, node) => { - - var fe = project.getByPath(file); - - if (fe == null) { - GLib.debug("Warning Can not find file %s", file); - return; - } - - - - - var ce = new CompileError.new_file(fe, res.get_object_member(file), prop); - ls.append(ce); - - if (!req.errorByFile.has_key(fe.targetName())) { - GLib.debug("add file %s to req.errorByFile", fe.targetName()); - req.errorByFile.set(fe.targetName(), new GLib.ListStore(typeof(CompileError))); - } - for(var i = 0; i < ce.lines.get_n_items(); i++) { - var lce = (CompileError) ce.lines.get_item(i); - GLib.debug("add error %s to %s", lce.msg, fe.targetName()); - req.errorByFile.get(fe.targetName()).append(lce); - } - - - - }); - GLib.debug("Files with %s : %d", prop, (int) ls.get_n_items()); - req.errorByType.set(prop,ls); - - } - - // only used by javascript /roo errors.. - public static GLib.ListStore jsonToListStore(Project.Project project, Json.Object tree) - { - var ls = new GLib.ListStore(typeof(CompileError)); - tree.foreach_member((obj, file, node) => { - - var fe = project.getByPath(file); - - if (fe == null) { - GLib.debug("Warning Can not find file %s", file); - return; - } - var ce = new CompileError.new_file(fe, tree.get_object_member(file), "ERR"); - ls.append(ce); - - - - }); - return ls; - - - } - */ + + } diff --git a/src/Palete/Javascript.vala b/src/Palete/Javascript.vala index c70eed98f..bb8390f28 100644 --- a/src/Palete/Javascript.vala +++ b/src/Palete/Javascript.vala @@ -87,20 +87,19 @@ 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(); + var ar = new Gee.ArrayList((a,b) => { return a.equals(b); }); + if (ex == null) { + file.updateErrors( ar ); return ; // this.compressionErrors(code, fn); << to slow on large files? } - + //GLib.debug("go t error %d %s", (int)ex.get_line_number() , ex.get_message() ); - + var diag = new Lsp.Diagnostic.simple((int) ex.get_line_number() -1 , 1, ex.get_message()); - var ret = new CompileError.new_jserror(file, "ERR", (int) ex.get_line_number() -1 , ex.get_message()); - - ar.append(ret); - + ar.add(diag); + file.updateErrors( ar ); } diff --git a/src/Palete/LanguageClientVala.vala b/src/Palete/LanguageClientVala.vala index fe374453a..d535822b4 100644 --- a/src/Palete/LanguageClientVala.vala +++ b/src/Palete/LanguageClientVala.vala @@ -241,6 +241,7 @@ namespace Palete { { switch (method) { case "textDocument/publishDiagnostics": + GLib.debug("got notification %s : %s", method , Json.to_string (Json.gvariant_serialize (return_value), true)); this.onDiagnostic(return_value); return; default: @@ -256,26 +257,17 @@ namespace Palete { */ public void onDiagnostic(Variant? return_value) { - + GLib.debug ("LS replied with %s", Json.to_string (Json.gvariant_serialize (return_value), true)); var dg = Json.gobject_deserialize (typeof (Lsp.Diagnostics), Json.gvariant_serialize (return_value)) as Lsp.Diagnostics; this.log(LanguageClientAction.DIAG, dg.filename); var f = this.project.getByPath(dg.filename); if (f == null) { //GLib.debug("no file %s", dg.uri); - this.project.updateErrorsforFile(null); + //this.project.updateErrorsforFile(null); 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); + f.updateErrors( dg.diagnostics ); + } diff --git a/src/Project/Project.vala b/src/Project/Project.vala index 42aaaf8b2..8ffeef840 100644 --- a/src/Project/Project.vala +++ b/src/Project/Project.vala @@ -998,36 +998,48 @@ namespace Project { return ret; } - public void updateErrorsforFile(JsRender.JsRender? f) + // called from file.. + public void addError(JsRender.JsRender f, Lsp.Diagnostic diag) { - if (f != null) { - var n = this.updateErrorsByType(f, "WARN"); - n += this.updateErrorsByType(f, "ERR"); - n += this.updateErrorsByType(f, "DEPR"); - } + var new_ce = new Palete.CompileError.new_from_diagnostic(f, diag); + var ls = this.getErrors(new_ce.category); // will create if necessary.. + // find the file in the list store. - BuilderApplication.updateCompileResults(); - - + 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) { + ce.lines.append(new_ce); + return; + } + } + // we did not have the file.. + var add = new Palete.CompileError.new_from_file(f, diag.category); + ls.append(add); + add.lines.append(new_ce); + } - public int updateErrorsByType(JsRender.JsRender f, string n) + public void removeError(JsRender.JsRender f, Lsp.Diagnostic diag) { - var ls = this.getErrors(n); - - // remove thie file from the list. + var ls = this.getErrors(diag.category); 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; + if (ce.file.path != f.path) { + continue; + } + for(var j =0; j < ce.lines.get_n_items(); j++) { + var lce = ce.lines.get_item(j) as Palete.CompileError; + + if (!diag.equals( lce.diag)) { + continue; + } + ce.lines.remove(j); + if (ce.lines.get_n_items() < 1) { + ls.remove(i); + return; + } } } - 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) {