This feature allows quick navigation do document/workspace symbols based on their names, open files, and line numbers.
The panel's code is mostly stolen from the LSP plugin which in turn stole it from the Colomban Wendling's Commander plugin. You can view, comment on, or merge this pull request online at:
https://github.com/geany/geany-plugins/pull/1341
-- Commit Summary --
* projectorganizer: Add popup panel for navigation
-- File Changes --
M projectorganizer/README (6) M projectorganizer/src/Makefile.am (6) A projectorganizer/src/prjorg-goto-anywhere.c (332) A projectorganizer/src/prjorg-goto-anywhere.h (28) A projectorganizer/src/prjorg-goto-panel.c (496) A projectorganizer/src/prjorg-goto-panel.h (59) M projectorganizer/src/prjorg-menu.c (55)
-- Patch Links --
https://github.com/geany/geany-plugins/pull/1341.patch https://github.com/geany/geany-plugins/pull/1341.diff
@b4n requested changes on this pull request.
LGTM, see inline comments.
Apart from that, I was kind of disappointed that the "goto file" only lists Geany open documents rather than the project's documents -- maybe you'd like to add that? Also, I hoped to be able to go to a specific file's line, not only in the current file -- but that's probably less useful in practice.
- GPtrArray *arr = g_ptr_array_new_full(0, (GDestroyNotify)prjorg_goto_symbol_free);
+ gint lineno = atoi(line_str); + gint linenum = sci_get_line_count(doc->editor->sci); + guint i; + + for (i = 0; i < 4; i++) + { + PrjorgGotoSymbol *sym = g_new0(PrjorgGotoSymbol, 1); + + sym->file_name = utils_get_utf8_from_locale(doc->real_path); + sym->icon = _ICON_OTHER; + + switch (i) + { + case 0: + sym->name = g_strdup(_("line typed above"));
This string and the ones below are probably worth a translator comment, and possibly even a translation context.
}
+ pos = new_pos; + } + end_pos = pos; + + if (start_pos == end_pos) + return NULL; + + return sci_get_contents_range(sci, start_pos, end_pos); +} + + +static void goto_panel_query(const gchar *query_type, gboolean prefill) +{ + GeanyDocument *doc = document_get_current(); + gint pos = sci_get_current_position(doc->editor->sci);
:warning: dereferencing `doc` which is tested against `NULL` further down. And the `NULL` check makes sense in the (unlikely) case no document is open.
- This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* This file contains mostly stolen code from the Colomban Wendling's Commander
You're welcome :laughing:
gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &x, &dummy);
+ } + return gtk_icon_theme_load_icon(icon_theme, icon_name, x, 0, NULL); +} + + +static GdkPixbuf *get_icon_pixbuf(gint icon) +{ + if (!geany_icons[_ICON_CLASS].pixbuf) + { + guint i; + for (i = 0; i < G_N_ELEMENTS(geany_icons); i++) + geany_icons[i].pixbuf = get_tag_icon(geany_icons[i].icon_name); + } + + if (icon < _N_ICONS)
```suggestion if (icon < G_N_ELEMENTS(geany_icons)) ``` maybe?
+ case GDK_KEY_Return: + case GDK_KEY_KP_Enter: + case GDK_KEY_ISO_Enter: + tree_view_activate_focused_row(GTK_TREE_VIEW(panel_data.tree_view)); + return TRUE; + + case GDK_KEY_Page_Up: + case GDK_KEY_Page_Down: + case GDK_KEY_KP_Page_Up: + case GDK_KEY_KP_Page_Down: + { + gboolean up = event->keyval == GDK_KEY_Page_Up || event->keyval == GDK_KEY_KP_Page_Up; + tree_view_move_focus(GTK_TREE_VIEW(panel_data.tree_view), + GTK_MOVEMENT_PAGES, up ? -1 : 1); + return TRUE;
```suggestion return TRUE; ```
+ if (!symbols) + return ret; + + tf_strv = g_strsplit_set(filter, " ", -1); + + for (i = 0; i < symbols->len && j < 100; i++) + { + PrjorgGotoSymbol *symbol = symbols->pdata[i]; + gchar *normalized_name = g_utf8_normalize(symbol->name, -1, G_NORMALIZE_ALL); + gboolean filtered = FALSE; + gchar **val; + + foreach_strv(val, tf_strv) + { + gchar *normalized_val = g_utf8_normalize(*val, -1, G_NORMALIZE_ALL);
Maybe you could normalize the filter before splitting it?
@b4n Thanks for having a look at it - I'll address the changes you suggested.
Apart from that, I was kind of disappointed that the "goto file" only lists Geany open documents rather than the project's documents -- maybe you'd like to add that?
Definitely makes sense for projectorganizer which knows what files belong to the project. So yes, I should add that. This isn't possible in the LSP plugin from which this feature was taken because the plugin itself doesn't know what files belong to the project (this is only known to the server).
Maybe I could also re-introduce the fuzzy search you use in the Commander plugin so one doesn't have to type the searched query exactly. In the LSP plugin it didn't make sense for the workspace symbols where the server did something like that already but e.g. for file names or file's symbols it could be useful (still we probably shouldn't use it for workspace symbols because there's way too many of them and filtering them could take too long because of this).
Also, I hoped to be able to go to a specific file's line, not only in the current file -- but that's probably less useful in practice.
Probably not hard to add something like `filename.c:123`, I'm just sure I'd be too lazy to type something like that :-). But maybe e.g. the right arrow could complete the value in the search entry to the selected value in the list so one could then just type `:123`.
@techee pushed 6 commits.
6a541d0ab820d830bd0a49c10681c67a9153200d Add translator comments to file navigation strings 4638f25f4ff3dd4cc9e6d270ce7e5168eb20062d Avoid possible NULL pointer dereferences and fix some related problems 290c9a36a08fdffcf587822ee593dc18e6c62aa1 Formatting 5bf7b1ecb441277c016ffc2252828df4e24803e6 Fix lookup function being called before initialized in on_entry_text_notify() ab0e8a81814af49cdab779431b33a5f9555292b5 Optimize prjorg_goto_panel_show(() 4e9eb962e79cca3b0939f41729536d75aafa334e Allow navigating to non-open project files as well
@techee commented on this pull request.
- GPtrArray *arr = g_ptr_array_new_full(0, (GDestroyNotify)prjorg_goto_symbol_free);
+ gint lineno = atoi(line_str); + gint linenum = sci_get_line_count(doc->editor->sci); + guint i; + + for (i = 0; i < 4; i++) + { + PrjorgGotoSymbol *sym = g_new0(PrjorgGotoSymbol, 1); + + sym->file_name = utils_get_utf8_from_locale(doc->real_path); + sym->icon = _ICON_OTHER; + + switch (i) + { + case 0: + sym->name = g_strdup(_("line typed above"));
Done (also in the LSP plugin).
@techee commented on this pull request.
}
+ pos = new_pos; + } + end_pos = pos; + + if (start_pos == end_pos) + return NULL; + + return sci_get_contents_range(sci, start_pos, end_pos); +} + + +static void goto_panel_query(const gchar *query_type, gboolean prefill) +{ + GeanyDocument *doc = document_get_current(); + gint pos = sci_get_current_position(doc->editor->sci);
Fixed, together with some other issues (also in the LSP plugin).
@techee commented on this pull request.
gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &x, &dummy);
+ } + return gtk_icon_theme_load_icon(icon_theme, icon_name, x, 0, NULL); +} + + +static GdkPixbuf *get_icon_pixbuf(gint icon) +{ + if (!geany_icons[_ICON_CLASS].pixbuf) + { + guint i; + for (i = 0; i < G_N_ELEMENTS(geany_icons); i++) + geany_icons[i].pixbuf = get_tag_icon(geany_icons[i].icon_name); + } + + if (icon < _N_ICONS)
I'd prefer if https://github.com/geany/geany/pull/3849/commits/1931fcc2f4d5de46871c85a7829... from https://github.com/geany/geany/pull/3849 could be merged and used here. While the icons can be accessed this way, if someone reorganizes something in Geany, it will break. So better have some proper API for accessing these icons.
@techee commented on this pull request.
+ case GDK_KEY_Return: + case GDK_KEY_KP_Enter: + case GDK_KEY_ISO_Enter: + tree_view_activate_focused_row(GTK_TREE_VIEW(panel_data.tree_view)); + return TRUE; + + case GDK_KEY_Page_Up: + case GDK_KEY_Page_Down: + case GDK_KEY_KP_Page_Up: + case GDK_KEY_KP_Page_Down: + { + gboolean up = event->keyval == GDK_KEY_Page_Up || event->keyval == GDK_KEY_KP_Page_Up; + tree_view_move_focus(GTK_TREE_VIEW(panel_data.tree_view), + GTK_MOVEMENT_PAGES, up ? -1 : 1); + return TRUE;
Done.
@techee commented on this pull request.
+ if (!symbols) + return ret; + + tf_strv = g_strsplit_set(filter, " ", -1); + + for (i = 0; i < symbols->len && j < 100; i++) + { + PrjorgGotoSymbol *symbol = symbols->pdata[i]; + gchar *normalized_name = g_utf8_normalize(symbol->name, -1, G_NORMALIZE_ALL); + gboolean filtered = FALSE; + gchar **val; + + foreach_strv(val, tf_strv) + { + gchar *normalized_val = g_utf8_normalize(*val, -1, G_NORMALIZE_ALL);
Done.
Apart from that, I was kind of disappointed that the "goto file" only lists Geany open documents rather than the project's documents -- maybe you'd like to add that?
Done in the last commit - open files are sorted before project files and also non-open project files don't have any icon in front of them to distinguish them from the open files.
Also, I hoped to be able to go to a specific file's line, not only in the current file -- but that's probably less useful in practice.
Not done now, possibly in the future.
@techee pushed 1 commit.
52ad718c2a847c145781d8b0750984e4f713364e Use newly introduced Geany API to access symbol icons
I've updated this PR to use https://github.com/geany/geany/pull/3916. What's still missing is updating the required Geany API once we bump it in Geany.
@techee pushed 1 commit.
481f688f3b911ef000e859b02f51305ea5f3ec83 Update required Geany API level
@techee pushed 1 commit.
c00e96f3cffae558ea43d2bb5dd4a0434dbcd1b8 Mention that search is performed both in open and project files in README
What's still missing is updating the required Geany API once we bump it in Geany.
Done now. This PR is complete from my point of view.
Unless there are any objections, I'll squash all the commits into one and merge this PR in about a week.
Merged #1341 into master.
github-comments@lists.geany.org