diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2012-11-24 19:57:07 +0100 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2012-11-24 19:57:07 +0100 |
commit | 71f84c2ca051fb3f4e0e98faaba05e9449598b81 (patch) | |
tree | cdcf22acae633132c2690c9c4035be915760a450 | |
parent | 2add69b7f08f19ae2687276ebafcf6989915aa69 (diff) | |
download | sciteco-71f84c2ca051fb3f4e0e98faaba05e9449598b81.tar.gz |
support auto-completion of symbols in the scintilla command (ES)
* does not yet handle case-insensitive completions
* does not handle omitting of the SCI_ prefix
-rw-r--r-- | cmdline.cpp | 79 | ||||
-rw-r--r-- | gtk-info-popup.gob | 24 | ||||
-rw-r--r-- | interface-gtk.cpp | 11 | ||||
-rw-r--r-- | interface-gtk.h | 4 | ||||
-rw-r--r-- | interface-ncurses.cpp | 10 | ||||
-rw-r--r-- | interface-ncurses.h | 4 | ||||
-rw-r--r-- | interface.h | 8 | ||||
-rw-r--r-- | qbuffers.cpp | 6 |
8 files changed, 108 insertions, 38 deletions
diff --git a/cmdline.cpp b/cmdline.cpp index fd37650..674000b 100644 --- a/cmdline.cpp +++ b/cmdline.cpp @@ -12,10 +12,14 @@ #include "qbuffers.h" #include "goto.h" #include "undo.h" +#include "symbols.h" static inline const gchar *process_edit_cmd(gchar key); static gchar *macro_echo(const gchar *macro); + static gchar *filename_complete(const gchar *filename, gchar completed = ' '); +static gchar *symbol_complete(SymbolList &list, const gchar *symbol, + gchar completed = ' '); static const gchar *last_occurrence(const gchar *str, const gchar *chars = " \t\v\r\n\f<>,;@"); @@ -118,7 +122,25 @@ process_edit_cmd(gchar key) if (States::current == &States::editfile || States::current == &States::savefile || States::current == &States::loadqreg) { - gchar *new_chars = filename_complete(strings[0], escape_char); + gchar *new_chars = filename_complete(strings[0], + escape_char); + if (new_chars) + g_stpcpy(insert, new_chars); + g_free(new_chars); + } else if (States::current == &States::scintilla_symbols) { + const gchar *symbol = NULL; + SymbolList &list = Symbols::scintilla; + gchar *new_chars; + + if (strings[0]) { + symbol = last_occurrence(strings[0], ","); + if (*symbol == ',') { + symbol++; + list = Symbols::scilexer; + } + } + + new_chars = symbol_complete(list, symbol, ','); if (new_chars) g_stpcpy(insert, new_chars); g_free(new_chars); @@ -255,7 +277,7 @@ filename_complete(const gchar *filename, gchar completed) for (GList *file = g_list_first(matching); file != NULL; file = g_list_next(file)) { - Interface::PopupFileType type; + Interface::PopupEntryType type; bool in_buffer = false; if (filename_is_dir((gchar *)file->data)) { @@ -266,19 +288,14 @@ filename_complete(const gchar *filename, gchar completed) in_buffer = ring.find((gchar *)file->data); } - interface.popup_add_filename(type, (gchar *)file->data, - in_buffer); + interface.popup_add(type, (gchar *)file->data, + in_buffer); } interface.popup_show(); } else if (g_list_length(matching) == 1 && !filename_is_dir((gchar *)g_list_first(matching)->data)) { - gchar *new_insert; - - new_insert = g_strconcat(insert ? : "", - (gchar []){completed, '\0'}, NULL); - g_free(insert); - insert = new_insert; + String::append(insert, completed); } g_completion_free(completion); @@ -290,6 +307,48 @@ filename_complete(const gchar *filename, gchar completed) return insert; } +static gchar * +symbol_complete(SymbolList &list, const gchar *symbol, gchar completed) +{ + GList *glist; + GList *matching; + GCompletion *completion; + gchar *new_prefix; + gchar *insert = NULL; + + if (!symbol) + symbol = ""; + + glist = list.get_glist(); + if (!glist) + return NULL; + + completion = g_completion_new(NULL); + g_completion_add_items(completion, glist); + + matching = g_completion_complete(completion, symbol, &new_prefix); + if (new_prefix && strlen(new_prefix) > strlen(symbol)) + insert = g_strdup(new_prefix + strlen(symbol)); + g_free(new_prefix); + + if (!insert && g_list_length(matching) > 1) { + for (GList *entry = g_list_first(matching); + entry != NULL; + entry = g_list_next(entry)) { + interface.popup_add(Interface::POPUP_PLAIN, + (gchar *)entry->data); + } + + interface.popup_show(); + } else if (g_list_length(matching) == 1) { + String::append(insert, completed); + } + + g_completion_free(completion); + + return insert; +} + /* * Auxiliary functions */ diff --git a/gtk-info-popup.gob b/gtk-info-popup.gob index 8b98e3c..54c62fb 100644 --- a/gtk-info-popup.gob +++ b/gtk-info-popup.gob @@ -9,9 +9,10 @@ requires 2.0.16 %} enum GTK_INFO_POPUP { + PLAIN, FILE, DIRECTORY -} Gtk:Info:Popup:File:Type; +} Gtk:Info:Popup:Entry:Type; class Gtk:Info:Popup from Gtk:Window { private GtkWidget *parent; @@ -91,10 +92,11 @@ class Gtk:Info:Popup from Gtk:Window { } public void - add_filename(self, Gtk:Info:Popup:File:Type type, const gchar *filename, - gboolean highlight) + add(self, Gtk:Info:Popup:Entry:Type type, + const gchar *name, gboolean highlight) { static const gchar *type2stock[] = { + [GTK_INFO_POPUP_PLAIN] = NULL, [GTK_INFO_POPUP_FILE] = GTK_STOCK_FILE, [GTK_INFO_POPUP_DIRECTORY] = GTK_STOCK_DIRECTORY }; @@ -102,13 +104,19 @@ class Gtk:Info:Popup from Gtk:Window { GtkWidget *vbox = gtk_bin_get_child(GTK_BIN(self)); GtkWidget *hbox; - GtkWidget *image, *label; + GtkWidget *label; gchar *markup; hbox = gtk_hbox_new(FALSE, 5); - image = gtk_image_new_from_stock(type2stock[type], - GTK_ICON_SIZE_MENU); - gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0); + + if (type2stock[type]) { + GtkWidget *image; + + image = gtk_image_new_from_stock(type2stock[type], + GTK_ICON_SIZE_MENU); + gtk_box_pack_start(GTK_BOX(hbox), image, + FALSE, FALSE, 0); + } /* * FIXME: setting Pango attributes directly would be @@ -117,7 +125,7 @@ class Gtk:Info:Popup from Gtk:Window { label = gtk_label_new(NULL); markup = g_markup_printf_escaped("<span weight=\"%s\">%s</span>", highlight ? "bold" : "normal", - filename); + name); gtk_label_set_markup(GTK_LABEL(label), markup); g_free(markup); gtk_misc_set_alignment(GTK_MISC(label), 0., 0.5); diff --git a/interface-gtk.cpp b/interface-gtk.cpp index 9145c27..a55a2c8 100644 --- a/interface-gtk.cpp +++ b/interface-gtk.cpp @@ -146,16 +146,17 @@ InterfaceGtk::cmdline_update(const gchar *cmdline) } void -InterfaceGtk::popup_add_filename(PopupFileType type, - const gchar *filename, bool highlight) +InterfaceGtk::popup_add(PopupEntryType type, + const gchar *name, bool highlight) { - static const GtkInfoPopupFileType type2gtk[] = { + static const GtkInfoPopupEntryType type2gtk[] = { + /* [POPUP_PLAIN] = */ GTK_INFO_POPUP_PLAIN, /* [POPUP_FILE] = */ GTK_INFO_POPUP_FILE, /* [POPUP_DIRECTORY] = */ GTK_INFO_POPUP_DIRECTORY }; - gtk_info_popup_add_filename(GTK_INFO_POPUP(popup_widget), - type2gtk[type], filename, highlight); + gtk_info_popup_add(GTK_INFO_POPUP(popup_widget), + type2gtk[type], name, highlight); } void diff --git a/interface-gtk.h b/interface-gtk.h index 4a60482..b46f821 100644 --- a/interface-gtk.h +++ b/interface-gtk.h @@ -49,8 +49,8 @@ public: void cmdline_update(const gchar *cmdline = NULL); - void popup_add_filename(PopupFileType type, - const gchar *filename, bool highlight = false); + void popup_add(PopupEntryType type, + const gchar *name, bool highlight = false); inline void popup_show(void) { diff --git a/interface-ncurses.cpp b/interface-ncurses.cpp index 0d7b9ad..9b22826 100644 --- a/interface-ncurses.cpp +++ b/interface-ncurses.cpp @@ -147,6 +147,8 @@ InterfaceNCurses::vmsg(MessageType type, const gchar *fmt, va_list ap) #ifdef PDCURSES_WIN32A stdio_vmsg(type, fmt, ap); + if (isendwin()) /* batch mode */ + return; #else if (isendwin()) { /* batch mode */ stdio_vmsg(type, fmt, ap); @@ -237,17 +239,17 @@ InterfaceNCurses::cmdline_update(const gchar *cmdline) } void -InterfaceNCurses::popup_add_filename(PopupFileType type, - const gchar *filename, bool highlight) +InterfaceNCurses::popup_add(PopupEntryType type __attribute__((unused)), + const gchar *name, bool highlight) { gchar *entry; if (isendwin()) /* batch mode */ return; - entry = g_strconcat(highlight ? "*" : " ", filename, NULL); + entry = g_strconcat(highlight ? "*" : " ", name, NULL); - popup.longest = MAX(popup.longest, (gint)strlen(filename)); + popup.longest = MAX(popup.longest, (gint)strlen(name)); popup.length++; popup.list = g_slist_prepend(popup.list, entry); diff --git a/interface-ncurses.h b/interface-ncurses.h index e821699..97269a4 100644 --- a/interface-ncurses.h +++ b/interface-ncurses.h @@ -57,8 +57,8 @@ public: void cmdline_update(const gchar *cmdline = NULL); - void popup_add_filename(PopupFileType type, - const gchar *filename, bool highlight = false); + void popup_add(PopupEntryType type, + const gchar *name, bool highlight = false); void popup_show(void); void popup_clear(void); diff --git a/interface.h b/interface.h index 223ec10..35ee1f7 100644 --- a/interface.h +++ b/interface.h @@ -80,13 +80,13 @@ public: /* NULL means to redraw the current cmdline if necessary */ virtual void cmdline_update(const gchar *cmdline = NULL) = 0; - enum PopupFileType { + enum PopupEntryType { + POPUP_PLAIN, POPUP_FILE, POPUP_DIRECTORY }; - virtual void popup_add_filename(PopupFileType type, - const gchar *filename, - bool highlight = false) = 0; + virtual void popup_add(PopupEntryType type, + const gchar *name, bool highlight = false) = 0; virtual void popup_show(void) = 0; virtual void popup_clear(void) = 0; diff --git a/qbuffers.cpp b/qbuffers.cpp index de9159e..ce22b6f 100644 --- a/qbuffers.cpp +++ b/qbuffers.cpp @@ -727,9 +727,9 @@ StateEditFile::initial(void) throw (Error) if (id == 0) { for (Buffer *cur = ring.first(); cur; cur = cur->next()) - interface.popup_add_filename(Interface::POPUP_FILE, - cur->filename ? : "(Unnamed)", - cur == ring.current); + interface.popup_add(Interface::POPUP_FILE, + cur->filename ? : "(Unnamed)", + cur == ring.current); interface.popup_show(); } |