/* Get the boundary, on @iter's line, between the end of the text and trailing * spaces. */ void _gtk_source_iter_get_trailing_spaces_start_boundary (const GtkTextIter *iter, GtkTextIter *trailing_start) { g_return_if_fail (iter != NULL); g_return_if_fail (trailing_start != NULL); *trailing_start = *iter; if (!gtk_text_iter_ends_line (trailing_start)) { gtk_text_iter_forward_to_line_end (trailing_start); } while (!gtk_text_iter_starts_line (trailing_start)) { GtkTextIter prev; gunichar ch; prev = *trailing_start; gtk_text_iter_backward_char (&prev); ch = gtk_text_iter_get_char (&prev); if (!g_unichar_isspace (ch)) { break; } *trailing_start = prev; } }
static gboolean ide_langserv_completion_provider_match (GtkSourceCompletionProvider *provider, GtkSourceCompletionContext *context) { GtkSourceCompletionActivation activation; GtkTextIter iter; g_assert (IDE_IS_LANGSERV_COMPLETION_PROVIDER (provider)); g_assert (GTK_SOURCE_IS_COMPLETION_CONTEXT (context)); if (!gtk_source_completion_context_get_iter (context, &iter)) return FALSE; activation = gtk_source_completion_context_get_activation (context); if (activation == GTK_SOURCE_COMPLETION_ACTIVATION_INTERACTIVE) { if (gtk_text_iter_starts_line (&iter) || !gtk_text_iter_backward_char (&iter) || g_unichar_isspace (gtk_text_iter_get_char (&iter))) return FALSE; } if (ide_completion_provider_context_in_comment (context)) return FALSE; return TRUE; }
static void ide_source_view_movements_line_chars (Movement *mv) { GtkTextIter orig = mv->insert; /* * Selects the current position up to the first nonspace character. * If the cursor is at the line start, we will select the newline. * If only whitespace exists, we will select line offset of 0. */ if (gtk_text_iter_starts_line (&mv->insert)) { gtk_text_iter_backward_char (&mv->insert); } else { gunichar ch; gtk_text_iter_set_line_offset (&mv->insert, 0); while (!gtk_text_iter_ends_line (&mv->insert) && (ch = gtk_text_iter_get_char (&mv->insert)) && g_unichar_isspace (ch)) gtk_text_iter_forward_char (&mv->insert); if (gtk_text_iter_ends_line (&mv->insert) || (gtk_text_iter_compare (&orig, &mv->insert) <= 0)) gtk_text_iter_set_line_offset (&mv->insert, 0); } if (!mv->exclusive) gtk_text_iter_forward_char (&mv->insert); }
void apotheke_highlight_buffer_diff (GtkTextBuffer *buffer, GtkTextIter *start) { GtkTextIter *end; GtkTextIter *word_end; gchar *c; if (!gtk_text_iter_starts_line (start)) gtk_text_iter_set_line_offset (start, 0); while (!gtk_text_iter_is_end (start)) { end = gtk_text_iter_copy (start); if (!gtk_text_iter_forward_to_line_end (end)) break; word_end = gtk_text_iter_copy (start); gtk_text_iter_forward_char (word_end); c = gtk_text_iter_get_text (start, word_end); if (g_ascii_strcasecmp ("+", c) == 0) { gtk_text_buffer_apply_tag_by_name (buffer, "diff-added", start, end); } else if (g_ascii_strcasecmp ("-", c) == 0) { gtk_text_buffer_apply_tag_by_name (buffer, "diff-removed", start, end); } gtk_text_iter_forward_line (start); } }
//カーソルのある行を削除する void kill_line(void) { int delete_flag = 0; GtkTextIter start, end; GtkClipboard *clipboard = gtk_widget_get_clipboard(view, GDK_SELECTION_CLIPBOARD); buf[0] = '\0'; if (kill_flag == 1) { char *text = gtk_clipboard_wait_for_text(clipboard); strcat(buf, text); free(text); } gtk_text_buffer_get_iter_at_mark(GTK_TEXT_BUFFER(buffer), &start, gtk_text_buffer_get_insert(GTK_TEXT_BUFFER(buffer))); end = start; gtk_text_iter_forward_line(&end); if (!gtk_text_iter_starts_line(&start) && !gtk_text_iter_ends_line(&start) && !gtk_text_iter_is_end(&end) && kill_flag == 0) gtk_text_iter_backward_char(&end); char *text = gtk_text_buffer_get_text(GTK_TEXT_BUFFER(buffer), &start, &end, TRUE); strcat(buf, text); free(text); if (buf[0] != '\0') delete_flag = 1; gtk_clipboard_set_text(clipboard, buf, -1); gtk_text_buffer_delete(GTK_TEXT_BUFFER(buffer), &start, &end); kill_flag = delete_flag; }
static gboolean ide_ctags_completion_provider_match (GtkSourceCompletionProvider *provider, GtkSourceCompletionContext *context) { IdeCtagsCompletionProvider *self = (IdeCtagsCompletionProvider *)provider; GtkSourceCompletionActivation activation; GtkTextIter iter; g_assert (IDE_IS_CTAGS_COMPLETION_PROVIDER (self)); g_assert (GTK_SOURCE_IS_COMPLETION_CONTEXT (context)); if (!gtk_source_completion_context_get_iter (context, &iter)) return FALSE; activation = gtk_source_completion_context_get_activation (context); if (activation == GTK_SOURCE_COMPLETION_ACTIVATION_INTERACTIVE) { if (gtk_text_iter_starts_line (&iter) || !gtk_text_iter_backward_char (&iter) || g_unichar_isspace (gtk_text_iter_get_char (&iter))) return FALSE; } if (!g_settings_get_boolean (self->settings, "ctags-autocompletion")) return FALSE; if (ide_completion_provider_context_in_comment (context)) return FALSE; return TRUE; }
static void gbp_retab_editor_page_addin_action (GSimpleAction *action, GVariant *variant, gpointer user_data) { GbpRetabEditorPageAddin *self = user_data; IdeSourceView *source_view; GtkTextBuffer *buffer; IdeCompletion *completion; guint tab_width; gint start_line; gint end_line; gint indent; GtkTextIter begin; GtkTextIter end; gboolean editable; gboolean to_spaces; g_assert (GBP_IS_RETAB_EDITOR_PAGE_ADDIN (self)); g_assert (G_IS_SIMPLE_ACTION (action)); buffer = GTK_TEXT_BUFFER (ide_editor_page_get_buffer (self->editor_view)); source_view = ide_editor_page_get_view (self->editor_view); g_assert (IDE_IS_SOURCE_VIEW (source_view)); editable = gtk_text_view_get_editable (GTK_TEXT_VIEW (source_view)); completion = ide_source_view_get_completion (IDE_SOURCE_VIEW (source_view)); tab_width = gtk_source_view_get_tab_width(GTK_SOURCE_VIEW (source_view)); to_spaces = gtk_source_view_get_insert_spaces_instead_of_tabs(GTK_SOURCE_VIEW (source_view)); if (!editable) return; gtk_text_buffer_get_selection_bounds (buffer, &begin, &end); gtk_text_iter_order (&begin, &end); if (!gtk_text_iter_equal (&begin, &end) && gtk_text_iter_starts_line (&end)) gtk_text_iter_backward_char (&end); start_line = gtk_text_iter_get_line (&begin); end_line = gtk_text_iter_get_line (&end); ide_completion_block_interactive (completion); gtk_text_buffer_begin_user_action (buffer); for (gint line = start_line; line <= end_line; ++line) { indent = get_buffer_range_indent (buffer, line, to_spaces); if (indent > 0) gbp_retab_editor_page_addin_retab (buffer, line, tab_width, indent, to_spaces); } gtk_text_buffer_end_user_action (buffer); ide_completion_unblock_interactive (completion); }
static gboolean smie_gtk_source_buffer_backward_to_line_start (gpointer data) { smie_gtk_source_buffer_context_t *context = data; GtkTextIter start_iter; gtk_text_iter_assign (&start_iter, &context->iter); while (!gtk_text_iter_starts_line (&context->iter)) gtk_text_iter_backward_char (&context->iter); return !gtk_text_iter_equal (&context->iter, &start_iter); }
static void ide_source_view_movements_last_char (Movement *mv) { if (!gtk_text_iter_ends_line (&mv->insert)) { gtk_text_iter_forward_to_line_end (&mv->insert); if (mv->exclusive && !gtk_text_iter_starts_line (&mv->insert)) gtk_text_iter_backward_char (&mv->insert); } }
static gboolean search_elem_locate(GtkTextBuffer* buf, gint* pline, gint* poffset, CppElem* elem) { GtkTextIter iter; GtkTextIter limit; GtkTextIter ps; GtkTextIter pe; guint ch; gboolean full_matched; gboolean need_move_cursor; *pline = elem->sline - 1; *poffset = -1; gtk_text_buffer_get_iter_at_line(buf, &iter, *pline); limit = iter; gtk_text_iter_forward_to_line_end(&limit); need_move_cursor = TRUE; full_matched = FALSE; while( gtk_text_iter_forward_search(&iter, elem->name->buf, 0, &ps, &pe, &limit) ) { *poffset = gtk_text_iter_get_line_offset(&pe); gtk_text_buffer_select_range(buf, &pe, &ps); need_move_cursor = FALSE; if( gtk_text_iter_starts_line(&ps) ) { full_matched = TRUE; } else { iter = ps; gtk_text_iter_backward_char(&iter); ch = gtk_text_iter_get_char(&iter); if( !g_unichar_isalnum(ch) && ch!='_' ) full_matched = TRUE; } if( full_matched && !gtk_text_iter_ends_line(&pe) ) { iter = pe; gtk_text_iter_forward_char(&iter); ch = gtk_text_iter_get_char(&iter); if( g_unichar_isalnum(ch) || ch=='_' ) full_matched = FALSE; } if( full_matched ) break; iter = ps; gtk_text_iter_forward_char(&iter); } return need_move_cursor; }
static void ide_source_view_movements_previous_char (Movement *mv) { mv->count = MAX (1, mv->count); for (; mv->count; mv->count--) { if (gtk_text_iter_starts_line (&mv->insert)) break; gtk_text_iter_backward_char (&mv->insert); } if (!mv->exclusive) gtk_text_iter_forward_char (&mv->insert); }
static gboolean text_iter_forward_to_empty_line (GtkTextIter *iter, GtkTextIter *bounds) { if (!gtk_text_iter_forward_char (iter)) return FALSE; while (gtk_text_iter_compare (iter, bounds) < 0) { if (gtk_text_iter_starts_line (iter) && gtk_text_iter_ends_line (iter)) return TRUE; if (!gtk_text_iter_forward_char (iter)) return FALSE; } return FALSE; }
gboolean mousepad_util_iter_backward_text_start (GtkTextIter *iter) { GtkTextIter prev = *iter; g_return_val_if_fail (!mousepad_util_iter_inside_word (iter), FALSE); while (!gtk_text_iter_starts_line (&prev) && gtk_text_iter_backward_char (&prev)) { if (g_unichar_isspace (gtk_text_iter_get_char (&prev))) *iter = prev; else break; } return TRUE; }
static void on_insert_text_before (GtkTextBuffer *buffer, GtkTextIter *location, gchar *text, gint len, InsertData *data) { if (gtk_text_iter_starts_line (location)) { GSList *marks; marks = gtk_source_buffer_get_source_marks_at_iter (GTK_SOURCE_BUFFER (buffer), location, BOOKMARK_CATEGORY); if (marks != NULL) { add_tracker (buffer, location, marks->data, data); g_slist_free (marks); } } }
static void ide_source_view_movements_previous_word_end (Movement *mv) { GtkTextIter copy; copy = mv->insert; _ide_vim_iter_backward_word_end (&mv->insert); /* * Vim treats an empty line as a word. */ while ((gtk_text_iter_compare (©, &mv->insert) > 0) && gtk_text_iter_backward_char (©)) { if (gtk_text_iter_starts_line (©) && gtk_text_iter_ends_line (©)) mv->insert = copy; } if (!mv->exclusive && !gtk_text_iter_ends_line (&mv->insert)) gtk_text_iter_forward_char (&mv->insert); }
gboolean gtk_source_completion_words_utils_backward_word_start (GtkTextIter *iter, CharacterCheck valid, CharacterCheck valid_start, gpointer data) { GtkTextIter prev = *iter; /* Go backward as long as there are word characters */ while (TRUE) { /* Starting a line is good */ if (gtk_text_iter_starts_line (&prev)) { break; } gtk_text_iter_backward_char (&prev); /* Check if the previous character is a valid word character */ if (!valid (gtk_text_iter_get_char (&prev), data)) { break; } *iter = prev; } if (!valid (gtk_text_iter_get_char (iter), data)) { return FALSE; } /* Go forward with while !valid_start */ return valid_start (gtk_text_iter_get_char (iter), data); }
static gboolean smie_gtk_source_buffer_starts_line (gpointer data) { smie_gtk_source_buffer_context_t *context = data; return gtk_text_iter_starts_line (&context->iter); }
static gboolean editor_application_window_key_press_event (GtkWidget *widget, GdkEventKey *event) { EditorApplicationWindow *window = EDITOR_APPLICATION_WINDOW (widget); if (event->keyval == GDK_KEY_KP_Tab || event->keyval == GDK_KEY_Tab) { GtkTextMark *mark; smie_gtk_source_buffer_context_t context; gint indent, current_indent; GtkTextIter iter, start_iter, end_iter; memset (&context, 0, sizeof (smie_gtk_source_buffer_context_t)); context.buffer = window->buffer; mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (window->buffer)); gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (window->buffer), &iter, mark); gtk_text_iter_assign (&context.iter, &iter); indent = smie_indenter_calculate (window->indenter, &context); if (indent < 0) { g_printf ("indent: undetermined\n"); return TRUE; } else g_printf ("indent: %d\n", indent); /* Point START_ITER to the beginning of the line. */ gtk_text_iter_assign (&start_iter, &iter); while (!gtk_text_iter_is_start (&start_iter) && !gtk_text_iter_starts_line (&start_iter) && gtk_text_iter_backward_char (&start_iter)) ; /* Point END_ITER to the end of the indent and count the offset. */ gtk_text_iter_assign (&end_iter, &start_iter); current_indent = 0; while (!gtk_text_iter_is_end (&end_iter) && !gtk_text_iter_ends_line (&end_iter) && g_unichar_isspace (gtk_text_iter_get_char (&end_iter)) && gtk_text_iter_forward_char (&end_iter)) current_indent++; /* Replace the current indent if it doesn't match the computed one. */ if (indent < current_indent) { gtk_text_iter_forward_chars (&start_iter, indent); gtk_text_buffer_delete (GTK_TEXT_BUFFER (window->buffer), &start_iter, &end_iter); } else if (indent > current_indent) { gchar *text = g_new0 (gchar, indent - current_indent); memset (text, ' ', indent * sizeof (gchar)); gtk_text_buffer_insert (GTK_TEXT_BUFFER (window->buffer), &start_iter, text, indent - current_indent); g_free (text); } return TRUE; } return GTK_WIDGET_CLASS (editor_application_window_parent_class)->key_press_event (widget, event); }
static gboolean on_view_draw (GtkSourceView *view, cairo_t *cr, GtkSourceGutter *gutter) { GdkWindow *window; GtkTextView *text_view; GArray *sizes; GdkRectangle clip; gint x, y; gint y1, y2; GArray *numbers; GArray *pixels; GArray *heights; GtkTextIter cur; gint cur_line; gint count; gint i; GList *item; GtkTextIter start; GtkTextIter end; GtkTextBuffer *buffer; GdkRectangle background_area; GdkRectangle cell_area; GtkTextIter selection_start; GtkTextIter selection_end; gboolean has_selection; gint idx; GtkStyleContext *style_context; GdkRGBA fg_color; window = gtk_source_gutter_get_window (gutter); if (window == NULL || !gtk_cairo_should_draw_window (cr, window)) { return FALSE; } gtk_cairo_transform_to_window (cr, GTK_WIDGET (view), window); text_view = GTK_TEXT_VIEW (view); if (!gdk_cairo_get_clip_rectangle (cr, &clip)) { return FALSE; } gutter->priv->is_drawing = TRUE; buffer = gtk_text_view_get_buffer (text_view); gdk_window_get_pointer (window, &x, &y, NULL); y1 = clip.y; y2 = y1 + clip.height; /* get the extents of the line printing */ gtk_text_view_window_to_buffer_coords (text_view, gutter->priv->window_type, 0, y1, NULL, &y1); gtk_text_view_window_to_buffer_coords (text_view, gutter->priv->window_type, 0, y2, NULL, &y2); numbers = g_array_new (FALSE, FALSE, sizeof (gint)); pixels = g_array_new (FALSE, FALSE, sizeof (gint)); heights = g_array_new (FALSE, FALSE, sizeof (gint)); sizes = g_array_new (FALSE, FALSE, sizeof (gint)); calculate_gutter_size (gutter, sizes); i = 0; x = 0; background_area.x = 0; background_area.height = get_lines (text_view, y1, y2, pixels, heights, numbers, &count, &start, &end); cell_area.x = gutter->priv->xpad; cell_area.height = background_area.height; gtk_text_view_buffer_to_window_coords (text_view, gutter->priv->window_type, 0, g_array_index (pixels, gint, 0), NULL, &background_area.y); cell_area.y = background_area.y; item = gutter->priv->renderers; idx = 0; style_context = gtk_widget_get_style_context (GTK_WIDGET (view)); gtk_style_context_get_color (style_context, gtk_widget_get_state (GTK_WIDGET (view)), &fg_color); gdk_cairo_set_source_rgba (cr, &fg_color); while (item) { Renderer *renderer = item->data; gint xpad; gint width; width = g_array_index (sizes, gint, idx++); if (gtk_source_gutter_renderer_get_visible (renderer->renderer)) { gtk_source_gutter_renderer_get_padding (renderer->renderer, &xpad, NULL); background_area.width = width; cell_area.width = width - 2 * xpad; cell_area.x = background_area.x + xpad; cairo_save (cr); gdk_cairo_rectangle (cr, &background_area); cairo_clip (cr); gtk_source_gutter_renderer_begin (renderer->renderer, cr, &background_area, &cell_area, &start, &end); cairo_restore (cr); background_area.x += background_area.width; } item = g_list_next (item); } gtk_text_buffer_get_iter_at_mark (buffer, &cur, gtk_text_buffer_get_insert (buffer)); cur_line = gtk_text_iter_get_line (&cur); gtk_text_buffer_get_selection_bounds (buffer, &selection_start, &selection_end); has_selection = !gtk_text_iter_equal (&selection_start, &selection_end); if (has_selection) { if (!gtk_text_iter_starts_line (&selection_start)) { gtk_text_iter_set_line_offset (&selection_start, 0); } if (!gtk_text_iter_ends_line (&selection_end)) { gtk_text_iter_forward_to_line_end (&selection_end); } } for (i = 0; i < count; ++i) { gint pos; gint line_to_paint; end = start; if (!gtk_text_iter_ends_line (&end)) { gtk_text_iter_forward_to_line_end (&end); } gtk_text_view_buffer_to_window_coords (text_view, gutter->priv->window_type, 0, g_array_index (pixels, gint, i), NULL, &pos); line_to_paint = g_array_index (numbers, gint, i); background_area.y = pos; background_area.height = g_array_index (heights, gint, i); background_area.x = 0; idx = 0; for (item = gutter->priv->renderers; item; item = g_list_next (item)) { Renderer *renderer; gint width; GtkSourceGutterRendererState state; gint xpad; gint ypad; renderer = item->data; width = g_array_index (sizes, gint, idx++); if (!gtk_source_gutter_renderer_get_visible (renderer->renderer)) { continue; } gtk_source_gutter_renderer_get_padding (renderer->renderer, &xpad, &ypad); background_area.width = width; cell_area.y = background_area.y + ypad; cell_area.height = background_area.height - 2 * ypad; cell_area.x = background_area.x + xpad; cell_area.width = background_area.width - 2 * xpad; state = GTK_SOURCE_GUTTER_RENDERER_STATE_NORMAL; if (line_to_paint == cur_line) { state |= GTK_SOURCE_GUTTER_RENDERER_STATE_CURSOR; } if (has_selection && gtk_text_iter_in_range (&start, &selection_start, &selection_end)) { state |= GTK_SOURCE_GUTTER_RENDERER_STATE_SELECTED; } if (renderer->prelit >= 0 && cell_area.y <= renderer->prelit && cell_area.y + cell_area.height >= renderer->prelit) { state |= GTK_SOURCE_GUTTER_RENDERER_STATE_PRELIT; } gtk_source_gutter_renderer_query_data (renderer->renderer, &start, &end, state); cairo_save (cr); gdk_cairo_rectangle (cr, &background_area); cairo_clip (cr); /* Call render with correct area */ gtk_source_gutter_renderer_draw (renderer->renderer, cr, &background_area, &cell_area, &start, &end, state); cairo_restore (cr); background_area.x += background_area.width; } gtk_text_iter_forward_line (&start); } for (item = gutter->priv->renderers; item; item = g_list_next (item)) { Renderer *renderer = item->data; if (gtk_source_gutter_renderer_get_visible (renderer->renderer)) { gtk_source_gutter_renderer_end (renderer->renderer); } } g_array_free (numbers, TRUE); g_array_free (pixels, TRUE); g_array_free (heights, TRUE); g_array_free (sizes, TRUE); gutter->priv->is_drawing = FALSE; return FALSE; }