diff options
author | Christian Hergert <chergert@redhat.com> | 2021-10-18 15:42:54 -0700 |
---|---|---|
committer | Christian Hergert <chergert@redhat.com> | 2021-11-11 21:36:52 -0800 |
commit | 15f4c2704131624d571f91f697811efb0567da89 (patch) | |
tree | d354aaf1d79158221e86fc1f60ba680e45367c97 /testsuite | |
parent | f9ae3c6a2e4bf119a04550ca04e7846af160e3ef (diff) | |
download | gtksourceview-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.build | 3 | ||||
-rw-r--r-- | testsuite/test-vim-input.c | 227 | ||||
-rw-r--r-- | testsuite/test-vim-state.c | 74 | ||||
-rw-r--r-- | testsuite/test-vim-text-object.c | 248 |
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; +} |