static void gb_vim_do_substitute_line (GtkTextBuffer *buffer, GtkTextIter *begin, const gchar *search_text, const gchar *replace_text, gboolean is_global) { GtkSourceSearchContext *search_context; GtkSourceSearchSettings *search_settings; GtkTextIter match_begin; GtkTextIter match_end; gboolean has_wrapped = FALSE; GError *error = NULL; gint line_number; g_assert(buffer); g_assert(begin); g_assert(search_text); g_assert(replace_text); search_settings = gtk_source_search_settings_new (); search_context = gtk_source_search_context_new (GTK_SOURCE_BUFFER (buffer), search_settings); line_number = gtk_text_iter_get_line(begin); gtk_text_iter_set_line_offset(begin, 0); gtk_source_search_settings_set_search_text (search_settings, search_text); gtk_source_search_settings_set_case_sensitive (search_settings, TRUE); while (gtk_source_search_context_forward (search_context, begin, &match_begin, &match_end, &has_wrapped) && !has_wrapped) { if (gtk_text_iter_get_line (&match_end) != line_number) break; if (!gtk_source_search_context_replace (search_context, &match_begin, &match_end, replace_text, -1, &error)) { g_warning ("%s", error->message); g_clear_error (&error); break; } *begin = match_end; if (!is_global) break; } g_clear_object (&search_settings); g_clear_object (&search_context); }
EditorState * initialize(int *argc, char **argv[]) { gtk_init(argc, argv); FileContainer* file_container = read_file((*argv)[1]); load_css("/home/lee/dev/src/tyreese/styles/style.css"); /* INITIALIZE COMPONENTS */ GtkWidget *main_window = init_window(file_container); GtkBox *horizontal_box = init_box(GTK_ORIENTATION_HORIZONTAL, TRUE); GtkBox *vertical_box = init_box(GTK_ORIENTATION_VERTICAL, FALSE); GtkEntry *tag = init_tag(); GtkContainer *scroll_container = GTK_CONTAINER(init_scroll_container()); GtkSourceBuffer *source_buffer = init_buffer(file_container); GtkSourceView *source_view = init_buffer_view(source_buffer); GtkSourceSearchSettings *search_settings = gtk_source_search_settings_new(); gtk_source_search_settings_set_regex_enabled (search_settings, TRUE); /* PACK COMPONENTS */ gtk_container_add(scroll_container, GTK_WIDGET(source_view)); gtk_box_pack_start(vertical_box, GTK_WIDGET(tag), FALSE, FALSE, 0); gtk_box_pack_start(vertical_box, GTK_WIDGET(scroll_container), TRUE, TRUE, 0); gtk_widget_set_size_request(GTK_WIDGET(main_window), 480, 768-24); gtk_box_pack_start(horizontal_box, GTK_WIDGET(vertical_box), TRUE, TRUE, 0); gtk_container_add(GTK_CONTAINER(main_window), GTK_WIDGET(horizontal_box)); gtk_widget_grab_focus(GTK_WIDGET(source_view)); /* INITIALIZE EDITOR STATE */ EditorState *editor_state = malloc(sizeof(EditorState)); editor_state->root = main_window; editor_state->view = source_view; editor_state->buffer = source_buffer; editor_state->search.settings = search_settings; editor_state->search.context = NULL; editor_state->mode = NO_MODE; editor_state->tag = tag; editor_state->fc = file_container; /* BIND EVENTS */ g_signal_connect(editor_state->root, "destroy", G_CALLBACK(gtk_main_quit), NULL); g_signal_connect(editor_state->root, "key-press-event", G_CALLBACK(window_key_press), editor_state); g_signal_connect(editor_state->tag, "key-press-event", G_CALLBACK(tag_key_press), editor_state); return editor_state; }
static void gb_vim_do_search_and_replace (GtkTextBuffer *buffer, GtkTextIter *begin, GtkTextIter *end, const gchar *search_text, const gchar *replace_text, gboolean is_global) { GtkSourceSearchContext *search_context; GtkSourceSearchSettings *search_settings; GtkTextMark *mark; GtkTextIter tmp1; GtkTextIter tmp2; GtkTextIter match_begin; GtkTextIter match_end; gboolean has_wrapped = FALSE; GError *error = NULL; g_assert (search_text); g_assert (replace_text); g_assert ((!begin && !end) || (begin && end)); search_settings = gtk_source_search_settings_new (); search_context = gtk_source_search_context_new (GTK_SOURCE_BUFFER (buffer), search_settings); if (!begin) { gtk_text_buffer_get_start_iter (buffer, &tmp1); begin = &tmp1; } if (!end) { gtk_text_buffer_get_end_iter (buffer, &tmp2); end = &tmp2; } mark = gtk_text_buffer_create_mark (buffer, NULL, end, FALSE); gtk_source_search_settings_set_search_text (search_settings, search_text); gtk_source_search_settings_set_case_sensitive (search_settings, TRUE); while (gtk_source_search_context_forward2 (search_context, begin, &match_begin, &match_end, &has_wrapped) && !has_wrapped) { if (is_global || gb_vim_match_is_selected (buffer, &match_begin, &match_end)) { if (!gtk_source_search_context_replace2 (search_context, &match_begin, &match_end, replace_text, -1, &error)) { g_warning ("%s", error->message); g_clear_error (&error); break; } } *begin = match_end; gtk_text_buffer_get_iter_at_mark (buffer, end, mark); } gtk_text_buffer_delete_mark (buffer, mark); g_clear_object (&search_settings); g_clear_object (&search_context); }
static void gb_editor_tab_init (GbEditorTab *tab) { GtkSourceCompletion *completion; GbEditorTabPrivate *priv; priv = tab->priv = gb_editor_tab_get_instance_private(tab); priv->is_empty = TRUE; priv->document = gb_editor_document_new(); priv->first_change_handler = g_signal_connect_object (priv->document, "changed", G_CALLBACK (gb_editor_tab_handle_first_change), tab, G_CONNECT_SWAPPED); priv->search_settings = gtk_source_search_settings_new (); priv->search = gtk_source_search_context_new (GTK_SOURCE_BUFFER (priv->document), priv->search_settings); g_signal_connect_object (priv->document, "notify::file", G_CALLBACK (gb_editor_tab_update_title), tab, (G_CONNECT_AFTER | G_CONNECT_SWAPPED)); priv->vbox = g_object_new (GTK_TYPE_BOX, "orientation", GTK_ORIENTATION_VERTICAL, "visible", TRUE, NULL); gtk_container_add (GTK_CONTAINER (tab), priv->vbox); priv->search_bar = g_object_new (GTK_TYPE_SEARCH_BAR, "search-mode-enabled", FALSE, "show-close-button", FALSE, "visible", TRUE, NULL); gtk_container_add (GTK_CONTAINER (priv->vbox), priv->search_bar); priv->search_entry = g_object_new (GTK_TYPE_SEARCH_ENTRY, "visible", TRUE, "width-chars", 32, NULL); g_object_bind_property (priv->search_entry, "text", priv->search_settings, "search-text", G_BINDING_SYNC_CREATE); g_signal_connect_object (priv->search_entry, "changed", G_CALLBACK (gb_editor_tab_search_entry_changed), tab, (G_CONNECT_AFTER | G_CONNECT_SWAPPED)); gtk_container_add (GTK_CONTAINER (priv->search_bar), priv->search_entry); priv->overlay = g_object_new(GTK_TYPE_OVERLAY, "vexpand", TRUE, "visible", TRUE, NULL); gtk_container_add(GTK_CONTAINER(priv->vbox), priv->overlay); priv->scroller = g_object_new(GTK_TYPE_SCROLLED_WINDOW, "visible", TRUE, NULL); gtk_container_add(GTK_CONTAINER(priv->overlay), priv->scroller); priv->text_view = g_object_new(GB_TYPE_SOURCE_VIEW, "buffer", priv->document, "visible", TRUE, NULL); gtk_container_add(GTK_CONTAINER(priv->scroller), priv->text_view); completion = gtk_source_view_get_completion (GTK_SOURCE_VIEW (priv->text_view)); g_object_set (completion, "show-headers", FALSE, "select-on-show", TRUE, NULL); priv->snippets_provider = g_object_new (GB_TYPE_SOURCE_SNIPPET_COMPLETION_PROVIDER, "source-view", priv->text_view, NULL); gtk_source_completion_add_provider (completion, priv->snippets_provider, NULL); priv->search_overlay = g_object_new (GB_TYPE_SOURCE_OVERLAY, "hexpand", TRUE, "search-context", priv->search, "source-view", priv->text_view, "vexpand", TRUE, "visible", FALSE, NULL); gtk_overlay_add_overlay(GTK_OVERLAY(priv->overlay), priv->search_overlay); priv->progress_bar = g_object_new (GTK_TYPE_PROGRESS_BAR, "halign", GTK_ALIGN_FILL, "valign", GTK_ALIGN_START, NULL); gtk_style_context_add_class (gtk_widget_get_style_context (priv->progress_bar), GTK_STYLE_CLASS_OSD); gtk_overlay_add_overlay (GTK_OVERLAY (priv->overlay), priv->progress_bar); priv->floating_bar = g_object_new(NAUTILUS_TYPE_FLOATING_BAR, "halign", GTK_ALIGN_END, "valign", GTK_ALIGN_END, "visible", TRUE, NULL); gtk_overlay_add_overlay(GTK_OVERLAY(priv->overlay), priv->floating_bar); g_signal_connect_object (priv->text_view, "toggle-overwrite", G_CALLBACK (gb_editor_tab_update_location), tab, (G_CONNECT_AFTER | G_CONNECT_SWAPPED)); g_signal_connect_object (priv->document, "notify::language", G_CALLBACK (gb_editor_tab_apply_settings), tab, (G_CONNECT_AFTER | G_CONNECT_SWAPPED)); g_signal_connect_object (priv->document, "delete-range", G_CALLBACK (gb_editor_tab_update_location), tab, (G_CONNECT_AFTER | G_CONNECT_SWAPPED)); g_signal_connect_object (priv->document, "insert-text", G_CALLBACK (gb_editor_tab_update_location), tab, (G_CONNECT_AFTER | G_CONNECT_SWAPPED)); g_signal_connect_object (priv->document, "mark-set", G_CALLBACK (gb_editor_tab_update_location), tab, (G_CONNECT_AFTER | G_CONNECT_SWAPPED)); g_signal_connect_object (priv->text_view, "grab-focus", G_CALLBACK (gb_editor_tab_emit_focused), tab, (G_CONNECT_AFTER | G_CONNECT_SWAPPED)); priv->shared_settings = g_settings_new ("org.gnome.builder.preferences.editor"); g_settings_bind (priv->shared_settings, "font", tab, "font", G_SETTINGS_BIND_GET); g_settings_bind (priv->shared_settings, "style-scheme", tab, "style-scheme-name", G_SETTINGS_BIND_GET); gb_editor_tab_update_location (tab); gb_editor_tab_apply_settings (tab); }
int main (int argc, char *argv[]) { GtkSourceBuffer *buffer; GtkSourceSearchContext *search_context; GtkSourceSearchSettings *search_settings; GtkTextIter iter; GtkTextIter match_end; GTimer *timer; gint i; GtkTextSearchFlags flags; gchar *regex_pattern; gtk_init (&argc, &argv); buffer = gtk_source_buffer_new (NULL); gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter); for (i = 0; i < NB_LINES; i++) { gtk_text_buffer_insert (GTK_TEXT_BUFFER (buffer), &iter, "A line of text to fill the text buffer. Is it long enough?\n", -1); } gtk_text_buffer_insert (GTK_TEXT_BUFFER (buffer), &iter, "foo\n", -1); /* Basic search, no flags */ timer = g_timer_new (); gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter); flags = 0; while (gtk_text_iter_forward_search (&iter, "foo", flags, NULL, &match_end, NULL)) { iter = match_end; } g_timer_stop (timer); g_print ("basic forward search, no flags: %lf seconds.\n", g_timer_elapsed (timer, NULL)); /* Basic search, with flags always enabled by gsv */ g_timer_start (timer); gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter); flags = GTK_TEXT_SEARCH_VISIBLE_ONLY | GTK_TEXT_SEARCH_TEXT_ONLY; while (gtk_text_iter_forward_search (&iter, "foo", flags, NULL, &match_end, NULL)) { iter = match_end; } g_timer_stop (timer); g_print ("basic forward search, visible and text only flags: %lf seconds.\n", g_timer_elapsed (timer, NULL)); /* Basic search, with default flags in gsv */ g_timer_start (timer); gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter); flags = GTK_TEXT_SEARCH_VISIBLE_ONLY | GTK_TEXT_SEARCH_TEXT_ONLY | GTK_TEXT_SEARCH_CASE_INSENSITIVE; while (gtk_text_iter_forward_search (&iter, "foo", flags, NULL, &match_end, NULL)) { iter = match_end; } g_timer_stop (timer); g_print ("basic forward search, all flags: %lf seconds.\n", g_timer_elapsed (timer, NULL)); /* Smart forward search, with default flags in gsv */ search_settings = gtk_source_search_settings_new (); search_context = gtk_source_search_context_new (buffer, search_settings); g_timer_start (timer); gtk_source_search_settings_set_search_text (search_settings, "foo"); gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter); while (gtk_source_search_context_forward (search_context, &iter, NULL, &match_end, NULL)) { iter = match_end; } g_timer_stop (timer); g_print ("smart synchronous forward search, case insensitive: %lf seconds.\n", g_timer_elapsed (timer, NULL)); /* Smart forward search, case sensitive */ g_timer_start (timer); gtk_source_search_settings_set_search_text (search_settings, NULL); gtk_source_search_settings_set_case_sensitive (search_settings, TRUE); gtk_source_search_settings_set_search_text (search_settings, "foo"); gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter); while (gtk_source_search_context_forward (search_context, &iter, NULL, &match_end, NULL)) { iter = match_end; } g_timer_stop (timer); g_print ("smart synchronous forward search, case sensitive: %lf seconds.\n", g_timer_elapsed (timer, NULL)); /* Regex search: search "foo" */ g_timer_start (timer); gtk_source_search_settings_set_search_text (search_settings, NULL); gtk_source_search_settings_set_regex_enabled (search_settings, TRUE); gtk_source_search_settings_set_search_text (search_settings, "foo"); gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter); while (gtk_source_search_context_forward (search_context, &iter, NULL, &match_end, NULL)) { iter = match_end; } g_timer_stop (timer); g_print ("regex search: 'foo' (no partial matches): %lf seconds.\n", g_timer_elapsed (timer, NULL)); /* Regex search: search "fill" */ g_timer_start (timer); gtk_source_search_settings_set_search_text (search_settings, "fill"); gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter); while (gtk_source_search_context_forward (search_context, &iter, NULL, &match_end, NULL)) { iter = match_end; } g_timer_stop (timer); g_print ("regex search: 'fill' (no partial matches): %lf seconds.\n", g_timer_elapsed (timer, NULL)); /* Regex search: search single lines */ g_timer_start (timer); gtk_source_search_settings_set_search_text (search_settings, ".*"); gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter); while (gtk_source_search_context_forward (search_context, &iter, NULL, &match_end, NULL)) { iter = match_end; } g_timer_stop (timer); g_print ("regex search: match single lines (no partial matches): %lf seconds.\n", g_timer_elapsed (timer, NULL)); /* Regex search: search matches of 3 lines */ g_timer_start (timer); /* The space at the beginning of the pattern permits to not have contiguous * matches. There is a performance issue with contiguous matches. */ gtk_source_search_settings_set_search_text (search_settings, " (.*\n){3}"); gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter); while (gtk_source_search_context_forward (search_context, &iter, NULL, &match_end, NULL)) { iter = match_end; } g_timer_stop (timer); g_print ("regex search: matches of 3 lines (small partial matches): %lf seconds.\n", g_timer_elapsed (timer, NULL)); /* Regex search: search matches of really big chunks */ g_timer_start (timer); regex_pattern = g_strdup_printf (" (.*\n){%d}", NB_LINES / 10); gtk_source_search_settings_set_search_text (search_settings, regex_pattern); g_free (regex_pattern); gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter); while (gtk_source_search_context_forward (search_context, &iter, NULL, &match_end, NULL)) { iter = match_end; } g_timer_stop (timer); g_print ("regex search: 10 matches of %d lines (big partial matches): %lf seconds.\n", NB_LINES / 10, g_timer_elapsed (timer, NULL)); /* Smart search, case sensitive, asynchronous */ /* The asynchronous overhead doesn't depend on the search flags, it * depends on the maximum number of lines to scan in one batch, and * (obviously), on the buffer size. * You can tune SCAN_BATCH_SIZE in gtksourcesearchcontext.c to see a * difference in the overhead. */ g_signal_connect (search_context, "notify::occurrences-count", G_CALLBACK (on_notify_search_occurrences_count_cb), timer); g_timer_start (timer); gtk_source_search_settings_set_search_text (search_settings, NULL); gtk_source_search_settings_set_regex_enabled (search_settings, FALSE); gtk_source_search_settings_set_search_text (search_settings, "foo"); gtk_main (); return 0; }
static void change_all_cb (GeditSpellCheckerDialog *dlg, const gchar *word, const gchar *change, GeditView *view) { GeditDocument *doc; CheckRange *range; gchar *w = NULL; GtkTextIter start, end; GtkSourceSearchSettings *search_settings; GtkSourceSearchContext *search_context; gedit_debug (DEBUG_PLUGINS); g_return_if_fail (view != NULL); g_return_if_fail (word != NULL); g_return_if_fail (change != NULL); doc = GEDIT_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); g_return_if_fail (doc != NULL); range = get_check_range (doc); g_return_if_fail (range != NULL); gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc), &start, range->mw_start); if (range->mw_end < 0) gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (doc), &end); else gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc), &end, range->mw_end); w = gtk_text_buffer_get_slice (GTK_TEXT_BUFFER (doc), &start, &end, TRUE); g_return_if_fail (w != NULL); if (strcmp (w, word) != 0) { g_free (w); return; } g_free (w); search_settings = gtk_source_search_settings_new (); gtk_source_search_settings_set_case_sensitive (search_settings, TRUE); gtk_source_search_settings_set_at_word_boundaries (search_settings, TRUE); gtk_source_search_settings_set_search_text (search_settings, word); search_context = gtk_source_search_context_new (GTK_SOURCE_BUFFER (doc), search_settings); gtk_source_search_context_set_highlight (search_context, FALSE); gtk_source_search_context_replace_all (search_context, change, -1, NULL); update_current (doc, range->mw_start + g_utf8_strlen (change, -1)); /* go to next misspelled word */ ignore_cb (dlg, word, view); g_object_unref (search_settings); g_object_unref (search_context); }