Started regex-based indenter
parent
c2ca12a203
commit
e2279c8e5b
|
@ -1,8 +1,8 @@
|
||||||
# XXX it needs plugins to be built first but plugins want mooedit-enums.h
|
# XXX it needs plugins to be built first but plugins want mooedit-enums.h
|
||||||
SUBDIRS = gtksourceview plugins language-specs
|
SUBDIRS = gtksourceview plugins language-specs
|
||||||
|
|
||||||
mooedit_toolsdir = $(MOO_DATA_DIR)
|
mooedit_datadir = $(MOO_DATA_DIR)
|
||||||
mooedit_tools_DATA = context.cfg menu.cfg filters.xml
|
mooedit_data_DATA = context.cfg menu.cfg filters.xml indent.xml
|
||||||
|
|
||||||
moocommand-exe.lo: moocommand-exe-unix.lo
|
moocommand-exe.lo: moocommand-exe-unix.lo
|
||||||
moocommand-exe-private.lo: moocommand-exe-unix.lo
|
moocommand-exe-private.lo: moocommand-exe-unix.lo
|
||||||
|
@ -13,7 +13,9 @@ objc_sources = \
|
||||||
mooedit-script.h \
|
mooedit-script.h \
|
||||||
mooedit-script.m \
|
mooedit-script.m \
|
||||||
moocommand-script.h \
|
moocommand-script.h \
|
||||||
moocommand-script.m
|
moocommand-script.m \
|
||||||
|
mooindenter-regex.h \
|
||||||
|
mooindenter-regex.m
|
||||||
|
|
||||||
unix_sources = \
|
unix_sources = \
|
||||||
moocommand-exe-unix.c
|
moocommand-exe-unix.c
|
||||||
|
@ -209,7 +211,7 @@ CLEANFILES += mooedit-ui.h medit-ui.h
|
||||||
|
|
||||||
EXTRA_DIST += \
|
EXTRA_DIST += \
|
||||||
$(completion_sources) \
|
$(completion_sources) \
|
||||||
$(mooedit_tools_DATA) \
|
$(mooedit_data_DATA) \
|
||||||
medit-ui.xml \
|
medit-ui.xml \
|
||||||
mooedit-ui.xml
|
mooedit-ui.xml
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<indent-settings version="1">
|
||||||
|
<lang id="python">
|
||||||
|
<shift pattern=":\s*$"/>
|
||||||
|
</lang>
|
||||||
|
</indent-settings>
|
|
@ -249,7 +249,7 @@ moo_edit_init (MooEdit *edit)
|
||||||
|
|
||||||
edit->priv->actions = moo_action_collection_new ("MooEdit", "MooEdit");
|
edit->priv->actions = moo_action_collection_new ("MooEdit", "MooEdit");
|
||||||
|
|
||||||
indent = moo_indenter_new (edit, NULL);
|
indent = moo_indenter_new (edit);
|
||||||
moo_text_view_set_indenter (MOO_TEXT_VIEW (edit), indent);
|
moo_text_view_set_indenter (MOO_TEXT_VIEW (edit), indent);
|
||||||
g_object_unref (indent);
|
g_object_unref (indent);
|
||||||
}
|
}
|
||||||
|
@ -946,6 +946,13 @@ moo_edit_set_lang (MooEdit *edit,
|
||||||
_moo_lang_mgr_update_config (moo_editor_get_lang_mgr (edit->priv->editor),
|
_moo_lang_mgr_update_config (moo_editor_get_lang_mgr (edit->priv->editor),
|
||||||
edit->config, _moo_lang_id (lang));
|
edit->config, _moo_lang_id (lang));
|
||||||
_moo_edit_update_config_from_global (edit);
|
_moo_edit_update_config_from_global (edit);
|
||||||
|
|
||||||
|
{
|
||||||
|
MooIndenter *indenter = moo_text_view_get_indenter (MOO_TEXT_VIEW (edit));
|
||||||
|
if (indenter)
|
||||||
|
g_object_set (indenter, "id", lang ? _moo_lang_id (lang) : NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
g_object_notify (G_OBJECT (edit), "has-comments");
|
g_object_notify (G_OBJECT (edit), "has-comments");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1420,7 +1420,7 @@ handle_backspace (MooTextView *view,
|
||||||
if (gtk_text_iter_starts_line (&end))
|
if (gtk_text_iter_starts_line (&end))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
tab_width = view->priv->indenter->tab_width;
|
tab_width = moo_indenter_get_tab_width (view->priv->indenter);
|
||||||
offset = moo_iter_get_blank_offset (&end, tab_width);
|
offset = moo_iter_get_blank_offset (&end, tab_width);
|
||||||
|
|
||||||
if (offset < 0)
|
if (offset < 0)
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* mooindenter-settings.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004-2007 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* See COPYING file that comes with this distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MOOEDIT_COMPILATION
|
||||||
|
#error "This file may not be included"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MOO_INDENTER_SETTINGS_H
|
||||||
|
#define MOO_INDENTER_SETTINGS_H
|
||||||
|
|
||||||
|
#include "mooindenter.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __OBJC__
|
||||||
|
@class MooIndenterRegex;
|
||||||
|
#else
|
||||||
|
typedef struct MooIndenterRegex MooIndenterRegex;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
MooIndenterRegex *_moo_indenter_get_regex (const char *id_);
|
||||||
|
MooIndenterRegex *_moo_indenter_regex_ref (MooIndenterRegex *regex);
|
||||||
|
void _moo_indenter_regex_unref (MooIndenterRegex *regex);
|
||||||
|
gboolean _moo_indenter_regex_newline (MooIndenterRegex *regex,
|
||||||
|
MooIndenter *indenter,
|
||||||
|
GtkTextIter *where);
|
||||||
|
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* MOO_INDENTER_SETTINGS_H */
|
|
@ -0,0 +1,371 @@
|
||||||
|
/* -*- objc -*-
|
||||||
|
* mooindenter-settings.m
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004-2007 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* See COPYING file that comes with this distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MOOEDIT_COMPILATION
|
||||||
|
#include "mooedit/mooindenter-regex.h"
|
||||||
|
#include "mooutils/moocobject.h"
|
||||||
|
#include "mooutils/moomarkup.h"
|
||||||
|
#include "mooutils/mooutils-misc.h"
|
||||||
|
#include <glib/gregex.h>
|
||||||
|
|
||||||
|
|
||||||
|
static GHashTable *regex_hash;
|
||||||
|
|
||||||
|
|
||||||
|
@protocol MooIndenterElm
|
||||||
|
- (BOOL) newline: (MooIndenter*)indenter
|
||||||
|
text: (const char*)text
|
||||||
|
cursor: (GtkTextIter*)cursor
|
||||||
|
start: (GtkTextIter*)start
|
||||||
|
end: (GtkTextIter*)end;
|
||||||
|
@end
|
||||||
|
|
||||||
|
typedef MooCObject<MooIndenterElm> MooIndenterElm;
|
||||||
|
|
||||||
|
@interface MooIndenterShift : MooCObject <MooIndenterElm>
|
||||||
|
{
|
||||||
|
GRegex *re;
|
||||||
|
}
|
||||||
|
|
||||||
|
- init: (const char*)pattern;
|
||||||
|
@end;
|
||||||
|
|
||||||
|
@interface MooIndenterRegex : MooCObject
|
||||||
|
{
|
||||||
|
char *id_;
|
||||||
|
GRegex *re_all;
|
||||||
|
guint n_elms;
|
||||||
|
MooIndenterElm **elms;
|
||||||
|
}
|
||||||
|
|
||||||
|
- initWithMarkup: (MooMarkupNode*)node
|
||||||
|
lang_id: (const char*)lang_id
|
||||||
|
filename: (const char*)filename;
|
||||||
|
|
||||||
|
- (BOOL) newline: (MooIndenter*)indenter
|
||||||
|
where: (GtkTextIter*)where;
|
||||||
|
|
||||||
|
+ (void) loadSettings;
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
@implementation MooIndenterRegex
|
||||||
|
|
||||||
|
+ (void) loadSettings
|
||||||
|
{
|
||||||
|
char *filename = NULL;
|
||||||
|
MooMarkupDoc *doc;
|
||||||
|
MooMarkupNode *root, *node;
|
||||||
|
const char *version;
|
||||||
|
GError *error = NULL;
|
||||||
|
MooIndenterRegex *re;
|
||||||
|
|
||||||
|
if (regex_hash)
|
||||||
|
return;
|
||||||
|
|
||||||
|
regex_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
|
||||||
|
(GDestroyNotify) _moo_indenter_regex_unref);
|
||||||
|
|
||||||
|
filename = moo_get_data_file ("indent.xml");
|
||||||
|
|
||||||
|
if (!filename)
|
||||||
|
return;
|
||||||
|
|
||||||
|
doc = moo_markup_parse_file (filename, &error);
|
||||||
|
|
||||||
|
if (!doc)
|
||||||
|
{
|
||||||
|
g_warning ("%s: %s", G_STRLOC, error->message);
|
||||||
|
g_free (error);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(root = moo_markup_get_root_element (doc, "indent-settings")))
|
||||||
|
{
|
||||||
|
g_warning ("%s: 'indent-settings' element missing", G_STRLOC);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
version = moo_markup_get_prop (root, "version");
|
||||||
|
if (!version || strcmp (version, "1") != 0)
|
||||||
|
{
|
||||||
|
g_warning ("%s: invalid version '%s'", G_STRLOC,
|
||||||
|
version ? version : "(null)");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (node = root->children; node != NULL; node = node->next)
|
||||||
|
{
|
||||||
|
const char *lang_id;
|
||||||
|
|
||||||
|
if (!MOO_MARKUP_IS_ELEMENT (node))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (strcmp (node->name, "lang") != 0)
|
||||||
|
{
|
||||||
|
g_warning ("%s: invalid element '%s'", G_STRLOC, node->name);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
lang_id = moo_markup_get_prop (node, "id");
|
||||||
|
if (!lang_id)
|
||||||
|
{
|
||||||
|
g_warning ("%s: 'id' attribute missing in file '%s'", G_STRLOC, filename);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
re = [[self alloc] initWithMarkup:node lang_id:lang_id filename:filename];
|
||||||
|
|
||||||
|
if (!re)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
g_hash_table_insert (regex_hash, g_strdup (re->id_), re);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
g_free (filename);
|
||||||
|
if (doc)
|
||||||
|
moo_markup_doc_unref (doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- initWithMarkup: (MooMarkupNode*)elm
|
||||||
|
lang_id: (const char*)lang_id
|
||||||
|
filename: (const char*)filename
|
||||||
|
{
|
||||||
|
MooMarkupNode *node;
|
||||||
|
GSList *elements = NULL;
|
||||||
|
GString *pattern_all;
|
||||||
|
GError *error = NULL;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
[super init];
|
||||||
|
|
||||||
|
id_ = g_strdup (lang_id);
|
||||||
|
pattern_all = NULL;
|
||||||
|
|
||||||
|
for (node = elm->children; node != NULL; node = node->next)
|
||||||
|
{
|
||||||
|
if (!MOO_MARKUP_IS_ELEMENT (node))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!strcmp (node->name, "shift"))
|
||||||
|
{
|
||||||
|
const char *pattern = moo_markup_get_prop (node, "pattern");
|
||||||
|
MooIndenterElm *elm = [[MooIndenterShift alloc] init:pattern];
|
||||||
|
|
||||||
|
if (!elm)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
elements = g_slist_prepend (elements, elm);
|
||||||
|
if (!pattern_all)
|
||||||
|
{
|
||||||
|
pattern_all = g_string_new ("(");
|
||||||
|
g_string_append (pattern_all, pattern);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_string_append_printf (pattern_all, "|%s", pattern);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_warning ("in file %s: invalid element '%s' in lang '%s'",
|
||||||
|
filename, node->name, lang_id);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!elements)
|
||||||
|
{
|
||||||
|
g_warning ("in file %s: empty lang '%s' node",
|
||||||
|
filename, lang_id);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_string_append (pattern_all, ")");
|
||||||
|
re_all = g_regex_new (pattern_all->str, G_REGEX_DUPNAMES | G_REGEX_OPTIMIZE,
|
||||||
|
0, &error);
|
||||||
|
if (!re_all)
|
||||||
|
{
|
||||||
|
g_warning ("in file %s: could not compile resulting regex '%s': %s",
|
||||||
|
filename, pattern_all->str, error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
elements = g_slist_reverse (elements);
|
||||||
|
n_elms = g_slist_length (elements);
|
||||||
|
elms = g_new (MooIndenterElm*, n_elms);
|
||||||
|
for (i = 0; i < n_elms; ++i)
|
||||||
|
{
|
||||||
|
elms[i] = elements->data;
|
||||||
|
elements = g_slist_delete_link (elements, elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_string_free (pattern_all, TRUE);
|
||||||
|
return self;
|
||||||
|
|
||||||
|
error:
|
||||||
|
while (elements)
|
||||||
|
{
|
||||||
|
[(id) elements->data release];
|
||||||
|
elements = g_slist_delete_link (elements, elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_string_free (pattern_all, TRUE);
|
||||||
|
[self release];
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) dealloc
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
g_free (id_);
|
||||||
|
|
||||||
|
if (re_all)
|
||||||
|
g_regex_unref (re_all);
|
||||||
|
|
||||||
|
for (i = 0; i < n_elms; ++i)
|
||||||
|
[elms[i] release];
|
||||||
|
g_free (elms);
|
||||||
|
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (BOOL) newline: (MooIndenter*)indenter
|
||||||
|
where: (GtkTextIter*)where
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
GtkTextIter start, end;
|
||||||
|
char *text;
|
||||||
|
BOOL handled;
|
||||||
|
|
||||||
|
start = *where;
|
||||||
|
gtk_text_iter_backward_line (&start);
|
||||||
|
|
||||||
|
if (gtk_text_iter_ends_line (&start))
|
||||||
|
return NO;
|
||||||
|
|
||||||
|
end = start;
|
||||||
|
gtk_text_iter_forward_to_line_end (&end);
|
||||||
|
text = gtk_text_iter_get_slice (&start, &end);
|
||||||
|
|
||||||
|
if (!g_regex_match (re_all, text, 0, NULL))
|
||||||
|
{
|
||||||
|
g_free (text);
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0, handled = NO; !handled && i < n_elms; ++i)
|
||||||
|
handled = [elms[i] newline:indenter text:text
|
||||||
|
cursor:where start:&start end:&end];
|
||||||
|
|
||||||
|
g_free (text);
|
||||||
|
return handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
MooIndenterRegex *
|
||||||
|
_moo_indenter_regex_ref (MooIndenterRegex *regex)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (regex != nil, NULL);
|
||||||
|
return [regex retain];
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_moo_indenter_regex_unref (MooIndenterRegex *regex)
|
||||||
|
{
|
||||||
|
g_return_if_fail (regex != nil);
|
||||||
|
[regex release];
|
||||||
|
}
|
||||||
|
|
||||||
|
MooIndenterRegex *
|
||||||
|
_moo_indenter_get_regex (const char *id_)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (id_ != NULL, nil);
|
||||||
|
[MooIndenterRegex loadSettings];
|
||||||
|
return g_hash_table_lookup (regex_hash, id_);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_moo_indenter_regex_newline (MooIndenterRegex *regex,
|
||||||
|
MooIndenter *indenter,
|
||||||
|
GtkTextIter *where)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (regex != NULL, FALSE);
|
||||||
|
return [regex newline:indenter where:where];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@implementation MooIndenterShift
|
||||||
|
|
||||||
|
- init: (const char*)pattern
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
[super init];
|
||||||
|
|
||||||
|
re = g_regex_new (pattern, G_REGEX_DUPNAMES | G_REGEX_OPTIMIZE, 0, &error);
|
||||||
|
if (!re)
|
||||||
|
{
|
||||||
|
g_warning ("%s: %s", G_STRFUNC, error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
[self release];
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) dealloc
|
||||||
|
{
|
||||||
|
if (re)
|
||||||
|
g_regex_unref (re);
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL) newline: (MooIndenter*)indenter
|
||||||
|
text: (const char*)text
|
||||||
|
cursor: (GtkTextIter*)cursor
|
||||||
|
start: (GtkTextIter*)start
|
||||||
|
end: (GtkTextIter*)end
|
||||||
|
{
|
||||||
|
GtkTextIter iter;
|
||||||
|
guint offset;
|
||||||
|
char *insert;
|
||||||
|
MOO_UNUSED_VAR (end);
|
||||||
|
|
||||||
|
if (!g_regex_match (re, text, 0, NULL))
|
||||||
|
return NO;
|
||||||
|
|
||||||
|
iter = *start;
|
||||||
|
if (!_moo_indenter_compute_line_offset (indenter, &iter, &offset))
|
||||||
|
{
|
||||||
|
g_critical ("%s: oops", G_STRFUNC);
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset = _moo_indenter_compute_next_offset (indenter, offset);
|
||||||
|
insert = moo_indenter_make_space (indenter, offset, 0);
|
||||||
|
gtk_text_buffer_insert (gtk_text_iter_get_buffer (start), cursor, insert, -1);
|
||||||
|
g_free (insert);
|
||||||
|
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end;
|
|
@ -11,12 +11,26 @@
|
||||||
* See COPYING file that comes with this distribution.
|
* See COPYING file that comes with this distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define MOOEDIT_COMPILATION
|
||||||
|
#include <config.h>
|
||||||
#include "mooedit/mooindenter.h"
|
#include "mooedit/mooindenter.h"
|
||||||
|
#include "mooedit/mooindenter-regex.h"
|
||||||
#include "mooedit/mooedit.h"
|
#include "mooedit/mooedit.h"
|
||||||
#include "mooutils/moomarshals.h"
|
#include "mooutils/moomarshals.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct _MooIndenterPrivate {
|
||||||
|
char *id;
|
||||||
|
MooIndenterRegex *re;
|
||||||
|
gpointer doc; /* MooEdit* */
|
||||||
|
gboolean use_tabs;
|
||||||
|
gboolean strip;
|
||||||
|
guint tab_width;
|
||||||
|
guint indent;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* XXX this doesn't take unicode control chars into account */
|
/* XXX this doesn't take unicode control chars into account */
|
||||||
|
|
||||||
static GObject *moo_indenter_constructor (GType type,
|
static GObject *moo_indenter_constructor (GType type,
|
||||||
|
@ -32,6 +46,9 @@ static void moo_indenter_get_property (GObject *object,
|
||||||
GValue *value,
|
GValue *value,
|
||||||
GParamSpec *pspec);
|
GParamSpec *pspec);
|
||||||
|
|
||||||
|
static void moo_indenter_set_id (MooIndenter *indenter,
|
||||||
|
const char *id);
|
||||||
|
|
||||||
static void character_default (MooIndenter *indenter,
|
static void character_default (MooIndenter *indenter,
|
||||||
gunichar inserted_char,
|
gunichar inserted_char,
|
||||||
GtkTextIter *where);
|
GtkTextIter *where);
|
||||||
|
@ -58,6 +75,7 @@ enum {
|
||||||
PROP_USE_TABS,
|
PROP_USE_TABS,
|
||||||
PROP_STRIP,
|
PROP_STRIP,
|
||||||
PROP_INDENT,
|
PROP_INDENT,
|
||||||
|
PROP_ID,
|
||||||
PROP_DOC
|
PROP_DOC
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -126,6 +144,11 @@ moo_indenter_class_init (MooIndenterClass *klass)
|
||||||
1, G_MAXUINT, 8,
|
1, G_MAXUINT, 8,
|
||||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class, PROP_ID,
|
||||||
|
g_param_spec_string ("id", "id", "id",
|
||||||
|
NULL,
|
||||||
|
G_PARAM_READWRITE));
|
||||||
|
|
||||||
signals[CONFIG_CHANGED] =
|
signals[CONFIG_CHANGED] =
|
||||||
g_signal_new ("config-changed",
|
g_signal_new ("config-changed",
|
||||||
G_OBJECT_CLASS_TYPE (klass),
|
G_OBJECT_CLASS_TYPE (klass),
|
||||||
|
@ -146,12 +169,17 @@ moo_indenter_class_init (MooIndenterClass *klass)
|
||||||
G_TYPE_NONE, 1,
|
G_TYPE_NONE, 1,
|
||||||
G_TYPE_UINT,
|
G_TYPE_UINT,
|
||||||
GTK_TYPE_TEXT_ITER | G_SIGNAL_TYPE_STATIC_SCOPE);
|
GTK_TYPE_TEXT_ITER | G_SIGNAL_TYPE_STATIC_SCOPE);
|
||||||
|
|
||||||
|
g_type_class_add_private (gobject_class, sizeof (MooIndenterPrivate));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
moo_indenter_init (G_GNUC_UNUSED MooIndenter *indent)
|
moo_indenter_init (MooIndenter *indent)
|
||||||
{
|
{
|
||||||
|
indent->priv = G_TYPE_INSTANCE_GET_PRIVATE (indent,
|
||||||
|
MOO_TYPE_INDENTER,
|
||||||
|
MooIndenterPrivate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -166,7 +194,7 @@ moo_indenter_constructor (GType type,
|
||||||
object = G_OBJECT_CLASS(moo_indenter_parent_class)->constructor (type, n_props, props);
|
object = G_OBJECT_CLASS(moo_indenter_parent_class)->constructor (type, n_props, props);
|
||||||
indent = MOO_INDENTER (object);
|
indent = MOO_INDENTER (object);
|
||||||
|
|
||||||
if (indent->doc)
|
if (indent->priv->doc)
|
||||||
{
|
{
|
||||||
guint i;
|
guint i;
|
||||||
GParamSpec *pspec;
|
GParamSpec *pspec;
|
||||||
|
@ -179,7 +207,7 @@ moo_indenter_constructor (GType type,
|
||||||
g_return_val_if_fail (pspec != NULL, object);
|
g_return_val_if_fail (pspec != NULL, object);
|
||||||
config_notify (indent, id, pspec);
|
config_notify (indent, id, pspec);
|
||||||
|
|
||||||
g_signal_connect_swapped (indent->doc, "config-notify",
|
g_signal_connect_swapped (indent->priv->doc, "config-notify",
|
||||||
G_CALLBACK (config_notify),
|
G_CALLBACK (config_notify),
|
||||||
indent);
|
indent);
|
||||||
}
|
}
|
||||||
|
@ -193,11 +221,14 @@ moo_indenter_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
MooIndenter *indent = MOO_INDENTER (object);
|
MooIndenter *indent = MOO_INDENTER (object);
|
||||||
|
|
||||||
if (indent->doc)
|
if (indent->priv->doc)
|
||||||
g_signal_handlers_disconnect_by_func (indent->doc,
|
g_signal_handlers_disconnect_by_func (indent->priv->doc,
|
||||||
(gpointer) config_notify,
|
(gpointer) config_notify,
|
||||||
indent);
|
indent);
|
||||||
|
|
||||||
|
if (indent->priv->re)
|
||||||
|
_moo_indenter_regex_unref (indent->priv->re);
|
||||||
|
|
||||||
G_OBJECT_CLASS(moo_indenter_parent_class)->finalize (object);
|
G_OBJECT_CLASS(moo_indenter_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,30 +243,34 @@ static void moo_indenter_set_property (GObject *object,
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
case PROP_DOC:
|
case PROP_DOC:
|
||||||
indenter->doc = g_value_get_object (value);
|
indenter->priv->doc = g_value_get_object (value);
|
||||||
g_object_notify (object, "doc");
|
g_object_notify (object, "doc");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_TAB_WIDTH:
|
case PROP_TAB_WIDTH:
|
||||||
indenter->tab_width = g_value_get_uint (value);
|
indenter->priv->tab_width = g_value_get_uint (value);
|
||||||
g_object_notify (object, "tab-width");
|
g_object_notify (object, "tab-width");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_USE_TABS:
|
case PROP_USE_TABS:
|
||||||
indenter->use_tabs = g_value_get_boolean (value);
|
indenter->priv->use_tabs = g_value_get_boolean (value);
|
||||||
g_object_notify (object, "use-tabs");
|
g_object_notify (object, "use-tabs");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_STRIP:
|
case PROP_STRIP:
|
||||||
indenter->strip = g_value_get_boolean (value);
|
indenter->priv->strip = g_value_get_boolean (value);
|
||||||
g_object_notify (object, "strip");
|
g_object_notify (object, "strip");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_INDENT:
|
case PROP_INDENT:
|
||||||
indenter->indent = g_value_get_uint (value);
|
indenter->priv->indent = g_value_get_uint (value);
|
||||||
g_object_notify (object, "indent");
|
g_object_notify (object, "indent");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_ID:
|
||||||
|
moo_indenter_set_id (indenter, g_value_get_string (value));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -253,23 +288,27 @@ static void moo_indenter_get_property (GObject *object,
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
case PROP_DOC:
|
case PROP_DOC:
|
||||||
g_value_set_object (value, indenter->doc);
|
g_value_set_object (value, indenter->priv->doc);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_TAB_WIDTH:
|
case PROP_TAB_WIDTH:
|
||||||
g_value_set_uint (value, indenter->tab_width);
|
g_value_set_uint (value, indenter->priv->tab_width);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_USE_TABS:
|
case PROP_USE_TABS:
|
||||||
g_value_set_boolean (value, indenter->use_tabs);
|
g_value_set_boolean (value, indenter->priv->use_tabs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_STRIP:
|
case PROP_STRIP:
|
||||||
g_value_set_boolean (value, indenter->strip);
|
g_value_set_boolean (value, indenter->priv->strip);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_INDENT:
|
case PROP_INDENT:
|
||||||
g_value_set_uint (value, indenter->indent);
|
g_value_set_uint (value, indenter->priv->indent);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_ID:
|
||||||
|
g_value_set_string (value, indenter->priv->id);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -302,14 +341,68 @@ moo_indenter_character (MooIndenter *indenter,
|
||||||
|
|
||||||
|
|
||||||
MooIndenter*
|
MooIndenter*
|
||||||
moo_indenter_new (gpointer doc,
|
moo_indenter_new (gpointer doc)
|
||||||
G_GNUC_UNUSED const char *name)
|
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (!doc || MOO_IS_EDIT (doc), NULL);
|
g_return_val_if_fail (!doc || MOO_IS_EDIT (doc), NULL);
|
||||||
return g_object_new (MOO_TYPE_INDENTER, "doc", doc, NULL);
|
return g_object_new (MOO_TYPE_INDENTER, "doc", doc, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
guint
|
||||||
|
moo_indenter_get_tab_width (MooIndenter *indenter)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (MOO_IS_INDENTER (indenter), 8);
|
||||||
|
return indenter->priv->tab_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef MOO_USE_OBJC
|
||||||
|
MooIndenterRegex *
|
||||||
|
_moo_indenter_get_regex (G_GNUC_UNUSED const char *id)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
MooIndenterRegex *
|
||||||
|
_moo_indenter_regex_ref (G_GNUC_UNUSED MooIndenterRegex *regex)
|
||||||
|
{
|
||||||
|
g_return_val_if_reached (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_moo_indenter_regex_unref (G_GNUC_UNUSED MooIndenterRegex *regex)
|
||||||
|
{
|
||||||
|
g_return_if_reached ();
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_moo_indenter_regex_newline (G_GNUC_UNUSED MooIndenterRegex *regex,
|
||||||
|
G_GNUC_UNUSED GtkTextBuffer *buffer,
|
||||||
|
G_GNUC_UNUSED GtkTextIter *where)
|
||||||
|
{
|
||||||
|
g_return_val_if_reached (FALSE);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
moo_indenter_set_id (MooIndenter *indenter,
|
||||||
|
const char *id)
|
||||||
|
{
|
||||||
|
if (!strcmp (indenter->priv->id ? indenter->priv->id : "", id ? id : ""))
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_free (indenter->priv->id);
|
||||||
|
indenter->priv->id = g_strdup (id);
|
||||||
|
|
||||||
|
if (indenter->priv->re)
|
||||||
|
_moo_indenter_regex_unref (indenter->priv->re);
|
||||||
|
indenter->priv->re = _moo_indenter_get_regex (id);
|
||||||
|
if (indenter->priv->re)
|
||||||
|
_moo_indenter_regex_ref (indenter->priv->re);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Default implementation
|
/* Default implementation
|
||||||
*/
|
*/
|
||||||
|
@ -320,7 +413,7 @@ moo_indenter_make_space (MooIndenter *indenter,
|
||||||
guint start)
|
guint start)
|
||||||
{
|
{
|
||||||
guint tabs, spaces, delta;
|
guint tabs, spaces, delta;
|
||||||
guint tab_width = indenter->tab_width;
|
guint tab_width = indenter->priv->tab_width;
|
||||||
char *string;
|
char *string;
|
||||||
|
|
||||||
g_return_val_if_fail (MOO_IS_INDENTER (indenter), NULL);
|
g_return_val_if_fail (MOO_IS_INDENTER (indenter), NULL);
|
||||||
|
@ -328,7 +421,7 @@ moo_indenter_make_space (MooIndenter *indenter,
|
||||||
if (!len)
|
if (!len)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!indenter->use_tabs)
|
if (!indenter->priv->use_tabs)
|
||||||
return g_strnfill (len, ' ');
|
return g_strnfill (len, ' ');
|
||||||
|
|
||||||
delta = start % tab_width;
|
delta = start % tab_width;
|
||||||
|
@ -407,6 +500,17 @@ compute_line_offset (GtkTextIter *dest,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_moo_indenter_compute_line_offset (MooIndenter *indenter,
|
||||||
|
GtkTextIter *dest,
|
||||||
|
guint *offsetp)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (MOO_IS_INDENTER (indenter), FALSE);
|
||||||
|
g_return_val_if_fail (dest != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (offsetp != NULL, FALSE);
|
||||||
|
return compute_line_offset (dest, indenter->priv->tab_width, offsetp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
character_default (MooIndenter *indenter,
|
character_default (MooIndenter *indenter,
|
||||||
|
@ -422,9 +526,14 @@ character_default (MooIndenter *indenter,
|
||||||
if (inserted_char != '\n')
|
if (inserted_char != '\n')
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (indenter->priv->re &&
|
||||||
|
_moo_indenter_regex_newline (indenter->priv->re,
|
||||||
|
indenter, where))
|
||||||
|
return;
|
||||||
|
|
||||||
iter = *where;
|
iter = *where;
|
||||||
gtk_text_iter_backward_line (&iter);
|
gtk_text_iter_backward_line (&iter);
|
||||||
ws_line = !compute_line_offset (&iter, indenter->tab_width, &offset);
|
ws_line = !compute_line_offset (&iter, indenter->priv->tab_width, &offset);
|
||||||
|
|
||||||
if (!offset)
|
if (!offset)
|
||||||
return;
|
return;
|
||||||
|
@ -436,22 +545,22 @@ character_default (MooIndenter *indenter,
|
||||||
g_free (indent_string);
|
g_free (indent_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ws_line && indenter->strip)
|
// if (ws_line && indenter->priv->strip)
|
||||||
{
|
// {
|
||||||
GtkTextMark *saved_location;
|
// GtkTextMark *saved_location;
|
||||||
GtkTextIter iter2;
|
// GtkTextIter iter2;
|
||||||
|
//
|
||||||
saved_location = gtk_text_buffer_create_mark (buffer, NULL, where, FALSE);
|
// saved_location = gtk_text_buffer_create_mark (buffer, NULL, where, FALSE);
|
||||||
|
//
|
||||||
iter = *where;
|
// iter = *where;
|
||||||
gtk_text_iter_backward_line (&iter);
|
// gtk_text_iter_backward_line (&iter);
|
||||||
iter2 = iter;
|
// iter2 = iter;
|
||||||
gtk_text_iter_forward_to_line_end (&iter2);
|
// gtk_text_iter_forward_to_line_end (&iter2);
|
||||||
gtk_text_buffer_delete (buffer, &iter, &iter2);
|
// gtk_text_buffer_delete (buffer, &iter, &iter2);
|
||||||
|
//
|
||||||
gtk_text_buffer_get_iter_at_mark (buffer, where, saved_location);
|
// gtk_text_buffer_get_iter_at_mark (buffer, where, saved_location);
|
||||||
gtk_text_buffer_delete_mark (buffer, saved_location);
|
// gtk_text_buffer_delete_mark (buffer, saved_location);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -592,14 +701,21 @@ iter_get_visual_offset (GtkTextIter *iter,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static guint
|
||||||
|
get_next_offset (guint offset,
|
||||||
|
guint indent)
|
||||||
|
{
|
||||||
|
return offset + (indent - offset % indent);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
moo_indenter_tab (MooIndenter *indenter,
|
moo_indenter_tab (MooIndenter *indenter,
|
||||||
GtkTextBuffer *buffer)
|
GtkTextBuffer *buffer)
|
||||||
{
|
{
|
||||||
GtkTextIter insert, start;
|
GtkTextIter insert, start;
|
||||||
int offset, new_offset, white_space;
|
int offset, new_offset, white_space;
|
||||||
guint tab_width = indenter->tab_width;
|
guint tab_width = indenter->priv->tab_width;
|
||||||
guint indent = indenter->indent;
|
guint indent = indenter->priv->indent;
|
||||||
char *text = NULL;
|
char *text = NULL;
|
||||||
|
|
||||||
gtk_text_buffer_get_iter_at_mark (buffer, &insert, gtk_text_buffer_get_insert (buffer));
|
gtk_text_buffer_get_iter_at_mark (buffer, &insert, gtk_text_buffer_get_insert (buffer));
|
||||||
|
@ -607,7 +723,7 @@ moo_indenter_tab (MooIndenter *indenter,
|
||||||
start = insert;
|
start = insert;
|
||||||
iter_get_visual_offset (&start, tab_width, &offset, &white_space);
|
iter_get_visual_offset (&start, tab_width, &offset, &white_space);
|
||||||
|
|
||||||
new_offset = offset + (indent - offset % indent);
|
new_offset = get_next_offset (offset, indent);
|
||||||
text = moo_indenter_make_space (indenter,
|
text = moo_indenter_make_space (indenter,
|
||||||
new_offset - offset + white_space,
|
new_offset - offset + white_space,
|
||||||
offset - white_space);
|
offset - white_space);
|
||||||
|
@ -618,6 +734,14 @@ moo_indenter_tab (MooIndenter *indenter,
|
||||||
g_free (text);
|
g_free (text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
guint
|
||||||
|
_moo_indenter_compute_next_offset (MooIndenter *indenter,
|
||||||
|
guint offset)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (MOO_IS_INDENTER (indenter), offset);
|
||||||
|
return get_next_offset (offset, indenter->priv->indent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
shift_line_forward (MooIndenter *indenter,
|
shift_line_forward (MooIndenter *indenter,
|
||||||
|
@ -628,7 +752,7 @@ shift_line_forward (MooIndenter *indenter,
|
||||||
guint offset;
|
guint offset;
|
||||||
GtkTextIter start;
|
GtkTextIter start;
|
||||||
|
|
||||||
if (!compute_line_offset (iter, indenter->tab_width, &offset))
|
if (!compute_line_offset (iter, indenter->priv->tab_width, &offset))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (offset)
|
if (offset)
|
||||||
|
@ -638,7 +762,7 @@ shift_line_forward (MooIndenter *indenter,
|
||||||
gtk_text_buffer_delete (buffer, &start, iter);
|
gtk_text_buffer_delete (buffer, &start, iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
text = moo_indenter_make_space (indenter, offset + indenter->indent, 0);
|
text = moo_indenter_make_space (indenter, offset + indenter->priv->indent, 0);
|
||||||
|
|
||||||
if (text)
|
if (text)
|
||||||
gtk_text_buffer_insert (buffer, iter, text, -1);
|
gtk_text_buffer_insert (buffer, iter, text, -1);
|
||||||
|
@ -675,20 +799,20 @@ shift_line_backward (MooIndenter *indenter,
|
||||||
else if (c == '\t')
|
else if (c == '\t')
|
||||||
{
|
{
|
||||||
gtk_text_iter_forward_char (&end);
|
gtk_text_iter_forward_char (&end);
|
||||||
deleted += indenter->tab_width;
|
deleted += indenter->priv->tab_width;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deleted >= (int) indenter->indent)
|
if (deleted >= (int) indenter->priv->indent)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_text_buffer_delete (buffer, iter, &end);
|
gtk_text_buffer_delete (buffer, iter, &end);
|
||||||
|
|
||||||
deleted -= indenter->indent;
|
deleted -= indenter->priv->indent;
|
||||||
|
|
||||||
if (deleted > 0)
|
if (deleted > 0)
|
||||||
{
|
{
|
||||||
|
@ -725,7 +849,7 @@ config_changed_default (MooIndenter *indenter,
|
||||||
guint var_id,
|
guint var_id,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
MooEdit *doc = indenter->doc;
|
MooEdit *doc = indenter->priv->doc;
|
||||||
|
|
||||||
g_return_if_fail (MOO_IS_EDIT (doc));
|
g_return_if_fail (MOO_IS_EDIT (doc));
|
||||||
|
|
||||||
|
|
|
@ -28,17 +28,13 @@ G_BEGIN_DECLS
|
||||||
|
|
||||||
|
|
||||||
typedef struct _MooIndenter MooIndenter;
|
typedef struct _MooIndenter MooIndenter;
|
||||||
|
typedef struct _MooIndenterPrivate MooIndenterPrivate;
|
||||||
typedef struct _MooIndenterClass MooIndenterClass;
|
typedef struct _MooIndenterClass MooIndenterClass;
|
||||||
|
|
||||||
struct _MooIndenter
|
struct _MooIndenter
|
||||||
{
|
{
|
||||||
GObject parent;
|
GObject parent;
|
||||||
|
MooIndenterPrivate *priv;
|
||||||
gpointer doc; /* MooEdit* */
|
|
||||||
gboolean use_tabs;
|
|
||||||
gboolean strip;
|
|
||||||
guint tab_width;
|
|
||||||
guint indent;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _MooIndenterClass
|
struct _MooIndenterClass
|
||||||
|
@ -56,8 +52,9 @@ struct _MooIndenterClass
|
||||||
|
|
||||||
GType moo_indenter_get_type (void) G_GNUC_CONST;
|
GType moo_indenter_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
MooIndenter *moo_indenter_new (gpointer doc,
|
MooIndenter *moo_indenter_new (gpointer doc);
|
||||||
const char *name);
|
|
||||||
|
guint moo_indenter_get_tab_width (MooIndenter *indenter);
|
||||||
|
|
||||||
char *moo_indenter_make_space (MooIndenter *indenter,
|
char *moo_indenter_make_space (MooIndenter *indenter,
|
||||||
guint len,
|
guint len,
|
||||||
|
@ -91,6 +88,12 @@ guint moo_text_iter_get_prev_stop (const GtkTextIter *start,
|
||||||
guint offset,
|
guint offset,
|
||||||
gboolean same_line);
|
gboolean same_line);
|
||||||
|
|
||||||
|
gboolean _moo_indenter_compute_line_offset (MooIndenter *indenter,
|
||||||
|
GtkTextIter *dest,
|
||||||
|
guint *offsetp);
|
||||||
|
guint _moo_indenter_compute_next_offset (MooIndenter *indenter,
|
||||||
|
guint offset);
|
||||||
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -574,7 +574,6 @@
|
||||||
(return-type "MooIndenter*")
|
(return-type "MooIndenter*")
|
||||||
(parameters
|
(parameters
|
||||||
'("MooEdit*" "doc")
|
'("MooEdit*" "doc")
|
||||||
'("const-char*" "name")
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1405,6 +1405,25 @@ moo_get_data_subdirs (const char *subdir,
|
||||||
return dirs;
|
return dirs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
moo_get_data_file (const char *name)
|
||||||
|
{
|
||||||
|
guint n_files, i;
|
||||||
|
char **files;
|
||||||
|
char *filename = NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail (name != NULL, NULL);
|
||||||
|
|
||||||
|
files = moo_get_data_files (name, MOO_DATA_SHARE, &n_files);
|
||||||
|
|
||||||
|
for (i = 0; !filename && i < n_files; ++i)
|
||||||
|
if (g_file_test (files[i], G_FILE_TEST_EXISTS))
|
||||||
|
filename = g_strdup (files[i]);
|
||||||
|
|
||||||
|
g_strfreev (files);
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
get_user_data_file (const char *basename,
|
get_user_data_file (const char *basename,
|
||||||
|
|
|
@ -82,6 +82,8 @@ char **moo_get_data_subdirs (const char *subdir,
|
||||||
guint *n_dirs);
|
guint *n_dirs);
|
||||||
#define moo_get_data_files moo_get_data_subdirs
|
#define moo_get_data_files moo_get_data_subdirs
|
||||||
|
|
||||||
|
char *moo_get_data_file (const char *name);
|
||||||
|
|
||||||
const char *moo_get_locale_dir (void);
|
const char *moo_get_locale_dir (void);
|
||||||
const char *const *_moo_get_shared_data_dirs (void);
|
const char *const *_moo_get_shared_data_dirs (void);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue