static gchar * smie_gtk_source_buffer_backward_token (gpointer data) { smie_gtk_source_buffer_context_t *context = data; GtkTextIter iter, start_iter; if (gtk_text_iter_is_start (&context->iter)) return NULL; /* Skip comments and whitespaces. */ gtk_text_iter_backward_char (&context->iter); while (!gtk_text_iter_is_start (&context->iter) && (gtk_source_buffer_iter_has_context_class (context->buffer, &context->iter, "comment") || g_unichar_isspace (gtk_text_iter_get_char (&context->iter)))) gtk_text_iter_backward_char (&context->iter); gtk_text_iter_assign (&iter, &context->iter); if (gtk_source_buffer_iter_has_context_class (context->buffer, &context->iter, "string")) { /* Read a string literal. */ while (!gtk_text_iter_is_start (&context->iter) && gtk_source_buffer_iter_has_context_class (context->buffer, &context->iter, "string")) gtk_text_iter_backward_char (&context->iter); } else if (g_unichar_ispunct (gtk_text_iter_get_char (&context->iter))) { /* Read a punctuation. */ while (!gtk_text_iter_is_start (&context->iter) && g_unichar_ispunct (gtk_text_iter_get_char (&context->iter))) gtk_text_iter_backward_char (&context->iter); } else { /* Read a normal token. */ while (!gtk_text_iter_is_start (&context->iter) && !(gtk_source_buffer_iter_has_context_class (context->buffer, &context->iter, "comment") || gtk_source_buffer_iter_has_context_class (context->buffer, &context->iter, "string") || g_unichar_ispunct (gtk_text_iter_get_char (&context->iter)) || g_unichar_isspace (gtk_text_iter_get_char (&context->iter)))) gtk_text_iter_backward_char (&context->iter); } gtk_text_iter_assign (&start_iter, &context->iter); if (!gtk_text_iter_is_start (&start_iter)) gtk_text_iter_forward_char (&start_iter); gtk_text_iter_forward_char (&iter); return gtk_text_iter_get_slice (&start_iter, &iter); }
static void ide_source_snippet_get_nth_chunk_range (IdeSourceSnippet *self, gint n, GtkTextIter *begin, GtkTextIter *end) { gint run; gint i; g_return_if_fail (IDE_IS_SOURCE_SNIPPET (self)); g_return_if_fail (n >= 0); g_return_if_fail (begin); g_return_if_fail (end); gtk_text_buffer_get_iter_at_mark (self->buffer, begin, self->mark_begin); for (i = 0; i < n; i++) { run = g_array_index (self->runs, gint, i); gtk_text_iter_forward_chars (begin, run); } gtk_text_iter_assign (end, begin); run = g_array_index (self->runs, gint, n); gtk_text_iter_forward_chars (end, run); }
static void smie_gtk_source_buffer_pop_context (gpointer data) { smie_gtk_source_buffer_context_t *context = data; g_return_if_fail (context->stack); gtk_text_iter_assign (&context->iter, context->stack->data); gtk_text_iter_free (context->stack->data); context->stack = g_list_delete_link (context->stack, context->stack); }
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 gboolean smie_gtk_source_buffer_forward_comment (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_is_end (&context->iter) && (gtk_source_buffer_iter_has_context_class (context->buffer, &context->iter, "comment") || g_unichar_isspace (gtk_text_iter_get_char (&context->iter))) && gtk_text_iter_forward_char (&context->iter)) ; return !gtk_text_iter_equal (&context->iter, &start_iter); }
gchar * ide_source_snippet_get_nth_text (IdeSourceSnippet *self, gint n) { GtkTextIter iter; GtkTextIter end; gchar *ret; gint i; g_return_val_if_fail (IDE_IS_SOURCE_SNIPPET (self), NULL); g_return_val_if_fail (n >= 0, NULL); gtk_text_buffer_get_iter_at_mark (self->buffer, &iter, self->mark_begin); for (i = 0; i < n; i++) gtk_text_iter_forward_chars (&iter, g_array_index (self->runs, gint, i)); gtk_text_iter_assign (&end, &iter); gtk_text_iter_forward_chars (&end, g_array_index (self->runs, gint, n)); ret = gtk_text_buffer_get_text (self->buffer, &iter, &end, TRUE); return ret; }
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); }