[gnome-builder/wip/libide] libide: add IdeSourceView::paste-clipboard-extended
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/libide] libide: add IdeSourceView::paste-clipboard-extended
- Date: Thu, 5 Mar 2015 22:32:40 +0000 (UTC)
commit ef4f8c11baa92f5b93bb533d58745413f9ce7366
Author: Christian Hergert <christian hergert me>
Date: Thu Mar 5 14:32:14 2015 -0800
libide: add IdeSourceView::paste-clipboard-extended
This gasctionsignal allows us a bit more control over how the paste will
be interprited. For example, we can allow/disallow smart pasting of lines
(lines with trailing \n such as those from `yy` in vim mode).
It also allows us to specifiy if they should happen before or after
the current cursor.
If place_cursor_at_original is FALSE, then we will move the insertion
cursor to the beginning of the pasted text (which may be on a different
line if smart_lines is TRUE).
libide/ide-source-view.c | 89 +++++++++++++++++++++++++++++++++++-----------
libide/ide-source-view.h | 4 ++
2 files changed, 72 insertions(+), 21 deletions(-)
---
diff --git a/libide/ide-source-view.c b/libide/ide-source-view.c
index de35dbf..b8edb0f 100644
--- a/libide/ide-source-view.c
+++ b/libide/ide-source-view.c
@@ -115,6 +115,7 @@ enum {
JOIN_LINES,
JUMP,
MOVEMENT,
+ PASTE_CLIPBOARD_EXTENDED,
PUSH_SNIPPET,
POP_SNIPPET,
RESTORE_INSERT_MARK,
@@ -1747,12 +1748,20 @@ ide_source_view_real_jump (IdeSourceView *self,
}
static void
-ide_source_view_real_paste_clipboard (GtkTextView *text_view)
+ide_source_view_real_paste_clipboard_extended (IdeSourceView *self,
+ gboolean smart_lines,
+ gboolean after_cursor,
+ gboolean place_cursor_at_original)
+
{
- IdeSourceView *self = (IdeSourceView *)text_view;
+ GtkTextView *text_view = (GtkTextView *)self;
g_autofree gchar *text = NULL;
GtkClipboard *clipboard;
GtkTextBuffer *buffer;
+ GtkTextMark *insert;
+ GtkTextIter iter;
+ guint target_line;
+ guint target_line_offset;
/*
* NOTE:
@@ -1766,13 +1775,19 @@ ide_source_view_real_paste_clipboard (GtkTextView *text_view)
* is handled within vim.css (for example, what character to leave the insert mark on).
*/
+ g_assert (GTK_IS_TEXT_VIEW (text_view));
g_assert (IDE_IS_SOURCE_VIEW (self));
buffer = gtk_text_view_get_buffer (text_view);
+ insert = gtk_text_buffer_get_insert (buffer);
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (self), GDK_SELECTION_CLIPBOARD);
text = gtk_clipboard_wait_for_text (clipboard);
+ gtk_text_buffer_get_iter_at_mark (buffer, &iter, insert);
+ target_line = gtk_text_iter_get_line (&iter);
+ target_line_offset = gtk_text_iter_get_line_offset (&iter);
+
gtk_text_buffer_begin_user_action (buffer);
/*
@@ -1780,7 +1795,7 @@ ide_source_view_real_paste_clipboard (GtkTextView *text_view)
* to insert a new line after the current line, and then paste it there (so move the insert mark
* first).
*/
- if (text && g_str_has_suffix (text, "\n"))
+ if (smart_lines && text && g_str_has_suffix (text, "\n"))
{
g_autofree gchar *trimmed = NULL;
@@ -1796,30 +1811,51 @@ ide_source_view_real_paste_clipboard (GtkTextView *text_view)
* Terribly annoying, but the result is something that feels very nice, similar to Vim.
*/
trimmed = g_strndup (text, strlen (text) - 1);
- _ide_source_view_apply_movement (self, IDE_SOURCE_VIEW_MOVEMENT_LAST_CHAR, FALSE, 0);
- g_signal_emit_by_name (self, "insert-at-cursor", "\n");
+
+ if (after_cursor)
+ {
+ _ide_source_view_apply_movement (self, IDE_SOURCE_VIEW_MOVEMENT_LAST_CHAR, FALSE, 0);
+ g_signal_emit_by_name (self, "insert-at-cursor", "\n");
+ }
+ else
+ {
+ _ide_source_view_apply_movement (self, IDE_SOURCE_VIEW_MOVEMENT_FIRST_CHAR, FALSE, 0);
+ g_signal_emit_by_name (self, "insert-at-cursor", "\n");
+ _ide_source_view_apply_movement (self, IDE_SOURCE_VIEW_MOVEMENT_PREVIOUS_LINE, FALSE, 0);
+ }
+
+ if (!place_cursor_at_original)
+ {
+ gtk_text_buffer_get_iter_at_mark (buffer, &iter, insert);
+ target_line = gtk_text_iter_get_line (&iter);
+ target_line_offset = gtk_text_iter_get_line_offset (&iter);
+ }
+
gtk_clipboard_set_text (clipboard, trimmed, -1);
GTK_TEXT_VIEW_CLASS (ide_source_view_parent_class)->paste_clipboard (text_view);
gtk_clipboard_set_text (clipboard, text, -1);
}
else
{
-#if 0
- /*
- * TODO:
- *
- * This is more important once we get block mode rendering for characters in place.
- *
- * By default, GtkTextBuffer will paste at our current position. While VIM will paste after
- * the current position. Let's advance the buffer a single character on the current line if
- * possible. We switch to insert mode so that we can move past the last character in the
- * buffer. Possibly should consider an alternate design for this.
- */
- _ide_source_view_apply_movement (self, IDE_SOURCE_VIEW_MOVEMENT_NEXT_CHAR, FALSE, 0);
-#endif
+ if (after_cursor)
+ _ide_source_view_apply_movement (self, IDE_SOURCE_VIEW_MOVEMENT_NEXT_CHAR, FALSE, 0);
+
GTK_TEXT_VIEW_CLASS (ide_source_view_parent_class)->paste_clipboard (text_view);
+
+ if (!place_cursor_at_original)
+ {
+ gtk_text_buffer_get_iter_at_mark (buffer, &iter, insert);
+ target_line = gtk_text_iter_get_line (&iter);
+ target_line_offset = gtk_text_iter_get_line_offset (&iter);
+ }
}
+ gtk_text_buffer_get_iter_at_line (buffer, &iter, target_line);
+ for (; target_line_offset; target_line_offset--)
+ if (gtk_text_iter_ends_line (&iter) || !gtk_text_iter_forward_char (&iter))
+ break;
+ gtk_text_buffer_select_range (buffer, &iter, &iter);
+
gtk_text_buffer_end_user_action (buffer);
}
@@ -2188,7 +2224,6 @@ ide_source_view_class_init (IdeSourceViewClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
- GtkTextViewClass *text_view_class = GTK_TEXT_VIEW_CLASS (klass);
object_class->constructed = ide_source_view_constructed;
object_class->dispose = ide_source_view_dispose;
@@ -2199,8 +2234,6 @@ ide_source_view_class_init (IdeSourceViewClass *klass)
widget_class->key_press_event = ide_source_view_key_press_event;
widget_class->query_tooltip = ide_source_view_query_tooltip;
- text_view_class->paste_clipboard = ide_source_view_real_paste_clipboard;
-
klass->action = ide_source_view_real_action;
klass->change_case = ide_source_view_real_change_case;
klass->clear_selection = ide_source_view_real_clear_selection;
@@ -2210,6 +2243,7 @@ ide_source_view_class_init (IdeSourceViewClass *klass)
klass->join_lines = ide_source_view_real_join_lines;
klass->jump = ide_source_view_real_jump;
klass->movement = ide_source_view_real_movement;
+ klass->paste_clipboard_extended = ide_source_view_real_paste_clipboard_extended;
klass->push_snippet = ide_source_view_real_push_snippet;
klass->restore_insert_mark = ide_source_view_real_restore_insert_mark;
klass->save_insert_mark = ide_source_view_real_save_insert_mark;
@@ -2381,6 +2415,19 @@ ide_source_view_class_init (IdeSourceViewClass *klass)
IDE_TYPE_SOURCE_VIEW_MOVEMENT,
G_TYPE_BOOLEAN);
+ gSignals [PASTE_CLIPBOARD_EXTENDED] =
+ g_signal_new ("paste-clipboard-extended",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (IdeSourceViewClass, paste_clipboard_extended),
+ NULL, NULL,
+ g_cclosure_marshal_generic,
+ G_TYPE_NONE,
+ 3,
+ G_TYPE_BOOLEAN,
+ G_TYPE_BOOLEAN,
+ G_TYPE_BOOLEAN);
+
gSignals [POP_SNIPPET] =
g_signal_new ("pop-snippet",
G_TYPE_FROM_CLASS (klass),
diff --git a/libide/ide-source-view.h b/libide/ide-source-view.h
index f8382c4..b74044f 100644
--- a/libide/ide-source-view.h
+++ b/libide/ide-source-view.h
@@ -194,6 +194,10 @@ struct _IdeSourceViewClass
void (*join_lines) (IdeSourceView *self);
void (*jump) (IdeSourceView *self,
const GtkTextIter *location);
+ void (*paste_clipboard_extended) (IdeSourceView *self,
+ gboolean smart_lines,
+ gboolean after_cursor,
+ gboolean place_cursor_at_original);
void (*pop_snippet) (IdeSourceView *self,
IdeSourceSnippet *snippet);
void (*push_snippet) (IdeSourceView *self,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]