Skip to content

Commit

Permalink
vi-mode: Add paragraph text object (#1740)
Browse files Browse the repository at this point in the history
* vi-mode: Add paragraph text object

* Add missing declare ignore
  • Loading branch information
Encryptoid authored Jan 9, 2025
1 parent 0d2ce9f commit b59ec3b
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 6 deletions.
2 changes: 2 additions & 0 deletions extensions/vi-mode/binds.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@
(define-key *inner-text-objects-keymap* "(" 'vi-inner-paren)
(define-key *inner-text-objects-keymap* ")" 'vi-inner-paren)
(define-key *inner-text-objects-keymap* "b" 'vi-inner-paren)
(define-key *outer-text-objects-keymap* "p" 'vi-a-paragraph)
(define-key *inner-text-objects-keymap* "p" 'vi-inner-paragraph)

(setf (gethash (lem:make-key :sym "a") (keymap-table *operator-keymap*))
(keymap-table *outer-text-objects-keymap*))
Expand Down
10 changes: 10 additions & 0 deletions extensions/vi-mode/commands.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@
:vi-inner-double-quote
:vi-a-paren
:vi-inner-paren
:vi-a-paragraph
:vi-inner-paragraph
:vi-repeat
:vi-normal
:vi-keyboard-quit
Expand Down Expand Up @@ -1101,6 +1103,14 @@ on the same line or at eol if there are none."
(:expand-selection t)
(inner-range-of 'paren-object (current-state) count))

(define-text-object-command vi-a-paragraph (count) ("p")
(:expand-selection t)
(a-range-of 'paragraph-object (current-state) count))

(define-text-object-command vi-inner-paragraph (count) ("p")
(:expand-selection t)
(inner-range-of 'paragraph-object (current-state) count))

(define-command vi-normal () ()
(change-state 'normal))

Expand Down
9 changes: 9 additions & 0 deletions extensions/vi-mode/tests/text-objects.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,12 @@
(cmd "va\"")
(ok (buf= " <\"foo\" [ ]>\"bar\""))))))

(deftest paragraph-object
(with-fake-interface ()
(with-vi-buffer (#?" \n \n f[o]o \n bar \n \n \n")
(cmd "vip")
(ok (buf= #?" \n \n< foo \n bar [\n]> \n \n")))
(with-vi-buffer (#?" \n \n f[o]o \n bar \n \n \n")
(cmd "vap")
(ok (buf= #?" \n \n< foo \n bar \n \n [\n]>")))))

43 changes: 37 additions & 6 deletions extensions/vi-mode/text-objects.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
:word-object
:broad-word-object
:paren-object
:paragraph-object
:double-quoted-object
:vi-operator-surrounding-blanks))
(in-package :lem-vi-mode/text-objects)
Expand Down Expand Up @@ -292,13 +293,13 @@
;; No quote-char found
((null prev-char)
(keyboard-quit))

;; Skip escape & quote-char
((and escape-char
((and escape-char
(character-at point -2) ;; Bound check
(char= (character-at point -2) escape-char))
(character-offset point -2))

;; Successfully found unescaped quote
(t
(character-offset point -1)
Expand All @@ -311,13 +312,13 @@
;; No quote-char found
((null next-char)
(keyboard-quit))

;; Skip escape & quote-char
((and escape-char
(character-at point 2) ;; Bound Check
(char= (character-at point -1) escape-char))
(character-offset point 2))
(character-offset point 2))

;; Successfully found
(t
(character-offset point 1)
Expand Down Expand Up @@ -392,3 +393,33 @@
(defclass double-quoted-object (quoted-text-object) ()
(:default-initargs
:quote-char #\"))

;;
;; paragraph-object
(defclass paragraph-object (text-object) ())

(defmethod inner-range-of ((object paragraph-object) state count)
(declare (ignore state count))
(with-point ((start (current-point))
(end (current-point)))
;; Start
(loop until (or (start-buffer-p start)
(blank-line-p start))
do (line-offset start -1))
(when (blank-line-p start) ;; pull back into paragraph
(line-offset start 1))

;; End
(loop until (or (end-buffer-p end)
(blank-line-p end))
do (line-offset end 1))
(make-range start end)))

;; adds on additional blank lines for inner paragraph-object
(defmethod a-range-of ((object paragraph-object) state count)
(let ((range (inner-range-of 'paragraph-object state count)))
(line-offset (range-end range) 1)
(loop until (or (end-buffer-p (range-end range))
(not (blank-line-p (range-end range))))
do (line-offset (range-end range) 1))
range))

0 comments on commit b59ec3b

Please sign in to comment.