Don't abort on copy/paste; still broken
parent
e2a5772998
commit
7f0d50c345
|
@ -56,6 +56,7 @@ void _moo_text_buffer_apply_syntax_tag (MooTextBuffer *buffer,
|
|||
void _moo_text_buffer_highlighting_changed (MooTextBuffer *buffer,
|
||||
int first,
|
||||
int last);
|
||||
gboolean _moo_text_buffer_has_placeholders (MooTextBuffer *buffer);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "mooedit/mootextiter.h"
|
||||
#include "mooedit/moohighlighter.h"
|
||||
#include "mooedit/mootext-private.h"
|
||||
#include "mooedit/mootexttag.h"
|
||||
#include "mooutils/moomarshals.h"
|
||||
#include "mooutils/mooundomanager.h"
|
||||
#include "mooutils/mooutils-gobject.h"
|
||||
|
@ -30,6 +31,7 @@ struct _MooTextBufferPrivate {
|
|||
MooLang *lang;
|
||||
gboolean may_apply_tag;
|
||||
gboolean do_highlight;
|
||||
gboolean has_placeholders;
|
||||
|
||||
gboolean highlight_matching_brackets;
|
||||
gboolean highlight_mismatching_brackets;
|
||||
|
@ -474,10 +476,10 @@ moo_text_buffer_mark_set (GtkTextBuffer *text_buffer,
|
|||
|
||||
|
||||
static void
|
||||
moo_text_buffer_insert_text (GtkTextBuffer *text_buffer,
|
||||
GtkTextIter *pos,
|
||||
const gchar *text,
|
||||
gint length)
|
||||
moo_text_buffer_insert_text_real (GtkTextBuffer *text_buffer,
|
||||
GtkTextIter *pos,
|
||||
const gchar *text,
|
||||
gint length)
|
||||
{
|
||||
MooTextBuffer *buffer = MOO_TEXT_BUFFER (text_buffer);
|
||||
GtkTextTag *tag;
|
||||
|
@ -536,6 +538,107 @@ moo_text_buffer_insert_text (GtkTextBuffer *text_buffer,
|
|||
}
|
||||
|
||||
|
||||
static const char *
|
||||
find_placeholder (const char *string,
|
||||
const char *end)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
if (string >= end)
|
||||
return NULL;
|
||||
|
||||
if (end - string < 6)
|
||||
return NULL;
|
||||
|
||||
for (p = string; p <= end - 6; ++p)
|
||||
if (!strncmp (p, MOO_PLACEHOLDER_STRING, 6))
|
||||
return p;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
moo_text_buffer_insert_text (GtkTextBuffer *text_buffer,
|
||||
GtkTextIter *pos,
|
||||
const gchar *text,
|
||||
gint length)
|
||||
{
|
||||
int pos_offset = 0;
|
||||
const char *ph, *ptr, *end;
|
||||
GArray *placeholders = NULL;
|
||||
|
||||
if (length < 0)
|
||||
length = strlen (text);
|
||||
|
||||
if (!length)
|
||||
return;
|
||||
|
||||
ptr = text;
|
||||
end = ptr + length;
|
||||
|
||||
while ((ph = find_placeholder (ptr, end)))
|
||||
{
|
||||
long offset;
|
||||
|
||||
if (!placeholders)
|
||||
placeholders = g_array_new (FALSE, FALSE, sizeof (long));
|
||||
|
||||
offset = g_utf8_pointer_to_offset (ptr, ph);
|
||||
g_array_append_val (placeholders, offset);
|
||||
|
||||
ptr = g_utf8_offset_to_pointer (ph, 2);
|
||||
}
|
||||
|
||||
if (placeholders)
|
||||
pos_offset = gtk_text_iter_get_offset (pos);
|
||||
|
||||
moo_text_buffer_insert_text_real (text_buffer, pos, text, length);
|
||||
|
||||
if (placeholders)
|
||||
{
|
||||
guint i;
|
||||
GtkTextIter start, end;
|
||||
|
||||
gtk_text_buffer_get_iter_at_offset (text_buffer, &start, pos_offset);
|
||||
|
||||
MOO_TEXT_BUFFER(text_buffer)->priv->has_placeholders = TRUE;
|
||||
MOO_TEXT_BUFFER(text_buffer)->priv->may_apply_tag = TRUE;
|
||||
|
||||
for (i = 0; i < placeholders->len; ++i)
|
||||
{
|
||||
long offset = g_array_index (placeholders, long, i);
|
||||
|
||||
gtk_text_iter_forward_chars (&start, offset);
|
||||
end = start;
|
||||
gtk_text_iter_forward_chars (&end, 1);
|
||||
|
||||
gtk_text_buffer_apply_tag_by_name (text_buffer,
|
||||
MOO_PLACEHOLDER_START,
|
||||
&start, &end);
|
||||
|
||||
start = end;
|
||||
gtk_text_iter_forward_chars (&start, 1);
|
||||
|
||||
gtk_text_buffer_apply_tag_by_name (text_buffer,
|
||||
MOO_PLACEHOLDER_END,
|
||||
&end, &start);
|
||||
}
|
||||
|
||||
MOO_TEXT_BUFFER(text_buffer)->priv->may_apply_tag = FALSE;
|
||||
|
||||
g_array_free (placeholders, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
_moo_text_buffer_has_placeholders (MooTextBuffer *buffer)
|
||||
{
|
||||
return buffer->priv->has_placeholders;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
marks_moved_or_deleted (MooTextBuffer *buffer,
|
||||
GSList *moved,
|
||||
|
@ -913,8 +1016,9 @@ moo_text_buffer_apply_tag (GtkTextBuffer *buffer,
|
|||
const GtkTextIter *start,
|
||||
const GtkTextIter *end)
|
||||
{
|
||||
if (MOO_IS_SYNTAX_TAG (tag) && !MOO_TEXT_BUFFER(buffer)->priv->may_apply_tag)
|
||||
return;
|
||||
if (!MOO_TEXT_BUFFER(buffer)->priv->may_apply_tag)
|
||||
if (MOO_IS_SYNTAX_TAG (tag) || MOO_IS_TEXT_TAG (tag))
|
||||
return;
|
||||
|
||||
GTK_TEXT_BUFFER_CLASS(moo_text_buffer_parent_class)->apply_tag (buffer, tag, start, end);
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ G_BEGIN_DECLS
|
|||
|
||||
#define MOO_TEXT_UNKNOWN_CHAR 0xFFFC
|
||||
#define MOO_TEXT_UNKNOWN_CHAR_S "\xEF\xBF\xBC"
|
||||
#define MOO_PLACEHOLDER_STRING MOO_TEXT_UNKNOWN_CHAR_S MOO_TEXT_UNKNOWN_CHAR_S
|
||||
|
||||
#define MOO_PLACEHOLDER_START "moo-placeholder-start"
|
||||
#define MOO_PLACEHOLDER_END "moo-placeholder-end"
|
||||
|
|
|
@ -628,6 +628,23 @@ static void moo_text_view_init (MooTextView *view)
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
add_tag (MooTextView *view,
|
||||
MooTextTagType type,
|
||||
const char *name)
|
||||
{
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextTag *tag;
|
||||
GtkTextTagTable *table;
|
||||
|
||||
buffer = get_buffer (view);
|
||||
tag = _moo_text_tag_new (type, name);
|
||||
table = gtk_text_buffer_get_tag_table (buffer);
|
||||
gtk_text_tag_table_add (table, tag);
|
||||
g_object_unref (tag);
|
||||
}
|
||||
|
||||
|
||||
static GObject*
|
||||
moo_text_view_constructor (GType type,
|
||||
guint n_construct_properties,
|
||||
|
@ -690,6 +707,9 @@ moo_text_view_constructor (GType type,
|
|||
|
||||
g_signal_connect (view, "notify::overwrite", G_CALLBACK (overwrite_changed), NULL);
|
||||
|
||||
add_tag (view, MOO_TEXT_TAG_PLACEHOLDER_START, MOO_PLACEHOLDER_START);
|
||||
add_tag (view, MOO_TEXT_TAG_PLACEHOLDER_END, MOO_PLACEHOLDER_END);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
|
@ -4054,61 +4074,21 @@ start_quick_search (MooTextView *view)
|
|||
/* Placeholders
|
||||
*/
|
||||
|
||||
static void
|
||||
add_tag (MooTextView *view,
|
||||
MooTextTagType type,
|
||||
const char *name)
|
||||
{
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextTag *tag;
|
||||
GtkTextTagTable *table;
|
||||
|
||||
buffer = get_buffer (view);
|
||||
tag = _moo_text_tag_new (type, name);
|
||||
table = gtk_text_buffer_get_tag_table (buffer);
|
||||
gtk_text_tag_table_add (table, tag);
|
||||
|
||||
if (GTK_WIDGET (view)->style)
|
||||
g_object_set (tag, "foreground-gdk",
|
||||
>K_WIDGET(view)->style->base[GTK_STATE_NORMAL],
|
||||
NULL);
|
||||
|
||||
g_object_unref (tag);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
moo_text_view_insert_placeholder (MooTextView *view,
|
||||
GtkTextIter *iter)
|
||||
{
|
||||
GtkTextBuffer *buffer;
|
||||
|
||||
g_return_if_fail (MOO_IS_TEXT_VIEW (view));
|
||||
g_return_if_fail (iter != NULL);
|
||||
|
||||
buffer = get_buffer (view);
|
||||
|
||||
if (!moo_text_view_lookup_tag (view, MOO_PLACEHOLDER_START))
|
||||
{
|
||||
add_tag (view, MOO_TEXT_TAG_PLACEHOLDER_START, MOO_PLACEHOLDER_START);
|
||||
add_tag (view, MOO_TEXT_TAG_PLACEHOLDER_END, MOO_PLACEHOLDER_END);
|
||||
}
|
||||
|
||||
gtk_text_buffer_insert_with_tags_by_name (buffer, iter,
|
||||
MOO_TEXT_UNKNOWN_CHAR_S,
|
||||
-1, MOO_PLACEHOLDER_START,
|
||||
NULL);
|
||||
gtk_text_buffer_insert_with_tags_by_name (buffer, iter,
|
||||
MOO_TEXT_UNKNOWN_CHAR_S,
|
||||
-1, MOO_PLACEHOLDER_END,
|
||||
NULL);
|
||||
gtk_text_buffer_insert (get_buffer (view), iter,
|
||||
MOO_PLACEHOLDER_STRING, -1);
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
_moo_text_view_has_placeholders (MooTextView *view)
|
||||
{
|
||||
return moo_text_view_lookup_tag (view, MOO_PLACEHOLDER_START) != NULL;
|
||||
return _moo_text_buffer_has_placeholders (get_moo_buffer (view));
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue