[latexila] Completion: more code clean-up
- From: SÃbastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [latexila] Completion: more code clean-up
- Date: Fri, 30 Dec 2011 08:10:17 +0000 (UTC)
commit d736ec823ad3e648a6e1a8d77e9921d0c1873b13
Author: SÃbastien Wilmet <swilmet src gnome org>
Date: Fri Dec 30 09:08:53 2011 +0100
Completion: more code clean-up
Mainly in match() and populate(). The clean-up is not finished, but it's
a good time to do a commit :)
src/completion.vala | 270 ++++++++++++++++++++++++++-------------------------
1 files changed, 137 insertions(+), 133 deletions(-)
---
diff --git a/src/completion.vala b/src/completion.vala
index 6d7cdf0..4e988b3 100644
--- a/src/completion.vala
+++ b/src/completion.vala
@@ -15,6 +15,9 @@
*
* You should have received a copy of the GNU General Public License
* along with LaTeXila. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: SÃbastien Wilmet
+ * Pieter Pareit
*/
using Gtk;
@@ -57,28 +60,21 @@ public class CompletionProvider : GLib.Object, SourceCompletionProvider
private CompletionArgument _current_arg;
private CompletionChoice _current_choice;
- private bool _show_all_proposals = false;
-
- private Gdk.Pixbuf _icon_normal_cmd;
- private Gdk.Pixbuf _icon_normal_choice;
+ private Gdk.Pixbuf _icon_cmd;
+ private Gdk.Pixbuf _icon_choice;
private Gdk.Pixbuf _icon_package_required;
private SourceCompletionInfo _calltip_window = null;
private Label _calltip_window_label = null;
- // HACK: match () is called one time and then populate () is called each time a new
- // character is typed (and also just after match () was called).
- private bool _first_populate = true;
-
/* CompletionProvider is a singleton */
private CompletionProvider ()
{
_settings = new GLib.Settings ("org.gnome.latexila.preferences.latex");
// icons
- _icon_normal_cmd = Utils.get_pixbuf_from_stock ("completion_cmd", IconSize.MENU);
- _icon_normal_choice = Utils.get_pixbuf_from_stock ("completion_choice",
- IconSize.MENU);
+ _icon_cmd = Utils.get_pixbuf_from_stock ("completion_cmd", IconSize.MENU);
+ _icon_choice = Utils.get_pixbuf_from_stock ("completion_choice", IconSize.MENU);
_icon_package_required = Utils.get_pixbuf_from_stock (Stock.DIALOG_WARNING,
IconSize.MENU);
@@ -89,6 +85,7 @@ public class CompletionProvider : GLib.Object, SourceCompletionProvider
{
if (_instance == null)
_instance = new CompletionProvider ();
+
return _instance;
}
@@ -99,22 +96,15 @@ public class CompletionProvider : GLib.Object, SourceCompletionProvider
public SourceCompletionActivation get_activation ()
{
- SourceCompletionActivation ret = SourceCompletionActivation.USER_REQUESTED;
-
- if (_settings.get_boolean ("interactive-completion"))
- ret |= SourceCompletionActivation.INTERACTIVE;
-
- return ret;
+ // This function is called only once, so if we disable interactive
+ // completion here, there would be a problem because in this case,
+ // if the user enables the option, it will take effect only on restart.
+ return SourceCompletionActivation.USER_REQUESTED
+ | SourceCompletionActivation.INTERACTIVE;
}
public bool match (SourceCompletionContext context)
{
- _first_populate = true;
-
- bool in_argument = false;
- bool valid_arg_contents = false;
- _show_all_proposals = false;
-
TextIter iter = context.get_iter ();
// if text selected, NO completion
@@ -122,22 +112,23 @@ public class CompletionProvider : GLib.Object, SourceCompletionProvider
if (buf.has_selection)
return false;
- string? cmd = get_latex_command_at_iter (iter);
-
- if (cmd == null)
- in_argument = in_latex_command_argument (iter, null, null, null,
- out valid_arg_contents);
-
+ /* Activation: user request */
if (context.activation == SourceCompletionActivation.USER_REQUESTED)
- {
- _show_all_proposals = cmd == null && ! in_argument;
return true;
- }
+ /* Activation: interactive */
if (! _settings.get_boolean ("interactive-completion"))
return false;
- if (in_argument)
+ string? cmd = get_latex_command_at_iter (iter);
+ bool in_arg = false;
+ bool valid_arg_contents = false;
+
+ if (cmd == null)
+ in_arg = in_latex_command_argument (iter, null, null, null,
+ out valid_arg_contents);
+
+ if (in_arg)
return valid_arg_contents;
uint min_nb_chars;
@@ -149,81 +140,100 @@ public class CompletionProvider : GLib.Object, SourceCompletionProvider
public void populate (SourceCompletionContext context)
{
TextIter iter = context.get_iter ();
+
+ /* The cursor is in a command name */
string? cmd = get_latex_command_at_iter (iter);
+ if (cmd != null)
+ {
+ populate_command (context, cmd);
+ return;
+ }
- bool in_argument = false;
- string cmd_name = null;
+ /* The cursor is probably in a command's argument */
+
+ string arg_cmd = null;
Gee.ArrayList<bool> arguments = new Gee.ArrayList<bool> ();
- string argument_contents = null;
+ string arg_contents = null;
bool valid_arg_contents = false;
- if (cmd == null)
- in_argument = in_latex_command_argument (iter, out cmd_name, out arguments,
- out argument_contents, out valid_arg_contents);
+ bool in_arg = in_latex_command_argument (iter, out arg_cmd, out arguments,
+ out arg_contents, out valid_arg_contents);
- // clear
- if ((! _show_all_proposals && cmd == null && ! in_argument)
- || (context.activation == SourceCompletionActivation.INTERACTIVE
- && ! _settings.get_boolean ("interactive-completion"))
- || (in_argument && ! _commands.has_key (cmd_name)))
+ bool user_request =
+ context.activation == SourceCompletionActivation.USER_REQUESTED;
+ if (! in_arg)
{
- clear_context (context);
- _first_populate = false;
+ if (user_request)
+ show_all_proposals (context);
+ else
+ show_no_proposals (context);
return;
}
- // show all proposals
- if (_show_all_proposals || cmd == "\\")
+ /* OK, we are in an argument */
+
+ // invalid argument's command
+ if (! _commands.has_key (arg_cmd))
{
- _show_all_proposals = false;
- context.add_proposals ((SourceCompletionProvider) this, _proposals, true);
- _first_populate = false;
+ show_no_proposals (context);
return;
}
- // filter proposals
unowned List<SourceCompletionItem> proposals_to_filter = null;
- string prefix = null;
- // try to complete a command
- if (! in_argument)
+
+ if (valid_arg_contents)
+ proposals_to_filter = get_argument_proposals (_commands[arg_cmd], arguments);
+
+ if (proposals_to_filter == null)
{
- proposals_to_filter = _proposals;
- prefix = cmd;
+ if (user_request)
+ show_calltip (arg_cmd, arguments);
+ else
+ show_no_proposals (context);
+ return;
}
- // try to complete a command argument choice
- else if (valid_arg_contents && _commands.has_key (cmd_name))
+
+ show_filtered_proposals (context, proposals_to_filter, arg_contents);
+ }
+
+ private void populate_command (SourceCompletionContext context, string cmd)
+ {
+ if (cmd == "\\")
{
- proposals_to_filter = get_argument_proposals (_commands[cmd_name], arguments);
- prefix = argument_contents ?? "";
+ show_all_proposals (context);
+ return;
}
- // show calltip?
- if (in_argument && proposals_to_filter == null)
- {
- // show calltip only on user request
- // Attention, clear the context before comparing the activation is not a
- // really good idea... ;)
- if (context.activation == SourceCompletionActivation.INTERACTIVE)
- {
- clear_context (context);
- hide_calltip_window ();
- return;
- }
+ show_filtered_proposals (context, _proposals, cmd);
+ }
- if (_first_populate)
- {
- CompletionCommand command = _commands[cmd_name];
- int num = get_argument_num (command.args, arguments);
- if (num != -1)
- {
- string info = get_command_info (command, num);
- show_calltip_info (info);
- }
- return;
- }
- }
+ private void show_no_proposals (SourceCompletionContext context)
+ {
+ // FIXME: maybe this method is not sure, because sometimes segfault occur,
+ // but it's really difficult to diagnose...
+ // see bug #618004
- hide_calltip_window ();
+ // The second argument can not be null so we use a variable...
+ // The vapi should be fixed.
+ List<SourceCompletionItem> empty_proposals = null;
+ context.add_proposals ((SourceCompletionProvider) this, empty_proposals, true);
+ }
+
+ private void show_all_proposals (SourceCompletionContext context)
+ {
+ context.add_proposals ((SourceCompletionProvider) this, _proposals, true);
+ }
+
+ private void show_filtered_proposals (SourceCompletionContext context,
+ List<SourceCompletionItem> proposals_to_filter, string? prefix)
+ {
+ // No filtering needed.
+ if (prefix == null || prefix == "")
+ {
+ context.add_proposals ((SourceCompletionProvider) this,
+ proposals_to_filter, true);
+ return;
+ }
List<SourceCompletionItem> filtered_proposals = null;
foreach (SourceCompletionItem item in proposals_to_filter)
@@ -232,28 +242,33 @@ public class CompletionProvider : GLib.Object, SourceCompletionProvider
filtered_proposals.prepend (item);
}
- // no match, show a message so the completion widget doesn't disappear
- if (filtered_proposals == null)
+ // Since we have prepend items we must reverse the list to keep the proposals
+ // in ascending order.
+ if (filtered_proposals != null)
+ filtered_proposals.reverse ();
+
+ // No match, show a message so the completion widget doesn't disappear.
+ else
{
var dummy_proposal = new SourceCompletionItem (_("No matching proposal"),
"", null, null);
filtered_proposals.prepend (dummy_proposal);
}
- // Since we have prepend items we must reverse the list to keep the proposals
- // in ascending order.
- // FIXME maybe it's better to sort the proposals in descending order so when
- // we prepend items it's in ascending order and we avoid reversing the list each
- // time. But when we have to display all proposals (see above) it takes more time,
- // but generally that occurs less often unless the minimum number of chars for
- // interactive completion is 0.
- else
- filtered_proposals.reverse ();
+ context.add_proposals ((SourceCompletionProvider) this, filtered_proposals, true);
+ }
- context.add_proposals ((SourceCompletionProvider) this, filtered_proposals,
- true);
+ private void show_calltip (string arg_cmd, Gee.ArrayList<bool> arguments)
+ {
+ return_if_fail (_commands.has_key (arg_cmd));
- _first_populate = false;
+ CompletionCommand command = _commands[arg_cmd];
+ int num = get_argument_num (command.args, arguments);
+ if (num != -1)
+ {
+ string info = get_command_info (command, num);
+ show_calltip_info (info);
+ }
}
public bool activate_proposal (SourceCompletionProposal proposal, TextIter iter)
@@ -267,16 +282,16 @@ public class CompletionProvider : GLib.Object, SourceCompletionProvider
// if it's an argument choice
if (cmd == null && text[0] != '\\')
{
- string cmd_name = null;
- string argument_contents = null;
+ string arg_cmd = null;
+ string arg_contents = null;
- bool in_argument = in_latex_command_argument (iter, out cmd_name, null,
- out argument_contents);
+ bool in_arg = in_latex_command_argument (iter, out arg_cmd, null,
+ out arg_contents);
- if (in_argument)
+ if (in_arg)
{
- activate_proposal_argument_choice (proposal, iter, cmd_name,
- argument_contents);
+ activate_proposal_argument_choice (proposal, iter, arg_cmd,
+ arg_contents);
return true;
}
}
@@ -314,11 +329,11 @@ public class CompletionProvider : GLib.Object, SourceCompletionProvider
}
private void activate_proposal_argument_choice (SourceCompletionProposal proposal,
- TextIter iter, string cmd_name, string? argument_contents)
+ TextIter iter, string arg_cmd, string? arg_contents)
{
string text = proposal.get_text ();
- long index_start = argument_contents != null ? argument_contents.length : 0;
+ long index_start = arg_contents != null ? arg_contents.length : 0;
string text_to_insert = text[index_start : text.length];
TextBuffer doc = iter.get_buffer ();
@@ -326,7 +341,7 @@ public class CompletionProvider : GLib.Object, SourceCompletionProvider
doc.insert (ref iter, text_to_insert, -1);
// close environment: \begin{env} => \end{env}
- if (cmd_name == "\\begin")
+ if (arg_cmd == "\\begin")
close_environment (text, iter);
// TODO place cursor, go to next argument, if any
@@ -476,7 +491,7 @@ public class CompletionProvider : GLib.Object, SourceCompletionProvider
pixbuf = _icon_package_required;
}
else
- pixbuf = _icon_normal_choice;
+ pixbuf = _icon_choice;
SourceCompletionItem item = new SourceCompletionItem (
choice.name, choice.name, pixbuf, info2 ?? info);
@@ -607,14 +622,14 @@ public class CompletionProvider : GLib.Object, SourceCompletionProvider
* Returns true if iter is in a latex command argument.
*/
private bool in_latex_command_argument (TextIter iter,
- out string cmd_name = null,
+ out string arg_cmd = null,
out Gee.ArrayList<bool> arguments = null,
- out string argument_contents = null,
+ out string arg_contents = null,
out bool valid_arg_contents = null)
{
- cmd_name = null;
+ arg_cmd = null;
arguments = new Gee.ArrayList<bool> ();
- argument_contents = null;
+ arg_contents = null;
valid_arg_contents = true;
string text = get_text_line_at_iter (iter);
@@ -635,7 +650,7 @@ public class CompletionProvider : GLib.Object, SourceCompletionProvider
arguments.insert (0, text[cur_pos] == '[');
if (cur_pos < end_pos)
- argument_contents = text[cur_pos + 1 : end_pos + 1];
+ arg_contents = text[cur_pos + 1 : end_pos + 1];
break;
}
@@ -672,8 +687,8 @@ public class CompletionProvider : GLib.Object, SourceCompletionProvider
// last character of the command name
if (text[cur_pos].isalpha () || text[cur_pos] == '*')
{
- cmd_name = get_latex_command_at_index (text, cur_pos);
- return cmd_name != null;
+ arg_cmd = get_latex_command_at_index (text, cur_pos);
+ return arg_cmd != null;
}
// maybe the end of a previous argument
@@ -702,18 +717,6 @@ public class CompletionProvider : GLib.Object, SourceCompletionProvider
return a.text.collate (b.text);
}
- private void clear_context (SourceCompletionContext context)
- {
- // the second argument can not be null so we use a variable...
- // the vapi should be fixed
-
- // FIXME: maybe this method is not sure, because sometimes segfault occur,
- // but it's really difficult to diagnose...
- // see bug #618004
- List<SourceCompletionItem> empty_proposals = null;
- context.add_proposals ((SourceCompletionProvider) this, empty_proposals, true);
- }
-
/*************************************************************************/
// Load the data contained in the XML file
@@ -860,7 +863,7 @@ public class CompletionProvider : GLib.Object, SourceCompletionProvider
{
case "command":
Gdk.Pixbuf pixbuf = _current_command.package != null
- ? _icon_package_required : _icon_normal_cmd;
+ ? _icon_package_required : _icon_cmd;
var item = new SourceCompletionItem (_current_command.name,
get_command_text (_current_command),
@@ -869,7 +872,8 @@ public class CompletionProvider : GLib.Object, SourceCompletionProvider
_proposals.append (item);
- // we don't need to store commands that have no argument
+ // We don't need to store commands that have no arguments,
+ // they are only in _proposals, it's sufficient.
if (0 < _current_command.args.length)
_commands[_current_command.name] = _current_command;
break;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]