[gnome-calculator/wip/cdavis/gtk4: 16/16] Rework completion code to use proper SourceView API
- From: Robert Roth <robertroth src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-calculator/wip/cdavis/gtk4: 16/16] Rework completion code to use proper SourceView API
- Date: Thu, 11 Nov 2021 06:04:16 +0000 (UTC)
commit a00c1f543864b3dfdd38bda14e2783b0fdc1c88c
Author: Christian Hergert <chergert redhat com>
Date: Tue Oct 26 13:47:31 2021 -0700
Rework completion code to use proper SourceView API
Calculator using sourceview's completion APIs correctly
prior to this commit. This commit fixes how we get matches,
how we filter items, and our populate vfunc.
lib/function-manager.vala | 2 -
src/gnome-calculator.vala | 1 +
src/math-display.vala | 109 ++++++++++++++++++++++++++++------------------
3 files changed, 68 insertions(+), 44 deletions(-)
---
diff --git a/lib/function-manager.vala b/lib/function-manager.vala
index 61dd4ea4..26cbc30a 100644
--- a/lib/function-manager.vala
+++ b/lib/function-manager.vala
@@ -365,8 +365,6 @@ public class FunctionManager : Object
public MathFunction[] functions_eligible_for_autocompletion_for_text (string display_text)
{
MathFunction[] eligible_functions = {};
- if (display_text.length <= 1)
- return eligible_functions;
string display_text_case_insensitive = display_text.down ();
var iter = HashTableIter<string, MathFunction> (functions);
diff --git a/src/gnome-calculator.vala b/src/gnome-calculator.vala
index 3fcf0c20..e808f30c 100644
--- a/src/gnome-calculator.vala
+++ b/src/gnome-calculator.vala
@@ -107,6 +107,7 @@ public class Calculator : Gtk.Application
base.startup ();
Adw.init ();
+ Gtk.Sourceinit ();
settings = new Settings ("org.gnome.calculator");
settings.delay ();
diff --git a/src/math-display.vala b/src/math-display.vala
index 5dde0c62..69a1a1ac 100644
--- a/src/math-display.vala
+++ b/src/math-display.vala
@@ -131,6 +131,7 @@ public class MathDisplay : Gtk.Box
private void create_autocompletion ()
{
Gtk.SourceCompletion completion = source_view.get_completion ();
+ completion.select_on_show = true;
completion.show.connect ((completion) => { this.completion_visible = true; this.completion_selected
= false;} );
completion.hide.connect ((completion) => { this.completion_visible = false; this.completion_selected
= false; } );
// completion.move_cursor.connect ((completion) => {this.completion_selected = true;});
@@ -551,60 +552,86 @@ public class CompletionProvider : GLib.Object, Gtk.SourceCompletionProvider
return false;
}
+ public static Gtk.StringFilter create_filter (string word)
+ {
+ Gtk.Expression expr = new Gtk.PropertyExpression (typeof (CompletionProposal), null, "text");
+ Gtk.StringFilter filter = new Gtk.StringFilter (expr);
+ filter.set_match_mode (Gtk.StringFilterMatchMode.PREFIX);
+ filter.set_ignore_case (true);
+ filter.set_search (word);
+
+ return filter;
+ }
+
+ public override void refilter (Gtk.SourceCompletionContext context, ListModel model)
+ {
+ if (!model.get_type ().is_a (typeof (Gtk.FilterListModel)))
+ return;
- public virtual bool activate_proposal (Gtk.SourceCompletionContext context, Gtk.SourceCompletionProposal
proposal)
+ ((Gtk.FilterListModel)model).set_filter (create_filter (context.get_word ()));
+ }
+
+ public override void activate (Gtk.SourceCompletionContext context, Gtk.SourceCompletionProposal
proposal)
{
string proposed_string = ((CompletionProposal) proposal).text;
- Gtk.TextBuffer buffer = context.get_buffer ();
+ string word;
+ Gtk.TextIter start_iter, end_iter;
- Gtk.TextIter start_iter, end;
- context.get_bounds(out start_iter, out end);
- move_iter_to_name_start (ref start_iter);
+ context.get_bounds (out start_iter, out end_iter);
+ word = start_iter.get_slice (end_iter);
+
+ Gtk.TextBuffer buffer = start_iter.get_buffer ();
+
+ buffer.begin_user_action ();
+#if 0
+ /* Honestly, you'd want to do this like the following so you can
+ * handle situations where there is not a perfect prefix match (such
+ * as fuzzy completion. but since that is broken due to incorrect
+ * handling of delete-range in math-equation.vala, you can't now.
+ */
+ buffer.@delete (ref start_iter, ref end_iter);
+ buffer.insert (ref end_iter, proposed_string, -1);
+#endif
+ if (proposed_string.has_prefix (word))
+ {
+ buffer.insert (ref end_iter, proposed_string.substring(word.length, -1), -1);
+ }
+ buffer.end_user_action ();
- buffer.place_cursor (start_iter);
- buffer.delete_range (start_iter, end);
- buffer.insert_at_cursor (proposed_string, proposed_string.length);
- if (proposed_string.contains ("()"))
+ if (proposed_string.has_suffix ("()"))
{
- end.backward_char ();
- buffer.place_cursor (end);
+ end_iter.backward_char ();
+ buffer.select_range (end_iter, end_iter);
}
- return true;
}
-
- public virtual void populate (Gtk.SourceCompletionContext context) {}
}
-public class FunctionCompletionProvider : CompletionProvider
+public class FunctionCompletionProvider : CompletionProvider, Gtk.SourceCompletionProvider
{
public override string? get_title ()
{
return _("Defined Functions");
}
- public static MathFunction[] get_matches_for_completion_at_cursor (Gtk.TextBuffer text_buffer)
+ public static MathFunction[] get_matches_for_completion_at_cursor (Gtk.SourceCompletionContext context)
{
Gtk.TextIter start_iter, end_iter;
- text_buffer.get_iter_at_mark (out end_iter, text_buffer.get_insert ());
- text_buffer.get_iter_at_mark (out start_iter, text_buffer.get_insert ());
- CompletionProvider.move_iter_to_name_start (ref start_iter);
- string search_pattern = text_buffer.get_slice (start_iter, end_iter, false);
+ context.get_bounds (out start_iter, out end_iter);
+ string search_pattern = start_iter.get_slice (end_iter);
FunctionManager function_manager = FunctionManager.get_default_function_manager ();
MathFunction[] functions = function_manager.functions_eligible_for_autocompletion_for_text
(search_pattern);
return functions;
}
- public override void populate (Gtk.SourceCompletionContext context)
+ public override async ListModel populate_async (Gtk.SourceCompletionContext context, GLib.Cancellable?
cancellable)
+ throws GLib.Error
{
- Gtk.TextBuffer? text_buffer = context.get_buffer ();
- if (text_buffer == null)
- return;
-
- MathFunction[] functions = get_matches_for_completion_at_cursor (text_buffer);
-
ListStore proposals = new ListStore (typeof (CompletionProposal));
+ MathFunction[] functions = get_matches_for_completion_at_cursor (context);
+ string word = context.get_word ();
+
if (functions.length > 0)
{
foreach (var function in functions)
@@ -619,11 +646,12 @@ public class FunctionCompletionProvider : CompletionProvider
proposals.append (new CompletionProposal (display_text, label_text, details_text));
}
}
- context.set_proposals_for_provider (this, proposals);
+
+ return new Gtk.FilterListModel (proposals, create_filter (word));
}
}
-public class VariableCompletionProvider : CompletionProvider
+public class VariableCompletionProvider : CompletionProvider, Gtk.SourceCompletionProvider
{
private MathEquation _equation;
@@ -637,27 +665,23 @@ public class VariableCompletionProvider : CompletionProvider
return _("Defined Variables");
}
- public static string[] get_matches_for_completion_at_cursor (Gtk.TextBuffer text_buffer, MathVariables
variables )
+ public static string[] get_matches_for_completion_at_cursor (Gtk.SourceCompletionContext context,
MathVariables variables)
{
Gtk.TextIter start_iter, end_iter;
- text_buffer.get_iter_at_mark (out end_iter, text_buffer.get_insert ());
- text_buffer.get_iter_at_mark (out start_iter, text_buffer.get_insert ());
- CompletionProvider.move_iter_to_name_start (ref start_iter);
- string search_pattern = text_buffer.get_slice (start_iter, end_iter, false);
+ context.get_bounds (out start_iter, out end_iter);
+
+ string search_pattern = start_iter.get_slice (end_iter);
string[] math_variables = variables.variables_eligible_for_autocompletion (search_pattern);
return math_variables;
}
- public override void populate (Gtk.SourceCompletionContext context)
+ public override async ListModel populate_async (Gtk.SourceCompletionContext context, GLib.Cancellable?
cancellable)
+ throws GLib.Error
{
- Gtk.TextBuffer? text_buffer = context.get_buffer ();
- if (text_buffer == null)
- return;
-
- string[] variables = get_matches_for_completion_at_cursor (text_buffer, _equation.variables);
-
ListStore proposals = new ListStore (typeof (CompletionProposal));
+ string[] variables = get_matches_for_completion_at_cursor (context, _equation.variables);
+
if (variables.length > 0)
{
foreach (var variable in variables)
@@ -669,6 +693,7 @@ public class VariableCompletionProvider : CompletionProvider
proposals.append (new CompletionProposal (display_text, label_text, details_text));
}
}
- context.set_proposals_for_provider (this, proposals);
+
+ return proposals;
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]