Skip to content

Commit

Permalink
Add wrap key themes
Browse files Browse the repository at this point in the history
  • Loading branch information
noctuid committed Apr 15, 2018
1 parent 4dfdbaa commit d249146
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 0 deletions.
28 changes: 28 additions & 0 deletions README.org
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,19 @@ The =slurp/barf-lispy= key theme provides commands that act the same as the defa

For both =<= bindings, if =lispyville-barf-stay-with-closing= is non-nil and barfing would move the closing delimiter behind the point, the point will instead be put on the closing delimiter.

** Wrap Key Theme
The corresponding symbol is =wrap=. The default state is normal state.

| key | command |
|-------+---------------------------------|
| =M-(= | ~lispyville-wrap-with-round~ |
| =M-[= | ~lispyville-wrap-with-brackets~ |
| =M-{= | ~lispyville-wrap-with-braces~ |

These are operators that will wrap the specified region with the corresponding delimiter. These are potentially fewer keypresses than using =evil-surround= since you do not have to specify the delimiter to use afterwards. If you use these often, you might want to bind them to something more convenient (e.g. =M-b= or =(= for ~lispyville-wrap-with-round~: =(evil-define-key 'normal lispyville-mode-map "(" 'lispyville-wrap-with-round)= if you are not using the additional movement key theme). Also note that you can wrap in lispy special (e.g. in insert state with region selected) just by pressing the delimiter. If you don't use the movement key theme in visual state (e.g. you only use it to enter lispy special), you can bind =(= to wrap only in visual state (e.g. =(evil-define-key 'visual lispyville-mode-map "(" 'lispy-parens)=; ~lispy-parens~ (which is what ~lispyville-wrap-with-round~ calls) can be used directly in this case; =v$(= would then wrap to the end of the line).

See the [[#additional-wrap-key-theme][additional wrap key theme]] for an alternative.

** Additional Key Theme
The corresponding symbol is =additional=. The default state is normal state. This key theme is the equivalent of cleverparens' "additional bindings" keys. It is currently incomplete. =M-j= is comparable to ~evil-cp-drag-forward~ and ~lispy-move-down~. =M-k= is comparable to ~evil-cp-drag-backward~ and ~lispy-move-up~.

Expand Down Expand Up @@ -192,6 +205,21 @@ The corresponding symbol is =additional-insert=. The default state is normal sta

Unlike cleverparens, these commands work only with lists. ~evil-cp-insert-at-beginning-of-form~, for example, will insert at the beginning of strings as well. To me, it is simpler and more consistent to only consider lists instead of specially handling string atoms. If you would prefer the original behavior, feel free to make an issue, and I can add alternative commands.

*** Additional Wrap Key Theme
The corresponding symbol is =additional-wrap=. The default state is normal state (to mimic cleverparens; you may want to also bind these in insert state).

| key | command |
|-------+----------------------------|
| =M-(= | ~lispyville-wrap-round~ |
| =M-[= | ~lispyville-wrap-brackets~ |
| =M-{= | ~lispyville-wrap-braces~ |

These are equivalents of ~lisp-wrap-round~, ~lispy-wrap-brackets~, and ~lispy-wrap-braces~. By default, they will wrap the sexp at the point. With a positive count, they will wrap that number of sexps. With a count of 0, they will wrap as far as possible. With a negative count, they will wrap to the sexp at the end of the line (e.g. =|foo bar= to =(|foo bar)=). If you would prefer this behavior by default, you can bind =(= to =lispy-parens-auto-wrap= in insert state (e.g. =(define-key lispy-mode-map-lispy "(" 'lispy-parens-auto-wrap)=). Also, if you would prefer to use something more generic, you can try the [[#wrap-key-theme][wrap key theme]] which provides corresponding operators instead.

Normally, lispy will insert a space after the opening delimiter when wrapping. The lispyville versions will never insert a space in normal state. When in a state in =lispyville-insert-states=, these commands will insert a space when =lispy-insert-space-after-wrap= is non-nil (the default).

Unlike cleverparens, no commands to wrap previous sexps are provided. If you would like this functionality, feel free to make an issue.

** Arrows Key Theme
The corresponding symbol is =arrows=. The default state is normal state. This key theme provides similar keybindings to those from [[https://github.com/tpope/vim-sexp-mappings-for-regular-people][vim-sexp-mappings-for-regular-people]]. It is currently incomplete.

Expand Down
22 changes: 22 additions & 0 deletions lispyville-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -698,6 +698,15 @@ character after it is not considered as part of the region."
"((a)| b (c))")))
(lispyville-set-key-theme))

(ert-deftest lispyville-wrap-with-round ()
(lispyville-set-key-theme '(wrap))
(should (string= (lispyville-with "|foo bar"
"M-( i w")
"|(foo) bar"))
(should (string= (lispyville-with "|foo bar"
"M-( $")
"|(foo bar)")))

(ert-deftest lispyville-drag-forward ()
;; region
(should (string= (lispyville-with "(~a |b c)"
Expand Down Expand Up @@ -859,6 +868,19 @@ character after it is not considered as part of the region."
"3 M-O")
"|\n\n((a))")))

(ert-deftest lispyville-wrap-round ()
;; TODO why are these failing?
;; (lispyville-set-key-theme '((additional-wrap insert normal)))
;; should never insert a space when in normal state
;; (should (string= (lispyville-with "a |b"
;; "M-(")
;; "a (|b)"))
;; should insert a space by default when in an insert state
;; (should (string= (lispyville-with "a |b"
;; "i M-(")
;; "a (| b)"))
)

;;; * Visual and Special Mark Integration
(ert-deftest lispyville-toggle-mark-type ()
(lispy-define-key lispy-mode-map "m" #'lispyville-toggle-mark-type)
Expand Down
62 changes: 62 additions & 0 deletions lispyville.el
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,25 @@ ARG has the same effect."
(lispy--normalize-1))
(goto-char orig-pos)))

;; ** Wrap Key Theme
(evil-define-operator lispyville-wrap-with-round (beg end)
"Insert ( at BEG and ) at END."
(interactive "<r>")
(lispy--mark (cons beg end))
(lispy-parens nil))

(evil-define-operator lispyville-wrap-with-brackets (beg end)
"Insert [ at BEG and ] at END."
(interactive "<r>")
(lispy--mark (cons beg end))
(lispy-brackets nil))

(evil-define-operator lispyville-wrap-with-braces (beg end)
"Insert { at BEG and } at END."
(interactive "<r>")
(lispy--mark (cons beg end))
(lispy-braces nil))

;; * Motions
;; ** Additional Movement Key Theme
(evil-define-motion lispyville-forward-sexp (count)
Expand Down Expand Up @@ -978,6 +997,37 @@ insert in between two newlines. This is the lispyville equivalent of
(insert "\n")))
(evil-change-state lispyville-preferred-state)))

;; ** Additional Wrap Key Theme
(defun lispyville-wrap-round (arg)
"Forward arg to `lispy-wrap-round'.
Never insert a space after the opening delimiter unless in a state in
`lispyville-insert-states'."
(interactive "P")
(let ((lispy-insert-space-after-wrap
(when (memq evil-state lispyville-insert-states)
lispy-insert-space-after-wrap)))
(lispy-wrap-round arg)))

(defun lispyville-wrap-brackets (arg)
"Forward ARG to `lispy-wrap-brackets'.
Never insert a space after the opening delimiter unless in a state in
`lispyville-insert-states'."
(interactive "P")
(let ((lispy-insert-space-after-wrap
(when (memq evil-state lispyville-insert-states)
lispy-insert-space-after-wrap)))
(lispy-wrap-brackets arg)))

(defun lispyville-wrap-braces (arg)
"Forward ARG to `lispy-wrap-braces'.
Never insert a space after the opening delimiter unless in a state in
`lispyville-insert-states'."
(interactive "P")
(let ((lispy-insert-space-after-wrap
(when (memq evil-state lispyville-insert-states)
lispy-insert-space-after-wrap)))
(lispy-wrap-braces arg)))

;; * Integration Between Visual State and Lispy's Special Mark State
;; ** Using Both Separately
(defun lispyville-normal-state ()
Expand Down Expand Up @@ -1207,6 +1257,12 @@ When THEME is not given, `lispville-key-theme' will be used instead."
(lispyville--define-key states
">" #'lispyville-slurp
"<" #'lispyville-barf))
(wrap
(or states (setq states 'normal))
(lispyville--define-key states
(kbd "M-(") #'lispyville-wrap-with-round
(kbd "M-[") #'lispyville-wrap-with-brackets
(kbd "M-{") #'lispyville-wrap-with-braces))
(additional
(or states (setq states 'normal))
(lispyville--define-key states
Expand All @@ -1226,6 +1282,12 @@ When THEME is not given, `lispville-key-theme' will be used instead."
(kbd "M-a") #'lispyville-insert-at-end-of-list
(kbd "M-o") #'lispyville-open-below-list
(kbd "M-O") #'lispyville-open-above-list))
(additional-wrap
(or states (setq states 'normal))
(lispyville--define-key states
(kbd "M-(") #'lispyville-wrap-round
(kbd "M-[") #'lispyyville-wrap-brackets
(kbd "M-{") #'lispyville-wrap-braces))
(arrows
(or states (setq states 'normal))
(lispyville--define-key states
Expand Down

0 comments on commit d249146

Please sign in to comment.