[anjuta] libanjuta: Improve editor modeline support



commit 9703cedd44959cd4bddcd80ec581f060e4bc9987
Author: Sébastien Granjoux <seb sfo free fr>
Date:   Sun Apr 21 10:52:09 2013 +0200

    libanjuta: Improve editor modeline support
    
    Move modeline support in libanjuta because it is used by both python and C
    indentation plugins.
    Check modeline not only on the first line.

 libanjuta/Makefile.am                              |   7 +-
 libanjuta/anjuta-modeline.c                        | 371 +++++++++++++++++++++
 libanjuta/anjuta-modeline.h                        |  33 ++
 libanjuta/libanjuta.h                              |   1 +
 .../C/language-support-cpp-modelines-emacs.page    |   5 +-
 .../C/language-support-cpp-modelines-vim.page      |   4 +-
 plugins/indentation-c-style/indentation.c          |   6 +-
 plugins/indentation-c-style/plugin.c               | 254 +-------------
 plugins/indentation-c-style/plugin.h               |   3 -
 plugins/indentation-python-style/plugin.h          |   3 -
 .../indentation-python-style/python-indentation.c  | 260 +--------------
 11 files changed, 422 insertions(+), 525 deletions(-)
---
diff --git a/libanjuta/Makefile.am b/libanjuta/Makefile.am
index d6a1ad7..4ac227e 100644
--- a/libanjuta/Makefile.am
+++ b/libanjuta/Makefile.am
@@ -136,7 +136,9 @@ libanjuta_3_la_SOURCES= \
        anjuta-completion.h \
        anjuta-completion.c \
        anjuta-close-button.c \
-       anjuta-close-button.h
+       anjuta-close-button.h \
+       anjuta-modeline.c \
+       anjuta-modeline.h
 
 # Glade module
 if ENABLE_GLADE_CATALOG
@@ -213,7 +215,8 @@ libanjuta_include = \
        anjuta-token-list.h \
        anjuta-token-stream.h \
        anjuta-tree-combo.h \
-       anjuta-close-button.h
+       anjuta-close-button.h \
+       anjuta-modeline.h
 
 libanjutainclude_HEADERS = \
        $(libanjuta_include) \
diff --git a/libanjuta/anjuta-modeline.c b/libanjuta/anjuta-modeline.c
new file mode 100644
index 0000000..45eb514
--- /dev/null
+++ b/libanjuta/anjuta-modeline.c
@@ -0,0 +1,371 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta-modeline.c
+ * Copyright (C) Sébastien Granjoux 2013 <seb sfo free fr>
+ * 
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * SECTION:anjuta-modeline
+ * @short_description: Parse editor mode line
+ * @see_also:
+ * @stability: Unstable
+ * @include: libanjuta/anjuta-modeline.h
+ *
+ */
+
+#include "anjuta-modeline.h"
+
+#include "anjuta-debug.h"
+
+#include <glib-object.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+/* Types declarations
+ *---------------------------------------------------------------------------*/
+
+enum {
+       SET_USE_SPACES = 1 << 0,
+       SET_STATEMENT_INDENTATION = 1 << 1,
+       SET_TAB_SIZE = 1 << 2,
+       CHECK_NEXT = 1 << 4
+};
+
+typedef struct {
+       gint settings;
+
+       gint use_spaces;
+       gint statement_indentation;
+       gint tab_size;
+} IndentationParams;
+
+
+/* Helpers functions
+ *---------------------------------------------------------------------------*/
+
+/* Private functions
+ *---------------------------------------------------------------------------*/
+
+static gchar *
+get_editor_line (IAnjutaEditor *editor, gint line)
+{
+       IAnjutaIterable *start;
+       IAnjutaIterable *end;
+       gchar *content = NULL;
+
+       if (line < 0)
+       {
+               gint last;
+               
+               end = ianjuta_editor_get_end_position(editor, NULL);
+               last = ianjuta_editor_get_line_from_position (editor, end, NULL);
+               line = last + line;
+               g_object_unref (end);
+       }
+       if (line > 0)
+       {
+               start = ianjuta_editor_get_line_begin_position (editor, line, NULL);
+               end = ianjuta_editor_get_line_end_position (editor, line, NULL);
+               content = ianjuta_editor_get_text (editor, start, end, NULL);
+               g_object_unref (start);
+               g_object_unref (end);
+       }
+
+       return content;
+}
+
+static void
+set_vim_params (IndentationParams *params, const gchar *key, const gchar *value)
+{
+       //DEBUG_PRINT ("Setting indent param: %s = %s", key, value);
+       if ((strcmp (key, "expandtab") == 0) ||
+           (strcmp (key, "et") == 0))
+       {
+               params->use_spaces = 1;
+               params->settings |= SET_USE_SPACES;
+       }
+       else if ((strcmp (key, "noexpandtab") == 0) ||
+                (strcmp (key, "noet") == 0))
+       {
+               params->use_spaces = 0;
+               params->settings |= SET_USE_SPACES;
+       }
+       else if ((strcmp (key, "shiftwidth") == 0) ||
+                (strcmp (key, "sw") == 0))
+       {
+               params->statement_indentation = atoi (value);
+               params->settings |= SET_STATEMENT_INDENTATION;
+       }
+       else if ((strcmp (key, "softtabstop") == 0) ||
+                (strcmp (key, "sts") == 0) ||
+                (strcmp (key, "tabstop") == 0) ||
+                (strcmp (key, "ts") == 0))
+       {
+               params->tab_size = atoi (value);
+               params->settings |= SET_TAB_SIZE;
+       }
+}
+
+static gboolean
+parse_vim_modeline (IndentationParams *params, const gchar *line, gint linenum)
+{
+       gchar *ptr;
+       gchar *end;
+       gchar *key;
+       gchar *value;
+
+       /* Check the first 5 and last 5 lines */
+       if ((linenum < -5) || (linenum == 0) || (linenum > 5))
+       {
+               return FALSE;
+       }
+
+       ptr = strstr (line, "vim:");
+       if (ptr == NULL)
+       {
+               if ((linenum != -5) && (linenum != 5)) params->settings = CHECK_NEXT;
+               return FALSE;
+       }
+       ptr += 4;
+       while (g_ascii_isspace (*ptr)) ptr++;
+       if (strncmp (ptr, "set", 3) != 0)
+       {
+               if ((linenum != -5) && (linenum != 5)) params->settings = CHECK_NEXT;
+               return FALSE;
+       }
+       ptr += 3;
+
+       for (end = ptr;; end++)
+       {
+               if ((*end == ':') && (*(end-1) != '\\')) break;
+       }
+       *end = '\0';
+
+       while (*ptr != '\0')
+       {
+               gchar sep;
+               
+               while (g_ascii_isspace (*ptr)) ptr++;
+               if (*ptr == '\0') break;
+
+               /* Get key */
+               key = ptr++;
+               value = NULL;
+               while ((*ptr != '\0') && (*ptr != '=') && !g_ascii_isspace(*ptr)) ptr++;
+               sep = *ptr;
+               *ptr = '\0';
+
+               if (sep == '=')
+               {
+                       /* Get value */
+                       value = ++ptr;
+                       while ((*ptr != '\0') && !g_ascii_isspace(*ptr)) ptr++;
+                       sep = *ptr;
+                       *ptr = '\0';
+                       
+                       if (sep != '\0') ptr++;
+               }
+
+               set_vim_params (params, key, value);
+       }
+
+       return TRUE;
+}
+
+static void
+set_emacs_params (IndentationParams *params, const gchar *key, const gchar *value)
+{
+       //DEBUG_PRINT ("Setting indent param: %s = %s", key, value);
+       if (strcmp (key, "indent-tabs-mode") == 0)
+       {
+               if (strcmp (value, "t") == 0)
+               {
+                       params->use_spaces = 0;
+                       params->settings |= SET_USE_SPACES;
+               }
+               else if (strcmp (value, "nil") == 0)
+               {
+                       params->use_spaces = 1;
+                       params->settings |= SET_USE_SPACES;
+               }
+       }
+       else if ((strcmp (key, "c-basic-offset") == 0) ||
+               (strcmp (key, "indent-offset") == 0))
+       {
+               params->statement_indentation = atoi (value);
+               params->settings |= SET_STATEMENT_INDENTATION;
+       }
+       else if (strcasecmp (key, "tab-width") == 0)
+       {
+               params->tab_size = atoi (value);
+               params->settings |= SET_TAB_SIZE;
+       }
+}
+
+static gboolean
+parse_emacs_modeline (IndentationParams *params, gchar *line, gint linenum)
+{
+       gchar *ptr;
+       gchar *end;
+       gchar *key;
+       gchar *value;
+       
+       if (linenum == 1)
+       {
+               /* If first line is a shebang, check second line */
+               if ((line[0] == '#') && (line[1] =='!'))
+               {
+                       params->settings |= CHECK_NEXT;
+                       return FALSE;
+               }
+       }
+       else if (linenum != 2)
+       {
+               /* Check only the 2 first lines */
+               return FALSE;
+       }
+
+       ptr = strstr (line, "-*-");
+       if (ptr == NULL) return FALSE;
+       ptr += 3;
+       end = strstr (ptr, "-*-");
+       if (end == NULL) return FALSE;
+       *end = '\0';
+
+       while (*ptr != '\0')
+       {
+               gchar sep;
+               
+               while (g_ascii_isspace (*ptr)) ptr++;
+               if (*ptr == '\0') break;
+
+               /* Get key */
+               key = ptr++;
+               value = NULL;
+               while ((*ptr != '\0') && (*ptr != ':') && (*ptr != ';')) ptr++;
+               sep = *ptr;
+               
+               end = ptr - 1;
+               while (g_ascii_isspace (*end)) end--;
+               *(end + 1) = '\0';
+                       
+               if (sep == ':')
+               {
+                       /* Get value */
+                       ptr++;
+                       while (g_ascii_isspace (*ptr)) ptr++;
+                       if (*ptr != '\0')
+                       {
+                               value = ptr;
+                               while ((*ptr != '\0') && (*ptr != ';')) ptr++;
+                               sep = *ptr;
+                       
+                               end = ptr - 1;
+                               while (g_ascii_isspace (*end)) end--;
+                               *(end + 1) = '\0';
+                       
+                               if (sep == ';') ptr++;
+                       }
+               }
+
+               set_emacs_params (params, key, value);
+       }
+
+       return TRUE;
+}
+
+
+static gboolean 
+set_indentation (IAnjutaEditor *editor, IndentationParams *params)
+{
+       if (params->settings == 0) return FALSE;
+
+       if (params->settings & SET_USE_SPACES)
+               ianjuta_editor_set_use_spaces (editor, params->use_spaces, NULL);
+
+       if (params->settings & SET_STATEMENT_INDENTATION)
+               ianjuta_editor_set_indentsize (editor, params->statement_indentation, NULL);
+
+       if (params->settings & SET_TAB_SIZE)
+               ianjuta_editor_set_tabsize (editor, params->tab_size, NULL);
+
+       return TRUE;
+}
+
+
+/* Public functions
+ *---------------------------------------------------------------------------*/
+
+
+/**
+ * anjuta_apply_modeline:
+ * @editor: #IAnjutaEditor object
+ *
+ * Check the editor buffer to find a mode line and update the indentation
+ * settings if found.
+ * 
+ * The mode line is special line used by the text editor to define settings for
+ * the current file, typically indentation. Anjuta currently recognize two kinds
+ * of mode line:
+ *
+ * Emacs mode line, on the first or the second line if the first one is a
+ * shebang (#!) with the following format:
+ * -*- key1: value1; key2: value2 -*-
+ *
+ * Vim mode line, one the first 5 or the last 5 lines with the following format:
+ * vim:set key1=value1 key2=value2
+ * 
+ * Returns: %TRUE if a mode line has been found and applied.
+ */
+gboolean
+anjuta_apply_modeline (IAnjutaEditor *editor)
+{
+       IndentationParams params = {CHECK_NEXT,0,0,0};
+       gint line;
+       gchar *content = NULL;
+       
+       g_return_val_if_fail (IANJUTA_IS_EDITOR (editor), FALSE);
+
+       /* Check the first lines */
+       for (line = 1; params.settings == CHECK_NEXT; line++)
+       {
+               g_free (content);
+               content = get_editor_line (editor, line);
+               if (content == NULL) return FALSE;
+
+               params.settings = 0;
+               if (parse_vim_modeline (&params, content, line)) break;
+               if (parse_emacs_modeline (&params, content, line)) break;
+       }
+
+       /* Check the last lines */
+       if (params.settings == 0) params.settings = CHECK_NEXT;
+       for (line = -1;params.settings == CHECK_NEXT; line--)
+       {
+               g_free (content);
+               content = get_editor_line (editor, line);
+               if (content == NULL) return FALSE;
+
+               params.settings = 0;
+               if (parse_vim_modeline (&params, content, line)) break;
+               if (parse_emacs_modeline (&params, content, line)) break;
+       }
+       g_free (content);
+
+       /* Set indentation settings */
+       return set_indentation (editor, &params);
+}
diff --git a/libanjuta/anjuta-modeline.h b/libanjuta/anjuta-modeline.h
new file mode 100644
index 0000000..f62f011
--- /dev/null
+++ b/libanjuta/anjuta-modeline.h
@@ -0,0 +1,33 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta-modeline.h
+ * Copyright (C) Sébastien Granjoux 2013 <seb sfo free fr>
+ * 
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _ANJUTA_MODELINE_H_
+#define _ANJUTA_MODELINE_H_
+
+#include <glib.h>
+
+#include <libanjuta/interfaces/ianjuta-editor.h>
+
+G_BEGIN_DECLS
+
+gboolean anjuta_apply_modeline (IAnjutaEditor *editor);
+
+G_END_DECLS
+
+#endif
diff --git a/libanjuta/libanjuta.h b/libanjuta/libanjuta.h
index faf2f24..44d75f6 100644
--- a/libanjuta/libanjuta.h
+++ b/libanjuta/libanjuta.h
@@ -75,5 +75,6 @@
 #include <libanjuta/anjuta-tree-combo.h>
 #include <libanjuta/anjuta-vcs-status.h>
 #include <libanjuta/anjuta-close-button.h>
+#include <libanjuta/anjuta-modeline.h>
 
 #endif
diff --git a/manuals/anjuta-manual/C/language-support-cpp-modelines-emacs.page 
b/manuals/anjuta-manual/C/language-support-cpp-modelines-emacs.page
index 8ff0a60..9d42295 100644
--- a/manuals/anjuta-manual/C/language-support-cpp-modelines-emacs.page
+++ b/manuals/anjuta-manual/C/language-support-cpp-modelines-emacs.page
@@ -17,7 +17,8 @@
 
   <title>Emacs modelines</title>
 
-  <p>Such modeline is a comment in the first line of the file, composed by
+  <p>Such modeline is a comment in the first line of the file or the second
+  one if the first contains a shebang (#!). It is composed by
   a list of variable names followed by <code>:</code> and a value,
   separated by <code>;</code> and surrounded by <code>-*-</code>.</p>
 
@@ -27,7 +28,7 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
   </code>
 
-  <p>Anjuta support only the following variables.</p>
+  <p>Anjuta supports only the following variables.</p>
 
   <terms>
     <item>
diff --git a/manuals/anjuta-manual/C/language-support-cpp-modelines-vim.page 
b/manuals/anjuta-manual/C/language-support-cpp-modelines-vim.page
index 2ec2c7a..8179dd5 100644
--- a/manuals/anjuta-manual/C/language-support-cpp-modelines-vim.page
+++ b/manuals/anjuta-manual/C/language-support-cpp-modelines-vim.page
@@ -17,8 +17,8 @@
 
   <title>Vim modelines</title>
 
-  <p>This modeline is a comment in the first line of the file which
-  has to start with <code>vim:</code> followed by at least one space and
+  <p>This modeline is a line in the 5 first of the 5 last of the
+  file containing <code>vim:</code> followed by at least one space and
   a list of variable names with an optional value after <code>=</code>
   separated by space or <code>:</code>.</p>
   
diff --git a/plugins/indentation-c-style/indentation.c b/plugins/indentation-c-style/indentation.c
index aeafd5d..811f852 100644
--- a/plugins/indentation-c-style/indentation.c
+++ b/plugins/indentation-c-style/indentation.c
@@ -43,11 +43,7 @@
 
 #define TAB_SIZE (ianjuta_editor_get_tabsize (editor, NULL))
 #define USE_SPACES_FOR_INDENTATION (ianjuta_editor_get_use_spaces (editor, NULL))
-
-#define INDENT_SIZE \
-       (plugin->param_statement_indentation >= 0? \
-               plugin->param_statement_indentation : \
-               g_settings_get_int (plugin->editor_settings, IANJUTA_EDITOR_INDENT_WIDTH_KEY))
+#define INDENT_SIZE (ianjuta_editor_get_indentsize (editor, NULL));
 
 #define BRACE_INDENT \
        (plugin->param_brace_indentation >= 0? \
diff --git a/plugins/indentation-c-style/plugin.c b/plugins/indentation-c-style/plugin.c
index 17ad70e..28acbe9 100644
--- a/plugins/indentation-c-style/plugin.c
+++ b/plugins/indentation-c-style/plugin.c
@@ -23,7 +23,8 @@
 #include <stdlib.h>
 #include <libanjuta/anjuta-shell.h>
 #include <libanjuta/anjuta-debug.h>
-#include "libanjuta/anjuta-utils.h"
+#include <libanjuta/anjuta-utils.h>
+#include <libanjuta/anjuta-modeline.h>
 #include <libanjuta/interfaces/ianjuta-iterable.h>
 #include <libanjuta/interfaces/ianjuta-document.h>
 #include <libanjuta/interfaces/ianjuta-document-manager.h>
@@ -59,273 +60,24 @@
 
 static gpointer parent_class;
 
-static void
-set_indentation_param_emacs (IndentCPlugin* plugin, const gchar *param,
-                       const gchar *value)
-{
-    //DEBUG_PRINT ("Setting indent param: %s = %s", param, value);
-    if (strcasecmp (param, "indent-tabs-mode") == 0)
-    {
-        if (strcasecmp (value, "t") == 0)
-        {
-            plugin->param_use_spaces = 0;
-            ianjuta_editor_set_use_spaces (IANJUTA_EDITOR (plugin->current_editor),
-                                           FALSE, NULL);
-        }
-        else if (strcasecmp (value, "nil") == 0)
-        {
-            plugin->param_use_spaces = 1;
-            ianjuta_editor_set_use_spaces (IANJUTA_EDITOR (plugin->current_editor),
-                                           TRUE, NULL);
-        }
-    }
-    else if (strcasecmp (param, "c-basic-offset") == 0)
-    {
-        plugin->param_statement_indentation = atoi (value);
-        ianjuta_editor_set_indentsize (IANJUTA_EDITOR (plugin->current_editor),
-                                       plugin->param_statement_indentation, NULL);
-    }
-    else if (strcasecmp (param, "tab-width") == 0)
-    {
-        plugin->param_tab_size = atoi (value);
-        ianjuta_editor_set_tabsize (IANJUTA_EDITOR (plugin->current_editor),
-                                    plugin->param_tab_size, NULL);
-    }
-}
-
-static void
-set_indentation_param_vim (IndentCPlugin* plugin, const gchar *param,
-                       const gchar *value)
-{
-    //DEBUG_PRINT ("Setting indent param: %s = %s", param, value);
-    if (g_str_equal (param, "expandtab") ||
-        g_str_equal (param, "et"))
-    {
-            plugin->param_use_spaces = 1;
-            ianjuta_editor_set_use_spaces (IANJUTA_EDITOR (plugin->current_editor),
-                                           TRUE, NULL);
-    }
-    else if (g_str_equal (param, "noexpandtab") ||
-             g_str_equal (param, "noet"))
-    {
-          plugin->param_use_spaces = 0;
-            ianjuta_editor_set_use_spaces (IANJUTA_EDITOR (plugin->current_editor),
-                                           FALSE, NULL);
-    }
-    if (!value)
-        return;
-    else if (g_str_equal (param, "shiftwidth") ||
-             g_str_equal (param, "sw"))
-    {
-        plugin->param_statement_indentation = atoi (value);
-        ianjuta_editor_set_indentsize (IANJUTA_EDITOR (plugin->current_editor),
-                                       plugin->param_statement_indentation, NULL);
-    }
-    else if (g_str_equal (param, "softtabstop") ||
-             g_str_equal (param, "sts") ||
-             g_str_equal (param, "tabstop") ||
-             g_str_equal (param, "ts"))
-    {
-        plugin->param_tab_size = atoi (value);
-        ianjuta_editor_set_tabsize (IANJUTA_EDITOR (plugin->current_editor),
-                                    plugin->param_tab_size, NULL);
-    }
-}
 
 static void
-parse_mode_line_emacs (IndentCPlugin *plugin, const gchar *modeline)
-{
-    gchar **strv, **ptr;
-
-    strv = g_strsplit (modeline, ";", -1);
-    ptr = strv;
-    while (*ptr)
-    {
-        gchar **keyval;
-        keyval = g_strsplit (*ptr, ":", 2);
-        if (keyval[0] && keyval[1])
-        {
-            g_strstrip (keyval[0]);
-            g_strstrip (keyval[1]);
-            set_indentation_param_emacs (plugin, g_strchug (keyval[0]),
-                                   g_strchug (keyval[1]));
-        }
-        g_strfreev (keyval);
-        ptr++;
-    }
-    g_strfreev (strv);
-}
-
-static void
-parse_mode_line_vim (IndentCPlugin *plugin, const gchar *modeline)
-{
-    gchar **strv, **ptr;
-
-    strv = g_strsplit_set (modeline, " \t:", -1);
-    ptr = strv;
-    while (*ptr)
-    {
-        gchar **keyval;
-        keyval = g_strsplit (*ptr, "=", 2);
-        if (keyval[0])
-        {
-            g_strstrip (keyval[0]);
-            if (keyval[1])
-            {
-                g_strstrip (keyval[1]);
-                set_indentation_param_vim (plugin, g_strchug (keyval[0]),
-                                           g_strchug (keyval[1]));
-            }
-            else
-                set_indentation_param_vim (plugin, g_strchug (keyval[0]),
-                                           NULL);
-        }
-        g_strfreev (keyval);
-        ptr++;
-    }
-    g_strfreev (strv);
-}
-
-static gchar *
-extract_mode_line (const gchar *comment_text, gboolean* vim)
-{
-    /* Search for emacs-like modelines */
-    gchar *begin_modeline, *end_modeline;
-    begin_modeline = strstr (comment_text, "-*-");
-    if (begin_modeline)
-    {
-        begin_modeline += 3;
-        end_modeline = strstr (begin_modeline, "-*-");
-        if (end_modeline)
-        {
-          *vim = FALSE;
-                return g_strndup (begin_modeline, end_modeline - begin_modeline);
-        }
-    }
-    /* Search for vim-like modelines */
-    begin_modeline = strstr (comment_text, "vim:");
-    if (begin_modeline)
-    {
-        begin_modeline += strlen ("vim:");
-        end_modeline = strstr (begin_modeline, "*/");
-        /* Check for escape characters */
-        while (end_modeline)
-        {
-             if (!g_str_equal ((end_modeline - 1), "\\"))
-                break;
-            end_modeline++;
-            end_modeline = strstr (end_modeline, "*/");
-        }
-        if (end_modeline)
-        {
-            gchar* vim_modeline = g_strndup (begin_modeline, end_modeline - begin_modeline);
-            *vim = TRUE;
-            return vim_modeline;
-        }
-    }
-    return NULL;
-}
-
-#define MINI_BUFFER_SIZE 3
-static void
 initialize_indentation_params (IndentCPlugin *plugin)
 {
-    IAnjutaIterable *iter;
-    GString *comment_text;
-    gboolean comment_begun = FALSE;
-    gboolean line_comment = FALSE;
-    gchar mini_buffer[MINI_BUFFER_SIZE] = {0};
-
     plugin->smart_indentation = g_settings_get_boolean (plugin->settings, PREF_INDENT_AUTOMATIC);
     /* Disable editor intern auto-indent if smart indentation is enabled */
     ianjuta_editor_set_auto_indent (IANJUTA_EDITOR(plugin->current_editor),
                                     !plugin->smart_indentation, NULL);
 
     /* Initialize indentation parameters */
-    plugin->param_tab_size = -1;
-    plugin->param_statement_indentation = -1;
     plugin->param_brace_indentation = -1;
     plugin->param_case_indentation = -1;
     plugin->param_label_indentation = -1;
-    plugin->param_use_spaces = -1;
 
     if (g_settings_get_boolean (plugin->settings,
                                 PREF_INDENT_MODELINE))
     {
-        /* Find the first comment text in the buffer */
-        comment_text = g_string_new (NULL);
-        iter = ianjuta_editor_get_start_position (IANJUTA_EDITOR (plugin->current_editor),
-                                                  NULL);
-        do
-        {
-            gboolean shift_buffer = TRUE;
-            gint i;
-            gchar ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter),
-                                                     0, NULL);
-
-            for (i = 0; i < MINI_BUFFER_SIZE - 1; i++)
-            {
-                if (mini_buffer[i] == '\0')
-                {
-                    mini_buffer[i] = ch;
-                    shift_buffer = FALSE;
-                    break;
-                }
-            }
-            if (shift_buffer == TRUE)
-            {
-                /* Shift buffer and add */
-                for (i = 0; i < MINI_BUFFER_SIZE - 1; i++)
-                    mini_buffer [i] = mini_buffer[i+1];
-                mini_buffer[i] = ch;
-            }
-
-            if (!comment_begun && strncmp (mini_buffer, "/*", 2) == 0)
-            {
-                comment_begun = TRUE;
-                /* Reset buffer */
-                mini_buffer[0] = mini_buffer[1] = '\0';
-            }
-            else if (!comment_begun && strncmp (mini_buffer, "//", 2) == 0)
-            {
-                comment_begun = TRUE;
-                line_comment = TRUE;
-            }
-            else if (!comment_begun && mini_buffer[1] != '\0')
-            {
-                /* The buffer doesn't begin with a comment */
-                break;
-            }
-            else if (comment_begun)
-            {
-                if ((line_comment && ch == '\n') ||
-                    (!line_comment && strncmp (mini_buffer, "*/", 2) == 0))
-                {
-                    break;
-                }
-            }
-            if (comment_begun)
-                g_string_append_c (comment_text, ch);
-        }
-        while (ianjuta_iterable_next (iter, NULL));
-
-        /* DEBUG_PRINT ("Comment text: %s", comment_text->str);*/
-        if (comment_text->len > 0)
-        {
-            /* First comment found */
-            gboolean vim;
-            gchar *modeline = extract_mode_line (comment_text->str, &vim);
-            if (modeline)
-            {
-                if (!vim)
-                    parse_mode_line_emacs (plugin, modeline);
-                else
-                    parse_mode_line_vim (plugin, modeline);
-                g_free (modeline);
-            }
-        }
-        g_string_free (comment_text, TRUE);
-        g_object_unref (iter);
+        anjuta_apply_modeline (IANJUTA_EDITOR (plugin->current_editor));
     }
 }
 
diff --git a/plugins/indentation-c-style/plugin.h b/plugins/indentation-c-style/plugin.h
index 7fff92f..6dac158 100644
--- a/plugins/indentation-c-style/plugin.h
+++ b/plugins/indentation-c-style/plugin.h
@@ -50,9 +50,6 @@ struct _IndentCPlugin {
        const gchar *current_language;
 
        /* Adaptive indentation parameters */
-       gint param_tab_size;
-       gint param_use_spaces;
-       gint param_statement_indentation;
        gint param_brace_indentation;
        gint param_case_indentation;
        gint param_label_indentation;
diff --git a/plugins/indentation-python-style/plugin.h b/plugins/indentation-python-style/plugin.h
index cdbb7e7..cd28f81 100644
--- a/plugins/indentation-python-style/plugin.h
+++ b/plugins/indentation-python-style/plugin.h
@@ -59,9 +59,6 @@ struct _IndentPythonPlugin{
        gint editor_watch_id;
        
        /* Adaptive indentation parameters */
-       gint param_tab_size;
-       gint param_use_spaces;
-       gint param_statement_indentation;
        gint param_brace_indentation;
        gint param_case_indentation;
        gint param_label_indentation;
diff --git a/plugins/indentation-python-style/python-indentation.c 
b/plugins/indentation-python-style/python-indentation.c
index e783243..d7cf2b8 100644
--- a/plugins/indentation-python-style/python-indentation.c
+++ b/plugins/indentation-python-style/python-indentation.c
@@ -24,6 +24,7 @@
 #include <libanjuta/anjuta-debug.h>
 #include <libanjuta/anjuta-launcher.h>
 #include <libanjuta/anjuta-preferences.h>
+#include <libanjuta/anjuta-modeline.h>
 #include <libanjuta/interfaces/ianjuta-iterable.h>
 #include <libanjuta/interfaces/ianjuta-document.h>
 #include <libanjuta/interfaces/ianjuta-document-manager.h>
@@ -48,10 +49,7 @@
 
 #define USE_SPACES_FOR_INDENTATION (ianjuta_editor_get_use_spaces (editor, NULL))
 
-#define INDENT_SIZE \
-(plugin->param_statement_indentation >= 0? \
-plugin->param_statement_indentation : \
-g_settings_get_int (plugin->editor_settings, IANJUTA_EDITOR_INDENT_WIDTH_KEY))
+#define INDENT_SIZE (ianjuta_editor_get_indentsize (editor, NULL))
 
 #define BRACE_INDENT \
 (plugin->param_brace_indentation >= 0? \
@@ -194,269 +192,17 @@ get_line_indentation_string (IAnjutaEditor *editor, gint spaces, gint line_inden
        return indent_string;
 }
 
-static void
-set_indentation_param_emacs (IndentPythonPlugin* plugin, const gchar *param,
-                             const gchar *value)
-{
-       //DEBUG_PRINT ("Setting indent param: %s = %s", param, value);
-       if (strcasecmp (param, "indent-tabs-mode") == 0)
-       {
-               if (strcasecmp (value, "t") == 0)
-               {
-                       plugin->param_use_spaces = 0;
-                       ianjuta_editor_set_use_spaces (IANJUTA_EDITOR (plugin->current_editor),
-                                                      FALSE, NULL);
-               }
-               else if (strcasecmp (value, "nil") == 0)
-               {
-                       plugin->param_use_spaces = 1;
-                       ianjuta_editor_set_use_spaces (IANJUTA_EDITOR (plugin->current_editor),
-                                                      TRUE, NULL);
-               }
-       }
-       else if (strcasecmp (param, "c-basic-offset") == 0)
-       {
-               plugin->param_statement_indentation = atoi (value);
-               ianjuta_editor_set_indentsize (IANJUTA_EDITOR (plugin->current_editor),
-                                              plugin->param_statement_indentation, NULL);
-       }
-       else if (strcasecmp (param, "tab-width") == 0)
-       {
-               plugin->param_tab_size = atoi (value);
-               ianjuta_editor_set_tabsize (IANJUTA_EDITOR (plugin->current_editor),
-                                           plugin->param_tab_size, NULL);
-       }
-}
-
-static void
-set_indentation_param_vim (IndentPythonPlugin* plugin, const gchar *param,
-                           const gchar *value)
-{
-       //DEBUG_PRINT ("Setting indent param: %s = %s", param, value);
-       if (g_str_equal (param, "expandtab") ||
-           g_str_equal (param, "et"))
-       {
-               plugin->param_use_spaces = 1;
-               ianjuta_editor_set_use_spaces (IANJUTA_EDITOR (plugin->current_editor),
-                                              TRUE, NULL);
-       }
-       else if (g_str_equal (param, "noexpandtabs") ||
-                g_str_equal (param, "noet"))
-       {
-               plugin->param_use_spaces = 0;
-               ianjuta_editor_set_use_spaces (IANJUTA_EDITOR (plugin->current_editor),
-                                              FALSE, NULL);
-       }
-       if (!value)
-               return;
-       else if (g_str_equal (param, "shiftwidth") ||
-                g_str_equal (param, "sw"))
-       {
-               plugin->param_statement_indentation = atoi (value);
-               ianjuta_editor_set_indentsize (IANJUTA_EDITOR (plugin->current_editor),
-                                              plugin->param_statement_indentation, NULL);
-       }
-       else if (g_str_equal (param, "softtabstop") ||
-                g_str_equal (param, "sts") ||
-                g_str_equal (param, "tabstop") ||
-                g_str_equal (param, "ts"))
-       {
-               plugin->param_tab_size = atoi (value);
-               ianjuta_editor_set_tabsize (IANJUTA_EDITOR (plugin->current_editor),
-                                           plugin->param_tab_size, NULL);
-       }
-}
-
-static void
-parse_mode_line_emacs (IndentPythonPlugin *plugin, const gchar *modeline)
-{
-       gchar **strv, **ptr;
-
-       strv = g_strsplit (modeline, ";", -1);
-       ptr = strv;
-       while (*ptr)
-       {
-               gchar **keyval;
-               keyval = g_strsplit (*ptr, ":", 2);
-               if (keyval[0] && keyval[1])
-               {
-                       g_strstrip (keyval[0]);
-                       g_strstrip (keyval[1]);
-                       set_indentation_param_emacs (plugin, g_strchug (keyval[0]),
-                                                    g_strchug (keyval[1]));
-               }
-               g_strfreev (keyval);
-               ptr++;
-       }
-       g_strfreev (strv);
-}
-
-static void
-parse_mode_line_vim (IndentPythonPlugin *plugin, const gchar *modeline)
-{
-       gchar **strv, **ptr;
-
-       strv = g_strsplit (modeline, " ", -1);
-       ptr = strv;
-       while (*ptr)
-       {
-               gchar **keyval;
-               keyval = g_strsplit (*ptr, "=", 2);
-               if (keyval[0])
-               {
-                       g_strstrip (keyval[0]);
-                       if (keyval[1])
-                       {
-                               g_strstrip (keyval[1]);
-                               set_indentation_param_vim (plugin, g_strchug (keyval[0]),
-                                                          g_strchug (keyval[1]));
-                       }
-                       else
-                               set_indentation_param_vim (plugin, g_strchug (keyval[0]),
-                                                          NULL);        
-               }
-               g_strfreev (keyval);
-               ptr++;
-       }
-       g_strfreev (strv);
-}
-
-static gchar *
-extract_mode_line (const gchar *comment_text, gboolean* vim)
-{
-       /* Search for emacs-like modelines */
-       gchar *begin_modeline, *end_modeline;
-       begin_modeline = strstr (comment_text, "-*-");
-       if (begin_modeline)
-       {
-               begin_modeline += 3;
-               end_modeline = strstr (begin_modeline, "-*-");
-               if (end_modeline)
-               {
-                       *vim = FALSE;
-                       return g_strndup (begin_modeline, end_modeline - begin_modeline);
-               }
-       }
-       /* Search for vim-like modelines */
-       begin_modeline = strstr (comment_text, "vim:set");
-       if (begin_modeline)
-       {
-               begin_modeline += 7;
-               end_modeline = strstr (begin_modeline, ":");
-               /* Check for escape characters */
-               while (end_modeline)
-               {
-                       if (!g_str_equal ((end_modeline - 1), "\\"))
-                               break;
-                       end_modeline++;
-                       end_modeline = strstr (end_modeline, ":");
-               }
-               if (end_modeline)
-               {
-                       gchar* vim_modeline = g_strndup (begin_modeline, end_modeline - begin_modeline);
-                       *vim = TRUE;
-                       return vim_modeline;
-               }
-       }
-       return NULL;
-}
-
-#define MINI_BUFFER_SIZE 3
 
 void
 python_indent_init (IndentPythonPlugin* plugin)
 {
-       IAnjutaIterable *iter;
-       GString *comment_text;
-       gboolean comment_begun = FALSE;
-       gboolean line_comment = FALSE;
-       gchar mini_buffer[MINI_BUFFER_SIZE] = {0};
 
        /* Initialize indentation parameters */
-       plugin->param_tab_size = -1;
-       plugin->param_statement_indentation = -1;
        plugin->param_brace_indentation = -1;
        plugin->param_case_indentation = -1;
        plugin->param_label_indentation = -1;
-       plugin->param_use_spaces = -1;
-
-       /* Find the first comment text in the buffer */
-       comment_text = g_string_new (NULL);
-       iter = ianjuta_editor_get_start_position (IANJUTA_EDITOR (plugin->current_editor),
-                                                 NULL);
-       do
-       {
-               gboolean shift_buffer = TRUE;
-               gint i;
-               gchar ch = ianjuta_editor_cell_get_char (IANJUTA_EDITOR_CELL (iter),
-                                                        0, NULL);
-
-               for (i = 0; i < MINI_BUFFER_SIZE - 1; i++)
-               {
-                       if (mini_buffer[i] == '\0')
-                       {
-                               mini_buffer[i] = ch;
-                               shift_buffer = FALSE;
-                               break;
-                       }
-               }
-               if (shift_buffer == TRUE)
-               {
-                       /* Shift buffer and add */
-                       for (i = 0; i < MINI_BUFFER_SIZE - 1; i++)
-                               mini_buffer [i] = mini_buffer[i+1];
-                       mini_buffer[i] = ch;
-               }
-
-               if (!comment_begun && strncmp (mini_buffer, "/*", 2) == 0)
-               {
-                       comment_begun = TRUE;
-                       /* Reset buffer */
-                       mini_buffer[0] = mini_buffer[1] = '\0';
-               }
-               else if (!comment_begun && strncmp (mini_buffer, "//", 2) == 0)
-                                                   {
-                                                                                               comment_begun 
= TRUE;
-                                                                                               line_comment 
= TRUE;
-                                                                                       }
-                                                   else if (!comment_begun && mini_buffer[1] != '\0')
-                                                   {
-                                                                                               /* The buffer 
doesn't begin with a comment */
-                                                                                               break;
-                                                                                       }
-                                                   else if (comment_begun)
-                                                   {
-                                                                                               if 
((line_comment && ch == '\n') ||
-                                                                                                   
(!line_comment && strncmp (mini_buffer, "*/", 2) == 0))
-                                                                                               {
-                                                                                                       break;
-                                                                                               }
-                                                                                       }
-
-                                                   if (comment_begun)
-                                                   g_string_append_c (comment_text, ch);
-
-                                           }
-       while (ianjuta_iterable_next (iter, NULL));
-
-       /* DEBUG_PRINT ("Comment text: %s", comment_text->str);*/
-       if (comment_text->len > 0)
-       {
 
-               /* First comment found */
-               gboolean vim;
-               gchar *modeline = extract_mode_line (comment_text->str, &vim);
-               if (modeline)
-               {
-                       if (!vim)
-                               parse_mode_line_emacs (plugin, modeline);
-                       else
-                               parse_mode_line_vim (plugin, modeline);
-                       g_free (modeline);
-               }
-       }
-       g_string_free (comment_text, TRUE);
-       g_object_unref (iter);
+       anjuta_apply_modeline (IANJUTA_EDITOR (plugin->current_editor));
 }
 
 static gint


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]