summaryrefslogtreecommitdiff
path: root/testsuite
diff options
context:
space:
mode:
authorChristian Hergert <chergert@redhat.com>2021-10-18 15:42:54 -0700
committerChristian Hergert <chergert@redhat.com>2021-11-11 21:36:52 -0800
commit15f4c2704131624d571f91f697811efb0567da89 (patch)
treed354aaf1d79158221e86fc1f60ba680e45367c97 /testsuite
parentf9ae3c6a2e4bf119a04550ca04e7846af160e3ef (diff)
downloadgtksourceview-15f4c2704131624d571f91f697811efb0567da89.tar.gz
vim: add GtkSourceVimIMContext
This adds a new GtkIMContext implementation that attempts to emulate a modern Vim experience. It can be used with a GtkSourceView by connecting it to a GtkEventControllerKey and adding it to a view. This is an initial implementation and could use further work on matching semantics with Vim. However it has a number of features beyond what was implemented in GNOME Builder. Various features supported by GtkSourceVimIMContext include: - Normal, Insert, Replace, Visual, and Visual Line modes - Support for an integrated command bar and current command preview - Search and replace - Motions and Text Objects - History replay - Jumplists within the current file - Registers including the system and primary clipboards - Creation and motion to marks - Some commonly used Vim commands Fixes #233
Diffstat (limited to 'testsuite')
-rw-r--r--testsuite/meson.build3
-rw-r--r--testsuite/test-vim-input.c227
-rw-r--r--testsuite/test-vim-state.c74
-rw-r--r--testsuite/test-vim-text-object.c248
4 files changed, 552 insertions, 0 deletions
diff --git a/testsuite/meson.build b/testsuite/meson.build
index efa4072a..2940639f 100644
--- a/testsuite/meson.build
+++ b/testsuite/meson.build
@@ -37,6 +37,9 @@ testsuite_sources = [
['test-syntax'],
['test-utils'],
['test-view'],
+ ['test-vim-input'],
+ ['test-vim-state'],
+ ['test-vim-text-object'],
]
foreach test: testsuite_sources
diff --git a/testsuite/test-vim-input.c b/testsuite/test-vim-input.c
new file mode 100644
index 00000000..1a6b32a5
--- /dev/null
+++ b/testsuite/test-vim-input.c
@@ -0,0 +1,227 @@
+/*
+ * This file is part of GtkSourceView
+ *
+ * Copyright 2021 Christian Hergert <chergert@redhat.com>
+ *
+ * GtkSourceView is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GtkSourceView is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "config.h"
+
+#include <gtksourceview/gtksource.h>
+#include <gtksourceview/vim/gtksourcevim.h>
+#include <gtksourceview/vim/gtksourcevimcommand.h>
+#include <gtksourceview/vim/gtksourceviminsert.h>
+#include <gtksourceview/vim/gtksourcevimnormal.h>
+#include <gtksourceview/vim/gtksourcevimstate.h>
+
+static void
+run_test (const char *text,
+ const char *input,
+ const char *expected)
+{
+ GtkSourceView *view = GTK_SOURCE_VIEW (g_object_ref_sink (gtk_source_view_new ()));
+ GtkSourceBuffer *buffer = GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
+ GtkSourceVim *vim = gtk_source_vim_new (view);
+ GtkTextIter begin, end;
+ char *ret;
+
+ gtk_text_buffer_set_text (GTK_TEXT_BUFFER (buffer), text, -1);
+ gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (buffer), &begin, &end);
+ gtk_text_buffer_select_range (GTK_TEXT_BUFFER (buffer), &begin, &begin);
+
+ for (const char *c = input; *c; c = g_utf8_next_char (c))
+ {
+ GtkSourceVimState *current = gtk_source_vim_state_get_current (GTK_SOURCE_VIM_STATE (vim));
+ gunichar ch = g_utf8_get_char (c);
+ char string[16] = {0};
+ GdkModifierType mods = 0;
+ guint keyval;
+
+ /* It would be nice to send GdkEvent, but we have to rely on
+ * the fact that our engine knows key-presses pretty much
+ * everywhere so that we can send keypresses based on chars.
+ */
+ string[g_unichar_to_utf8 (ch, string)] = 0;
+
+ if (ch == '\e')
+ {
+ string[0] = '^';
+ string[1] = '[';
+ string[2] = 0;
+ keyval = GDK_KEY_Escape;
+ }
+ else if (ch == '\n')
+ {
+ string[0] = '\n';
+ string[1] = 0;
+ keyval = GDK_KEY_Return;
+ }
+ else
+ {
+ keyval = gdk_unicode_to_keyval (ch);
+ }
+
+ if (!GTK_SOURCE_VIM_STATE_GET_CLASS (current)->handle_keypress (current, keyval, 0, mods, string))
+ {
+ gtk_text_buffer_insert_at_cursor (GTK_TEXT_BUFFER (buffer), string, -1);
+ }
+ }
+
+ gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (buffer), &begin, &end);
+ ret = gtk_text_iter_get_slice (&begin, &end);
+ g_assert_cmpstr (ret, ==, expected);
+ g_free (ret);
+
+ g_object_unref (vim);
+ g_object_unref (view);
+}
+
+static void
+test_yank (void)
+{
+ run_test ("1\n2\n3", "yGP", "1\n2\n3\n1\n2\n3");
+ run_test ("1\n2\n3", "yGp", "1\n1\n2\n3\n2\n3");
+ run_test ("1\n2\n3", "\"zyGP", "1\n2\n3");
+ run_test ("1\n2\n3", "\"zyG\"zP", "1\n2\n3\n1\n2\n3");
+}
+
+static void
+test_insert (void)
+{
+ run_test ("line1", "o\e", "line1\n");
+ run_test ("line1", "O\e", "\nline1");
+ run_test ("", "itesting\ea this.\e", "testing this.");
+ run_test ("", "3iz\e", "zzz");
+}
+
+static void
+test_change (void)
+{
+ run_test ("word here", "ciwnot\e", "not here");
+}
+
+static void
+test_delete (void)
+{
+ run_test ("a word here.", "v$x", "");
+ run_test ("t\nt\n", "Vx", "t\n");
+ run_test ("a word here.", "vex", " here.");
+ run_test ("line1", "dd", "");
+ run_test ("line1\n", "dj", "");
+ run_test ("line1\n\n", "dj", "");
+ run_test ("1\n2\n", "d2j", "");
+ run_test ("1\n2\n", "d10j", "");
+ run_test ("1\n2\n3\n42", "vjjjx", "2");
+ run_test ("1\n2\n3\n42", "vjjjVx", "");
+ run_test ("1\n2\n3\n4", "dG", "");
+ run_test ("1\n2\n3\n42", "jmzjjd'z", "1\n");
+ run_test ("1\n2\n3\n4\n5", "4Gd1G", "5");
+ run_test ("1\n2\n3\n4\n5", ":4\nd1G", "5");
+
+#if 0
+ /* somehow VIM ignores \n before 4. */
+ run_test ("1\n22\n3\n4", "jlmzjjd`z", "1\n2\n4");
+#endif
+}
+
+static void
+test_search_and_replace (void)
+{
+ static const struct {
+ const char *command;
+ gboolean success;
+ const char *search;
+ const char *replace;
+ const char *options;
+ } parse_s_and_r[] = {
+ { "s/", TRUE, NULL, NULL, NULL },
+ { "s/a", TRUE, "a", NULL, NULL },
+ { "s/a/", TRUE, "a", NULL, NULL },
+ { "s/a/b", TRUE, "a", "b", NULL },
+ { "s/a/b/", TRUE, "a", "b", NULL },
+ { "s/a/b/c", TRUE, "a", "b", "c" },
+ { "s#a#b#c", TRUE, "a", "b", "c" },
+ { "s/^ \\//", TRUE, "^ /", NULL, NULL },
+ { "s/\\/\\/", TRUE, "//", NULL, NULL },
+ { "s/^$//gI", TRUE, "^$", "", "gI" },
+ };
+
+ for (guint i = 0; i < G_N_ELEMENTS (parse_s_and_r); i++)
+ {
+ const char *str = parse_s_and_r[i].command;
+ char *search = NULL;
+ char *replace = NULL;
+ char *options = NULL;
+ gboolean ret;
+
+ g_assert_true (*str == 's');
+
+ str++;
+ ret = gtk_source_vim_command_parse_search_and_replace (str, &search, &replace, &options);
+
+ if (!parse_s_and_r[i].success && ret)
+ {
+ g_error ("expected %s to fail, but it succeeded",
+ parse_s_and_r[i].command);
+ }
+ else if (parse_s_and_r[i].success && !ret)
+ {
+ g_error ("expected %s to pass, but it failed",
+ parse_s_and_r[i].command);
+ }
+
+ g_assert_cmpstr (search, ==, parse_s_and_r[i].search);
+ g_assert_cmpstr (replace, ==, parse_s_and_r[i].replace);
+ g_assert_cmpstr (options, ==, parse_s_and_r[i].options);
+
+ g_free (search);
+ g_free (replace);
+ g_free (options);
+ }
+
+ run_test ("test test test test", ":s/test\n", " test test test");
+ run_test ("test test test test", ":s/test/bar\n", "bar test test test");
+ run_test ("test test test test", ":s/test/bar/g\n", "bar bar bar bar");
+ run_test ("test test test test", ":s/TEST/bar/gi\n", "bar bar bar bar");
+ run_test ("test test test test", ":s/TEST/bar\n", "test test test test");
+ run_test ("t t t t\nt t t t\n", ":s/t/f\n", "f t t t\nt t t t\n");
+ run_test ("t t t t\nt t t t\n", ":%s/t/f\n", "f t t t\nf t t t\n");
+ run_test ("t t t t\nt t t t\n", ":%s/t/f/g\n", "f f f f\nf f f f\n");
+ run_test ("t t t t\nt t t t\n", ":.,$s/t/f\n", "f t t t\nf t t t\n");
+ run_test ("t t\nt t\nt t\n", ":.,+1s/t/f\n", "f t\nf t\nt t\n");
+ run_test ("t t t t\nt t t t\n", "V:s/t/f\n", "f t t t\nt t t t\n");
+ run_test ("/ / / /", ":s/\\//#/g\n", "# # # #");
+}
+
+int
+main (int argc,
+ char *argv[])
+{
+ int ret;
+
+ gtk_init ();
+ gtk_source_init ();
+ g_test_init (&argc, &argv, NULL);
+ g_test_add_func ("/GtkSourceView/vim-input/yank", test_yank);
+ g_test_add_func ("/GtkSourceView/vim-input/insert", test_insert);
+ g_test_add_func ("/GtkSourceView/vim-input/change", test_change);
+ g_test_add_func ("/GtkSourceView/vim-input/delete", test_delete);
+ g_test_add_func ("/GtkSourceView/vim-input/search-and-replace", test_search_and_replace);
+ ret = g_test_run ();
+ gtk_source_finalize ();
+ return ret;
+}
diff --git a/testsuite/test-vim-state.c b/testsuite/test-vim-state.c
new file mode 100644
index 00000000..026ed09a
--- /dev/null
+++ b/testsuite/test-vim-state.c
@@ -0,0 +1,74 @@
+/*
+ * This file is part of GtkSourceView
+ *
+ * Copyright 2021 Christian Hergert <chergert@redhat.com>
+ *
+ * GtkSourceView is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GtkSourceView is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "config.h"
+
+#include <gtksourceview/gtksource.h>
+
+#include <gtksourceview/vim/gtksourcevim.h>
+#include <gtksourceview/vim/gtksourcevimcommand.h>
+#include <gtksourceview/vim/gtksourceviminsert.h>
+#include <gtksourceview/vim/gtksourcevimnormal.h>
+#include <gtksourceview/vim/gtksourcevimstate.h>
+
+static void
+test_parents (void)
+{
+ GtkWidget *view = gtk_source_view_new ();
+ GtkSourceVim *vim = gtk_source_vim_new (GTK_SOURCE_VIEW (view));
+ GtkSourceVimState *normal = gtk_source_vim_state_get_current (GTK_SOURCE_VIM_STATE (vim));
+ GtkSourceVimState *insert = gtk_source_vim_insert_new ();
+ GtkSourceVimState *command = gtk_source_vim_command_new (":join");
+
+ gtk_source_vim_state_push (normal, g_object_ref (insert));
+ g_assert_true (normal == gtk_source_vim_state_get_parent (insert));
+
+ gtk_source_vim_state_pop (insert);
+ g_assert_true (normal == gtk_source_vim_state_get_parent (insert));
+
+ gtk_source_vim_state_push (normal, g_object_ref (command));
+ gtk_source_vim_state_pop (command);
+
+ /* Now insert should be released */
+ g_assert_finalize_object (insert);
+
+ g_assert_true (GTK_SOURCE_IS_VIM_NORMAL (normal));
+ g_object_ref (normal);
+
+ g_assert_finalize_object (vim);
+ g_assert_finalize_object (normal);
+ g_assert_finalize_object (command);
+}
+
+int
+main (int argc,
+ char *argv[])
+{
+ int ret;
+
+ gtk_init ();
+ gtk_source_init ();
+ g_test_init (&argc, &argv, NULL);
+ g_test_add_func ("/GtkSourceView/vim-state/set-parent", test_parents);
+ ret = g_test_run ();
+ gtk_source_finalize ();
+ return ret;
+}
diff --git a/testsuite/test-vim-text-object.c b/testsuite/test-vim-text-object.c
new file mode 100644
index 00000000..6fe1f86f
--- /dev/null
+++ b/testsuite/test-vim-text-object.c
@@ -0,0 +1,248 @@
+/*
+ * This file is part of GtkSourceView
+ *
+ * Copyright 2021 Christian Hergert <chergert@redhat.com>
+ *
+ * GtkSourceView is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GtkSourceView is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "config.h"
+
+#include <gtksourceview/gtksource.h>
+#include <gtksourceview/vim/gtksourcevimtextobject.h>
+
+static void
+run_test (GtkSourceVimState *text_object,
+ const char *text,
+ guint position,
+ const char *expect_selection)
+{
+ GtkSourceBuffer *buffer;
+ GtkTextIter begin, end;
+
+ g_assert (GTK_SOURCE_IS_VIM_TEXT_OBJECT (text_object));
+ g_assert (text != NULL);
+
+ buffer = gtk_source_buffer_new (NULL);
+ gtk_text_buffer_set_text (GTK_TEXT_BUFFER (buffer), text, -1);
+
+ gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (buffer), &begin, position);
+ end = begin;
+
+ if (!gtk_source_vim_text_object_select (GTK_SOURCE_VIM_TEXT_OBJECT (text_object), &begin, &end))
+ {
+ char *text_escape;
+ char *exp_escape;
+
+ if (expect_selection == NULL)
+ goto cleanup;
+
+ text_escape = g_strescape (text, NULL);
+ exp_escape = g_strescape (expect_selection, NULL);
+
+ g_error ("Selection Failed: '%s' at position %u expected '%s'",
+ text_escape, position, exp_escape);
+
+ g_free (text_escape);
+ g_free (exp_escape);
+ }
+
+ if (expect_selection == NULL)
+ {
+ char *out = gtk_text_iter_get_slice (&begin, &end);
+ char *escaped = g_strescape (out, NULL);
+ g_error ("Expected to fail selection but got '%s'", escaped);
+ g_free (escaped);
+ g_free (out);
+ }
+ else
+ {
+ char *selected_text = gtk_text_iter_get_slice (&begin, &end);
+ g_assert_cmpstr (selected_text, ==, expect_selection);
+ g_free (selected_text);
+ }
+
+cleanup:
+ g_clear_object (&buffer);
+
+ g_assert_finalize_object (text_object);
+}
+
+static void
+test_word (void)
+{
+ run_test (gtk_source_vim_text_object_new_inner_word (), "", 0, "");
+ run_test (gtk_source_vim_text_object_new_inner_word (), "this is some- text to modify\n", 8, "some");
+ run_test (gtk_source_vim_text_object_new_inner_word (), "something here\n", 10, " ");
+ run_test (gtk_source_vim_text_object_new_inner_word (), "something here", 9, " ");
+ run_test (gtk_source_vim_text_object_new_inner_word (), "a", 0, "a");
+ run_test (gtk_source_vim_text_object_new_inner_word (), "a b", 1, " ");
+ run_test (gtk_source_vim_text_object_new_inner_word (), "+ -", 1, " ");
+ run_test (gtk_source_vim_text_object_new_inner_word (), "z a", 2, "a");
+ run_test (gtk_source_vim_text_object_new_a_word (), "a b", 1, " b");
+ run_test (gtk_source_vim_text_object_new_a_word (), "+ -", 1, " -");
+ run_test (gtk_source_vim_text_object_new_a_word (), "a b", 2, "b");
+ run_test (gtk_source_vim_text_object_new_a_word (), "a b c", 2, "b ");
+ run_test (gtk_source_vim_text_object_new_inner_word (), "\n \n\n", 2, " ");
+ run_test (gtk_source_vim_text_object_new_a_word (), "\n \n\n", 2, " ");
+}
+
+static void
+test_WORD (void)
+{
+ run_test (gtk_source_vim_text_object_new_inner_WORD (), "this is some- text to modify\n", 8, "some-");
+ run_test (gtk_source_vim_text_object_new_inner_WORD (), "something here\n", 10, " ");
+ run_test (gtk_source_vim_text_object_new_inner_WORD (), "something here", 9, " ");
+ run_test (gtk_source_vim_text_object_new_inner_WORD (), "\n \n\n", 2, " ");
+ run_test (gtk_source_vim_text_object_new_a_WORD (), "\n \n\n", 2, " ");
+}
+
+static void
+test_block (void)
+{
+ run_test (gtk_source_vim_text_object_new_a_block_paren (), "this_is_a_function (some stuff\n and some more)\ntrailing", 23, "(some stuff\n and some more)");
+ run_test (gtk_source_vim_text_object_new_inner_block_paren (), "this_is_a_function (some stuff\n and some more)\ntrailing", 23, "some stuff\n and some more");
+ run_test (gtk_source_vim_text_object_new_inner_block_paren (), "(should not match\n", 5, NULL);
+ run_test (gtk_source_vim_text_object_new_inner_block_paren (), "(m)", 0, "m");
+ run_test (gtk_source_vim_text_object_new_inner_block_paren (), "(m)", 1, "m");
+ run_test (gtk_source_vim_text_object_new_inner_block_paren (), "(m)", 2, "m");
+ run_test (gtk_source_vim_text_object_new_inner_block_paren (), "(m)", 3, NULL);
+ run_test (gtk_source_vim_text_object_new_a_block_paren (), "(m)", 0, "(m)");
+ run_test (gtk_source_vim_text_object_new_a_block_paren (), "(m)", 1, "(m)");
+ run_test (gtk_source_vim_text_object_new_a_block_paren (), "(m)", 2, "(m)");
+ run_test (gtk_source_vim_text_object_new_inner_block_paren (), "(m)", 3, NULL);
+ run_test (gtk_source_vim_text_object_new_inner_block_paren (), "()", 2, NULL);
+ run_test (gtk_source_vim_text_object_new_inner_block_paren (), "()", 1, "");
+ run_test (gtk_source_vim_text_object_new_inner_block_paren (), "()", 0, "");
+ run_test (gtk_source_vim_text_object_new_a_block_paren (), "() ", 1, "()");
+ run_test (gtk_source_vim_text_object_new_a_block_paren (), "() ", 0, "()");
+ run_test (gtk_source_vim_text_object_new_a_block_lt_gt (), "<a></a>", 0, "<a>");
+ run_test (gtk_source_vim_text_object_new_inner_block_lt_gt (), "<a>", 0, "a");
+ run_test (gtk_source_vim_text_object_new_inner_block_lt_gt (), "<a>", 2, "a");
+ run_test (gtk_source_vim_text_object_new_inner_block_lt_gt (), "<a></a>", 0, "a");
+ run_test (gtk_source_vim_text_object_new_inner_block_lt_gt (), "<a></a>", 1, "a");
+ run_test (gtk_source_vim_text_object_new_inner_block_lt_gt (), "<a></a>", 2, "a");
+ run_test (gtk_source_vim_text_object_new_inner_block_lt_gt (), "<a></a>", 3, "/a");
+
+ run_test (gtk_source_vim_text_object_new_inner_block_bracket (), "[a[b[c]]]", 0, "a[b[c]]");
+ run_test (gtk_source_vim_text_object_new_inner_block_bracket (), "[a[b[c]]]", 1, "a[b[c]]");
+ run_test (gtk_source_vim_text_object_new_inner_block_bracket (), "[a[b[c]]]", 2, "b[c]");
+ run_test (gtk_source_vim_text_object_new_inner_block_bracket (), "[a[b[c]]]", 3, "b[c]");
+ run_test (gtk_source_vim_text_object_new_inner_block_bracket (), "[a[b[c]]]", 4, "c");
+ run_test (gtk_source_vim_text_object_new_inner_block_bracket (), "[a[b[c]]]", 5, "c");
+ run_test (gtk_source_vim_text_object_new_inner_block_bracket (), "[a[b[c]]]", 6, "c");
+ run_test (gtk_source_vim_text_object_new_inner_block_bracket (), "[a[b[c]]]", 7, "b[c]");
+ run_test (gtk_source_vim_text_object_new_inner_block_bracket (), "[a[b[c]]]", 8, "a[b[c]]");
+ run_test (gtk_source_vim_text_object_new_inner_block_bracket (), "[a[b[c]]]", 9, NULL);
+}
+
+static void
+test_quote (void)
+{
+ run_test (gtk_source_vim_text_object_new_inner_quote_double (), "\"this is a string.\"", 0, "this is a string.");
+ run_test (gtk_source_vim_text_object_new_a_quote_double (), "\"this is a string.\"", 0, "\"this is a string.\"");
+ run_test (gtk_source_vim_text_object_new_inner_quote_double (), "\"this is a string.\n", 0, NULL);
+ run_test (gtk_source_vim_text_object_new_inner_quote_double (), "\"this \"is a string.\"", 6, "this ");
+ run_test (gtk_source_vim_text_object_new_a_quote_double (), "\"this \"is a string.\"", 6, "\"this \"");
+ run_test (gtk_source_vim_text_object_new_inner_quote_double (), "\"this \"is a string.\"", 7, "is a string.");
+ run_test (gtk_source_vim_text_object_new_inner_quote_double (), "\"this \"is a string.", 7, NULL);
+ run_test (gtk_source_vim_text_object_new_inner_quote_double (), "\"\"", 0, "");
+ run_test (gtk_source_vim_text_object_new_inner_quote_double (), "\"\"", 1, "");
+ run_test (gtk_source_vim_text_object_new_inner_quote_double (), " \"\"", 2, "");
+ run_test (gtk_source_vim_text_object_new_inner_quote_double (), "\"\" ", 1, "");
+ run_test (gtk_source_vim_text_object_new_inner_quote_double (), "\"\" \"", 1, "");
+ run_test (gtk_source_vim_text_object_new_inner_quote_double (), "\"a\" \"", 1, "a");
+ run_test (gtk_source_vim_text_object_new_a_quote_double (), "\"\"", 0, "\"\"");
+ run_test (gtk_source_vim_text_object_new_a_quote_double (), "\"\"", 1, "\"\"");
+ run_test (gtk_source_vim_text_object_new_a_quote_double (), " \"\"", 2, "\"\"");
+ run_test (gtk_source_vim_text_object_new_a_quote_double (), "\"\" ", 1, "\"\"");
+ run_test (gtk_source_vim_text_object_new_a_quote_double (), "\"\" \"", 1, "\"\"");
+ run_test (gtk_source_vim_text_object_new_a_quote_double (), "\"a\"b\"", 2, "\"a\"");
+ run_test (gtk_source_vim_text_object_new_a_quote_double (), "\"a\"b\"", 3, "\"b\"");
+}
+
+static void
+test_sentence (void)
+{
+ run_test (gtk_source_vim_text_object_new_inner_sentence (), "a. b! c?", 0, "a.");
+ run_test (gtk_source_vim_text_object_new_inner_sentence (), "a. b! c?", 1, "a.");
+ run_test (gtk_source_vim_text_object_new_inner_sentence (), "a. b! c?", 2, "b!");
+ run_test (gtk_source_vim_text_object_new_inner_sentence (), "a. b! c?", 3, "b!");
+ run_test (gtk_source_vim_text_object_new_inner_sentence (), "a. b! c?", 4, "b!");
+ run_test (gtk_source_vim_text_object_new_inner_sentence (), "a. b! c?", 5, "c?");
+ run_test (gtk_source_vim_text_object_new_inner_sentence (), "a. b! c?", 6, "c?");
+ run_test (gtk_source_vim_text_object_new_inner_sentence (), "\n a. b! c?", 1, "a.");
+ run_test (gtk_source_vim_text_object_new_inner_sentence (), "\n a. b! c?", 2, "a.");
+
+ run_test (gtk_source_vim_text_object_new_a_sentence (), "a. b! c?", 0, "a. ");
+ run_test (gtk_source_vim_text_object_new_a_sentence (), " a. b! c?", 0, " a. ");
+ run_test (gtk_source_vim_text_object_new_a_sentence (), "\n a. b! c?", 1, "a. ");
+ run_test (gtk_source_vim_text_object_new_a_sentence (), "\n a. b! c?", 2, "a. ");
+}
+
+static void
+test_paragraph (void)
+{
+ GtkSourceVimState *temp;
+
+ run_test (gtk_source_vim_text_object_new_inner_paragraph (), "testing this.\n\n\n", 0, "testing this.");
+ run_test (gtk_source_vim_text_object_new_inner_paragraph (), "testing this.\n", 5, "testing this.");
+ run_test (gtk_source_vim_text_object_new_inner_paragraph (), "\n\n", 0, "\n\n");
+ run_test (gtk_source_vim_text_object_new_inner_paragraph (), "\n\n", 1, "\n\n");
+ run_test (gtk_source_vim_text_object_new_inner_paragraph (), "\n\n\n", 1, "\n\n\n");
+ run_test (gtk_source_vim_text_object_new_inner_paragraph (), "what\nwill\n we\n\nfind\nhere.", 1, "what\nwill\n we");
+ run_test (gtk_source_vim_text_object_new_inner_paragraph (), "\tword;\n\n\tanother;\n\n\tthird;\n", 9, "\tanother;");
+ run_test (gtk_source_vim_text_object_new_inner_paragraph (), "\tword;\n\n\tanother;\n", 7, "");
+ run_test (gtk_source_vim_text_object_new_inner_paragraph (), "\t1\n\n\t2\n\n\t3", 8, "");
+ run_test (gtk_source_vim_text_object_new_inner_paragraph (), "\n", 0, "\n");
+ run_test (gtk_source_vim_text_object_new_inner_paragraph (), "\n\na\nb\nc\n", 0, "\n");
+
+ run_test (gtk_source_vim_text_object_new_a_paragraph (), "testing this.\n\n\n", 0, "testing this.\n\n\n");
+ run_test (gtk_source_vim_text_object_new_a_paragraph (), "testing this.\n", 5, "testing this.\n");
+ run_test (gtk_source_vim_text_object_new_a_paragraph (), "\n", 0, NULL);
+ run_test (gtk_source_vim_text_object_new_a_paragraph (), "\n\n", 0, NULL);
+ run_test (gtk_source_vim_text_object_new_a_paragraph (), "\n\n", 1, NULL);
+ run_test (gtk_source_vim_text_object_new_a_paragraph (), "\n\n\n", 1, NULL);
+ run_test (gtk_source_vim_text_object_new_a_paragraph (), "what\nwill\n we\n\nfind\nhere.", 1, "what\nwill\n we\n");
+ run_test (gtk_source_vim_text_object_new_a_paragraph (), "\tword;\n\n\tanother;\n\n\tthird;\n", 9, "\tanother;\n");
+ run_test (gtk_source_vim_text_object_new_a_paragraph (), "\tword;\n\n\tanother;\n", 7, "\n\tanother;");
+ run_test (gtk_source_vim_text_object_new_a_paragraph (), "\t1\n\n\t2\n\n\t3\n", 7, "\n\t3");
+ run_test (gtk_source_vim_text_object_new_a_paragraph (), "\t1\n\n\t2\n\n\t3\n", 8, "\t3\n");
+
+ temp = gtk_source_vim_text_object_new_inner_paragraph ();
+ gtk_source_vim_state_set_count (temp, 2);
+ run_test (temp, "t\n\nt", 0, "t\n");
+}
+
+int
+main (int argc,
+ char *argv[])
+{
+ int ret;
+
+ gtk_init ();
+ gtk_source_init ();
+ g_test_init (&argc, &argv, NULL);
+ g_test_add_func ("/GtkSourceView/vim-text-object/word", test_word);
+ g_test_add_func ("/GtkSourceView/vim-text-object/WORD", test_WORD);
+ g_test_add_func ("/GtkSourceView/vim-text-object/block", test_block);
+ g_test_add_func ("/GtkSourceView/vim-text-object/quote", test_quote);
+ g_test_add_func ("/GtkSourceView/vim-text-object/sentence", test_sentence);
+ g_test_add_func ("/GtkSourceView/vim-text-object/paragraph", test_paragraph);
+ ret = g_test_run ();
+ gtk_source_finalize ();
+ return ret;
+}