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;
+ global::Gtk.StringFilter? filter = null;
public CompletionProvider(Editor editor)
{
return 200;
}
+
+ public bool is_trigger(global::Gtk.TextIter iter, unichar ch)
+ {
+ if (this.in_populate || ch == 32) {
+ return false;
+ }
+ if (this.editor.buffer.el.iter_has_context_class(iter, "comment") ||
+ this.editor.buffer.el.iter_has_context_class(iter, "string")
+ ) {
+ return false;
+ }
+
+
+ //GLib.debug("should trigger? %c", (int) ch);
+
+
+ return true;
+ }
+
public void activate (GtkSource.CompletionContext context, GtkSource.CompletionProposal proposal)
{
GLib.debug("compelte activate");
for(var i = 0 ; i < args.length; i++) {
word += i > 0 ? ", " : " ";
var wbit = args[i].strip().split(" ");
+ if (wbit.length < 2) {
+ word += wbit[0];
+ continue;
+ }
var ty = wbit[wbit.length - 2];
ty = ty.has_suffix("?") ? "?" : "";
word += ty + wbit[wbit.length-1]; // property type..?
internal async GLib.ListModel populate_async (GtkSource.CompletionContext context, GLib.Cancellable? cancellable)
{
GLib.debug("pupoulate async");
- /*if (!this.in_populate) {
+ var ret = new GLib.ListStore(typeof(CompletionProposal));
+
+ if (this.in_populate) {
GLib.debug("pupoulate async - skipped waiting for reply");
- return null;
+ return ret;
}
this.in_populate = true;
-*/
+
global::Gtk.TextIter begin, end;
Lsp.CompletionList res;
if (context.get_bounds (out begin, out end)) {
var offset = end.get_line_offset();
if (this.editor.prop != null) {
// tried line -1 (does not work)
-
+ GLib.debug("node pad = '%s' %d", this.editor.node.node_pad, this.editor.node.node_pad.length);
+
line += this.editor.prop.start_line ;
// this is based on Gtk using tabs (hence 1/2 chars);
- offset += this.editor.file.file_namespace == "" ? 1 : 2;
+ offset += this.editor.node.node_pad.length;
+ // javascript listeners are indented 2 more spaces.
+ if (this.editor.prop.ptype == JsRender.NodePropType.LISTENER) {
+ offset += 2;
+ }
}
-
- this.file.getLanguageServer().document_change_real(this.file, this.editor.tempFileContents());
+ // this should not really be slow, as it's a quick repsonse
+ yield this.file.getLanguageServer().document_change_force(this.file, this.editor.tempFileContents());
try {
+ GLib.debug("sending request to language server %s", this.file.getLanguageServer().get_type().name());
+
res = yield this.file.getLanguageServer().completion(this.file, line, offset, 1);
} catch (GLib.Error e) {
GLib.debug("got error %s", e.message);
- res = null;
+ this.in_populate = false;
+ return ret;
}
} else {
- res = null;
+ this.in_populate = false;
+ return ret;
}
GLib.debug("pupoulate async - got reply");
this.model = new CompletionModel(this, context, res, cancellable);
var word = context.get_word();
+ GLib.debug("Context word is %s, %d", word, (int)word.length);
var expression = new global::Gtk.PropertyExpression(typeof(CompletionProposal), null, "label");
{
//GLib.debug("pupoulate refilter");
-
+ if (this.filter == null) {
+ return;
+ }
var word = context.get_word();
this.filter.set_search(word);
this.search = word;
if (res != null) {
foreach(var comp in res.items) {
-
+ if (comp.label == "_") { // skip '_'
+ continue;
+ }
this.items.add(new CompletionProposal(comp));
}