[gnome-builder/wip/libide-merge] libide: add discovery of language time from first line of file
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/libide-merge] libide: add discovery of language time from first line of file
- Date: Sat, 21 Mar 2015 00:19:54 +0000 (UTC)
commit c7b8ea16e6cfced7e1b8ef4ff8f5cb5134130b0d
Author: Christian Hergert <christian hergert me>
Date: Fri Mar 20 17:19:06 2015 -0700
libide: add discovery of language time from first line of file
#!/usr/bin/env python will change the language to "python".
<?xml will change to "xml"
#!/usr/bin/env ruby will change to "ruby"
etc
I still think we want to take this a bit further and reload the completion
providers. That will need to force load a language by identifier using
the GIOExtension Provider. But that can come later, this is already
clearly better.
libide/ide-buffer.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 103 insertions(+), 0 deletions(-)
---
diff --git a/libide/ide-buffer.c b/libide/ide-buffer.c
index 74da9c3..82e640f 100644
--- a/libide/ide-buffer.c
+++ b/libide/ide-buffer.c
@@ -526,6 +526,89 @@ ide_buffer_reload_change_monitor (IdeBuffer *self)
}
static void
+ide_buffer_do_modeline (IdeBuffer *self)
+{
+ g_autofree gchar *line = NULL;
+ GtkTextIter begin;
+ GtkTextIter end;
+
+ g_assert (IDE_IS_BUFFER (self));
+
+ gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (self), &begin);
+ end = begin;
+ gtk_text_iter_forward_to_line_end (&end);
+ line = gtk_text_iter_get_slice (&begin, &end);
+
+ if (((line [0] == '#') && (line [1] == '!')) || g_str_has_prefix (line, "<?xml"))
+ {
+ GtkSourceLanguage *language;
+ const gchar *lang_id = NULL;
+ const gchar *target = NULL;
+ const gchar *tmp;
+
+ /*
+ * This is pretty hacky, but I don't want to call out to anything external either.
+ * If there is a discovery thing that does this that is simply to reuse (or port),
+ * just point me at it. I guess *one* option might be to use the content_type guessing that
+ * comes from glib, g_content_type_guess().
+ */
+
+ if (g_str_has_prefix (line, "<?xml"))
+ {
+ target = "xml";
+ }
+ else if ((tmp = strstr (line, "python")) != NULL)
+ {
+ if (strstr (tmp, "python3") != NULL)
+ target = "python3";
+ else
+ target = "python";
+ }
+ else if (strstr (line, "gjs") != NULL)
+ {
+ target = "javascript";
+ }
+ else if (strstr (line, "ruby") != NULL)
+ {
+ target = "ruby";
+ }
+ else if ((strstr (line, " sh") != NULL) ||
+ (strstr (line, " bash") != NULL) ||
+ (strstr (line, "/sh") != NULL) ||
+ (strstr (line, "/bash") != NULL))
+ {
+ target = "sh";
+ }
+ else if ((strstr (line, "perl") != NULL))
+ {
+ target = "perl";
+ }
+ else if ((strstr (line, "php") != NULL))
+ {
+ target = "php";
+ }
+ else if ((strstr (line, "graphviz") != NULL) ||
+ (strstr (line, "neato") != NULL))
+ {
+ target = "dot";
+ }
+
+ language = gtk_source_buffer_get_language (GTK_SOURCE_BUFFER (self));
+ if (language != NULL)
+ lang_id = gtk_source_language_get_id (language);
+
+ if (0 != g_strcmp0 (lang_id, target))
+ {
+ GtkSourceLanguageManager *manager;
+
+ manager = gtk_source_language_manager_get_default ();
+ language = gtk_source_language_manager_get_language (manager, target);
+ g_object_set (self, "language", language, NULL);
+ }
+ }
+}
+
+static void
ide_buffer_changed (GtkTextBuffer *buffer)
{
IdeBuffer *self = (IdeBuffer *)buffer;
@@ -556,8 +639,28 @@ ide_buffer_insert_text (GtkTextBuffer *buffer,
const gchar *text,
gint len)
{
+ gboolean check_modeline = FALSE;
+
+ g_assert (IDE_IS_BUFFER (buffer));
+ g_assert (location);
+ g_assert (text);
+
+ /*
+ * If we are inserting a \n at the end of the first line, then we might want to adjust the
+ * GtkSourceBuffer:language property to reflect the format. This is similar to emacs "modelines",
+ * which is apparently a bit of an overloaded term as is not to be confused with editor setting
+ * modelines.
+ */
+ if ((gtk_text_iter_get_line (location) == 0) && gtk_text_iter_ends_line (location) &&
+ ((text [0] == '\n') || ((len > 1) && (strchr (text, '\n') != NULL))))
+ check_modeline = TRUE;
+
GTK_TEXT_BUFFER_CLASS (ide_buffer_parent_class)->insert_text (buffer, location, text, len);
+
ide_buffer_emit_cursor_moved (IDE_BUFFER (buffer));
+
+ if (check_modeline)
+ ide_buffer_do_modeline (IDE_BUFFER (buffer));
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]