diff --git a/extensions/vi-mode/README.md b/extensions/vi-mode/README.md index 9430de968..8e91b9560 100644 --- a/extensions/vi-mode/README.md +++ b/extensions/vi-mode/README.md @@ -20,6 +20,27 @@ To enable, add the following code to `~/.lem/init.lisp`: (define-key lem-vi-mode:*insert-keymap* ")" 'paredit-close-parenthesis) ``` +## User Settings + +### vi-operator-surrounding-blanks + +This is an editor variable that allows capturing the surround blanks (Space/Tab) in operator pending mode (eg da", ya", va")) +This currently only works for double quotes. This feature is not in vanilla vi/vim. + +```common-lisp To enable this variable: +(setf (variable-value 'lem-vi-mode/text-objects:vi-operator-surrounding-blanks :global) t) +``` + +#### Example + +``` +"cursor inside these quotes" "but not inside these" +``` +Here va" will select inside < >: +``` +<"cursor inside these quotes" >"but not inside these" +``` + ## Options Vi-mode options are global settings, similarly to Vim. diff --git a/extensions/vi-mode/tests/text-objects.lisp b/extensions/vi-mode/tests/text-objects.lisp index c63190d30..20b6156fa 100644 --- a/extensions/vi-mode/tests/text-objects.lisp +++ b/extensions/vi-mode/tests/text-objects.lisp @@ -27,39 +27,52 @@ ))) (deftest double-quoted + (with-global-variable-value (lem-vi-mode/text-objects:vi-operator-surrounding-blanks t) + (with-fake-interface () + (with-vi-buffer ("[ ]\"foo\" \"bar\"") + (cmd "va\"") + (ok (buf= " <\"foo\"[ ]>\"bar\""))) + (with-vi-buffer (" [\"]foo\" \"bar\"") + (cmd "va\"") + (ok (buf= " <\"foo\"[ ]>\"bar\""))) + (with-vi-buffer (" \"f[o]o\" \"bar\"") + (cmd "va\"") + (ok (buf= " <\"foo\"[ ]>\"bar\""))) + (with-vi-buffer (" \"foo[\"] \"bar\"") + (cmd "va\"") + (ok (buf= " <\"foo\"[ ]>\"bar\""))) + (with-vi-buffer (" \"foo\"[ ]\"bar\"") + (cmd "va\"") + ;; NOTE: This behavior is not same as Vim + (ok (buf= " \"foo\"< \"bar[\"]>"))) + (with-vi-buffer (" \"foo\" \"bar[\"]") + (cmd "va\"") + (ok (buf= " \"foo\"< \"bar[\"]>"))) + + ;; Escape Character + ; v i + (with-vi-buffer (" \" f[o]o \\\" bar \"") + (cmd "vi\"") + (ok (buf= " \"< foo \\\" bar[ ]>\""))) + (with-vi-buffer (" \" foo \\\" b[a]r \"") + (cmd "vi\"") + (ok (buf= " \"< foo \\\" bar[ ]>\""))) + ; v a + (with-vi-buffer (" \" f[o]o \\\" bar \"") + (cmd "va\"") + (ok (buf= " <\" foo \\\" bar [\"]>"))) + (with-vi-buffer (" \" foo \\\" b[a]r \"") + (cmd "va\"") + (ok (buf= " <\" foo \\\" bar [\"]>")))))) + +(deftest vi-operator-surrounding-blanks (with-fake-interface () - (with-vi-buffer ("[ ]\"foo\" \"bar\"") - (cmd "va\"") - (ok (buf= " <\"foo\"[ ]>\"bar\""))) - (with-vi-buffer (" [\"]foo\" \"bar\"") - (cmd "va\"") - (ok (buf= " <\"foo\"[ ]>\"bar\""))) - (with-vi-buffer (" \"f[o]o\" \"bar\"") - (cmd "va\"") - (ok (buf= " <\"foo\"[ ]>\"bar\""))) - (with-vi-buffer (" \"foo[\"] \"bar\"") - (cmd "va\"") - (ok (buf= " <\"foo\"[ ]>\"bar\""))) - (with-vi-buffer (" \"foo\"[ ]\"bar\"") - (cmd "va\"") - ;; NOTE: This behavior is not same as Vim - (ok (buf= " \"foo\"< \"bar[\"]>"))) - (with-vi-buffer (" \"foo\" \"bar[\"]") - (cmd "va\"") - (ok (buf= " \"foo\"< \"bar[\"]>"))) + (with-global-variable-value (lem-vi-mode/text-objects:vi-operator-surrounding-blanks nil) + (with-vi-buffer (" \"f[o]o\" \"bar\"") + (cmd "va\"") + (ok (buf= " <\"foo[\"]> \"bar\"")))) + (with-global-variable-value (lem-vi-mode/text-objects:vi-operator-surrounding-blanks t) + (with-vi-buffer (" \"f[o]o\" \"bar\"") + (cmd "va\"") + (ok (buf= " <\"foo\" [ ]>\"bar\"")))))) - ;; Escape Character - ; v i - (with-vi-buffer (" \" f[o]o \\\" bar \"") - (cmd "vi\"") - (ok (buf= " \"< foo \\\" bar[ ]>\""))) - (with-vi-buffer (" \" foo \\\" b[a]r \"") - (cmd "vi\"") - (ok (buf= " \"< foo \\\" bar[ ]>\""))) - ; v a - (with-vi-buffer (" \" f[o]o \\\" bar \"") - (cmd "va\"") - (ok (buf= " <\" foo \\\" bar [\"]>"))) - (with-vi-buffer (" \" foo \\\" b[a]r \"") - (cmd "va\"") - (ok (buf= " <\" foo \\\" bar [\"]>"))))) diff --git a/extensions/vi-mode/text-objects.lisp b/extensions/vi-mode/text-objects.lisp index aab0ccc05..688b2dd61 100644 --- a/extensions/vi-mode/text-objects.lisp +++ b/extensions/vi-mode/text-objects.lisp @@ -25,9 +25,12 @@ :word-object :broad-word-object :paren-object - :double-quoted-object)) + :double-quoted-object + :vi-operator-surrounding-blanks)) (in-package :lem-vi-mode/text-objects) +(define-editor-variable vi-operator-surrounding-blanks nil) + (defclass text-object () ()) (defgeneric a-range-of (object state count) @@ -328,8 +331,9 @@ range)) (defmethod include-surrounding-blanks ((object quoted-text-object) beg end direction on-object) + (when (variable-value 'vi-operator-surrounding-blanks) ;; Trailing first - (or (/= 0 (if (eq direction :backward) + (or (/= 0 (if (eq direction :backward) (skip-chars-backward end '(#\Space #\Tab)) (skip-chars-forward end '(#\Space #\Tab)))) ;; If no trailing spaces, delete leading spaces unless it's the beginning indentation @@ -343,7 +347,7 @@ (progn (skip-chars-backward p '(#\Space #\Tab)) (unless (zerop (point-charpos p)) - (move-point beg p))))))) + (move-point beg p)))))))) ;; ;; word-object