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,
|
void _moo_text_buffer_highlighting_changed (MooTextBuffer *buffer,
|
||||||
int first,
|
int first,
|
||||||
int last);
|
int last);
|
||||||
|
gboolean _moo_text_buffer_has_placeholders (MooTextBuffer *buffer);
|
||||||
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "mooedit/mootextiter.h"
|
#include "mooedit/mootextiter.h"
|
||||||
#include "mooedit/moohighlighter.h"
|
#include "mooedit/moohighlighter.h"
|
||||||
#include "mooedit/mootext-private.h"
|
#include "mooedit/mootext-private.h"
|
||||||
|
#include "mooedit/mootexttag.h"
|
||||||
#include "mooutils/moomarshals.h"
|
#include "mooutils/moomarshals.h"
|
||||||
#include "mooutils/mooundomanager.h"
|
#include "mooutils/mooundomanager.h"
|
||||||
#include "mooutils/mooutils-gobject.h"
|
#include "mooutils/mooutils-gobject.h"
|
||||||
|
@ -30,6 +31,7 @@ struct _MooTextBufferPrivate {
|
||||||
MooLang *lang;
|
MooLang *lang;
|
||||||
gboolean may_apply_tag;
|
gboolean may_apply_tag;
|
||||||
gboolean do_highlight;
|
gboolean do_highlight;
|
||||||
|
gboolean has_placeholders;
|
||||||
|
|
||||||
gboolean highlight_matching_brackets;
|
gboolean highlight_matching_brackets;
|
||||||
gboolean highlight_mismatching_brackets;
|
gboolean highlight_mismatching_brackets;
|
||||||
|
@ -474,7 +476,7 @@ moo_text_buffer_mark_set (GtkTextBuffer *text_buffer,
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
moo_text_buffer_insert_text (GtkTextBuffer *text_buffer,
|
moo_text_buffer_insert_text_real (GtkTextBuffer *text_buffer,
|
||||||
GtkTextIter *pos,
|
GtkTextIter *pos,
|
||||||
const gchar *text,
|
const gchar *text,
|
||||||
gint length)
|
gint length)
|
||||||
|
@ -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
|
static void
|
||||||
marks_moved_or_deleted (MooTextBuffer *buffer,
|
marks_moved_or_deleted (MooTextBuffer *buffer,
|
||||||
GSList *moved,
|
GSList *moved,
|
||||||
|
@ -913,7 +1016,8 @@ moo_text_buffer_apply_tag (GtkTextBuffer *buffer,
|
||||||
const GtkTextIter *start,
|
const GtkTextIter *start,
|
||||||
const GtkTextIter *end)
|
const GtkTextIter *end)
|
||||||
{
|
{
|
||||||
if (MOO_IS_SYNTAX_TAG (tag) && !MOO_TEXT_BUFFER(buffer)->priv->may_apply_tag)
|
if (!MOO_TEXT_BUFFER(buffer)->priv->may_apply_tag)
|
||||||
|
if (MOO_IS_SYNTAX_TAG (tag) || MOO_IS_TEXT_TAG (tag))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GTK_TEXT_BUFFER_CLASS(moo_text_buffer_parent_class)->apply_tag (buffer, tag, start, end);
|
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 0xFFFC
|
||||||
#define MOO_TEXT_UNKNOWN_CHAR_S "\xEF\xBF\xBC"
|
#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_START "moo-placeholder-start"
|
||||||
#define MOO_PLACEHOLDER_END "moo-placeholder-end"
|
#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*
|
static GObject*
|
||||||
moo_text_view_constructor (GType type,
|
moo_text_view_constructor (GType type,
|
||||||
guint n_construct_properties,
|
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);
|
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;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4054,61 +4074,21 @@ start_quick_search (MooTextView *view)
|
||||||
/* Placeholders
|
/* 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
|
void
|
||||||
moo_text_view_insert_placeholder (MooTextView *view,
|
moo_text_view_insert_placeholder (MooTextView *view,
|
||||||
GtkTextIter *iter)
|
GtkTextIter *iter)
|
||||||
{
|
{
|
||||||
GtkTextBuffer *buffer;
|
|
||||||
|
|
||||||
g_return_if_fail (MOO_IS_TEXT_VIEW (view));
|
g_return_if_fail (MOO_IS_TEXT_VIEW (view));
|
||||||
g_return_if_fail (iter != NULL);
|
g_return_if_fail (iter != NULL);
|
||||||
|
gtk_text_buffer_insert (get_buffer (view), iter,
|
||||||
buffer = get_buffer (view);
|
MOO_PLACEHOLDER_STRING, -1);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
_moo_text_view_has_placeholders (MooTextView *view)
|
_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