Skip to content

Instantly share code, notes, and snippets.

@codebrainz
Last active October 26, 2021 23:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save codebrainz/3824677 to your computer and use it in GitHub Desktop.
Save codebrainz/3824677 to your computer and use it in GitHub Desktop.
Automatically Sort Geany's Document Tabs
#include <geanyplugin.h>
GeanyData *geany_data;
GeanyPlugin *geany_plugin;
GeanyFunctions *geany_functions;
PLUGIN_VERSION_CHECK(211);
PLUGIN_SET_INFO("Tab Sort",
"Automatically keeps document tabs sorted",
"v0.01",
"Matthew Brush <matt@geany.org>");
struct tab_info
{
gchar *label;
GtkWidget *page;
};
static gint compare_tab_info(const struct tab_info *t1, const struct tab_info *t2)
{
return g_utf8_collate(t2->label, t1->label);
}
static void sort_tabs_callback(GObject *geany_object, GeanyDocument *doc, gpointer user_data)
{
GtkNotebook *nb = GTK_NOTEBOOK(geany_data->main_widgets->notebook);
gint index, n_pages = gtk_notebook_get_n_pages(nb);
GSList *tab, *tabs = NULL;
gtk_notebook_set_tab_reorderable(nb, GTK_WIDGET(doc->editor->sci), FALSE);
for (index = 0; index < n_pages; index++)
{
struct tab_info *inf = g_slice_alloc(sizeof(struct tab_info));
inf->page = gtk_notebook_get_nth_page(nb, index);
inf->label = document_get_basename_for_display(document_get_from_page(index), index);
tabs = g_slist_prepend(tabs, inf);
}
tabs = g_slist_sort(tabs, (GCompareFunc) compare_tab_info);
for (tab = tabs, index = 0; tab != NULL && index < n_pages; tab = tab->next, n_pages++)
gtk_notebook_reorder_child(nb, ((struct tab_info *)tab->data)->page, index);
for (tab = tabs; tab != NULL; tab = tab->next)
{
struct tab_info *inf = tab->data;
g_free(inf->label);
g_slice_free1(sizeof(struct tab_info), inf);
}
g_slist_free(tabs);
}
static void document_notebook_set_tabs_reorderable(GtkNotebook *nb, gboolean reorderable)
{
gint index, n_pages = gtk_notebook_get_n_pages(nb);
for (index = 0; index < n_pages; index++)
gtk_notebook_set_tab_reorderable(nb, gtk_notebook_get_nth_page(nb, index), reorderable);
}
void plugin_init(GeanyData *data)
{
document_notebook_set_tabs_reorderable(GTK_NOTEBOOK(data->main_widgets->notebook), FALSE);
plugin_signal_connect(geany_plugin, NULL, "document-open", TRUE, G_CALLBACK(sort_tabs_callback), NULL);
}
void plugin_cleanup(void)
{
document_notebook_set_tabs_reorderable(GTK_NOTEBOOK(geany_data->main_widgets->notebook), TRUE);
}
@codebrainz
Copy link
Author

Compile and install with:

PKG_CONFIG_PATH=/path/to/your/geany/prefix/lib/pkgconfig \
    gcc -shared -fPIC `pkg-config --cflags geany` -o tabsort.so tabsort.c \
        `pkg-config --libs geany` && \
    cp -v tabsort.so ~/.config/geany/plugins/

@MatrixMike
Copy link

Looks interesting and I was successful in earlier years in building, from source, the Geany IDE.
I am getting
typedef struct GeanyFunctionsUndefined GeanyFunctions GEANY_DEPRECATED;
and I will try and resolve this...

@codebrainz
Copy link
Author

The old plugin API should still be working, are you getting an error?

For more info: https://www.geany.org/manual/reference/legacy.html

@MatrixMike
Copy link

Actually it seemed to work OK. I would really like tabs sorted by extension so I can work on that - keeping all language sources together. thanks

@codebrainz
Copy link
Author

Yeah, it might give a warning about using the old-style plugin entry points. You could probably disable the warning by putting #define GEANY_DISABLE_DEPRECATION_WARNINGS on the first line before the plugin header is included.

The sort algorithm can be extended by changing the compare_tab_info function, for example (untested) to sort also by extension, you could do something like this:

static gint compare_tab_info(const struct tab_info *t1, const struct tab_info *t2)
{
  const char *in1 = t1->label;
  const char *in2 = t2->label;
  const char *ext1 = strrchr(in1, '.');
  const char *ext2 = strrchr(in2, '.');

  if (ext1 && ext2)
  {
    gint result = g_utf8_collate(ext2, ext1);
    if (result != 0)
      return result;
  }

  return g_utf8_collate(in2, in1);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment