[anjuta] libanjuta: Improve editor modeline support
- From: Sebastien Granjoux <sgranjoux src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [anjuta] libanjuta: Improve editor modeline support
- Date: Sun, 21 Apr 2013 09:14:29 +0000 (UTC)
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 (¶ms, content, line)) break;
+ if (parse_emacs_modeline (¶ms, 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 (¶ms, content, line)) break;
+ if (parse_emacs_modeline (¶ms, content, line)) break;
+ }
+ g_free (content);
+
+ /* Set indentation settings */
+ return set_indentation (editor, ¶ms);
+}
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]