smartparens
smartparens copied to clipboard
How to comment out sexps and stay balanced?
Expected behavior
With paredit I could enter a ;
in front of a sexp which then commented out the whole sexp not just the line, it even inserted newlines if needed to keep parantheses balanced.
Example (Cursor is |
):
|(defun blah()
(message "blah"))
After entering ;
;|(defun blah()
; (message "blah"))
Actual behavior
I get this after entering ;
;|(defun blah()
(message "blah"))
Now I have unbalanced parentheses in my code.
Steps to reproduce the problem
Pretty default config, strict mode disabled.
Environment & version information
-
smartparens
version: git (I didn't find any version string in the sp code base) - Active major-mode: emacs-lisp-mode
- Emacs version (
M-x emacs-version
): 25.3.2 - Spacemacs/Evil/Other starterkit (specify which)/Vanilla: vanilla
- OS: LInux
Update
I tried to revert my config to a pre-smartparens version but I am still unable to reproduce the old behavoir. So it might be that this was no paredit feature but something else I had enabled previously and lost when switching to smartparens. However, I would love it, if there were a feature like this in smartparens.
I wrote a little function which demonstrates it:
(defun tvd-lisp-comment ()
(interactive)
(if (not (looking-at "\("))
(self-insert-command 1)
(let ((beg (point)))
(forward-list 1)
(when (looking-at "\(")
(insert "\n"))
(comment-region beg (point))
(indent-for-tab-command)
(goto-char beg))))
(define-key smartparens-mode-map (kbd ";") 'tvd-lisp-comment)
There is sp-comment
, but it behaves a little bit differently. You can try it out and see if it works for you
I think the paredit behaviour might make a bit more sense, but it is what it is. What I use is I select the sexp and then I call comment-dwim
.
We can add a variant that behaves closer than paredit.
Hm, sp-comment
doesn't do this, it only seems to insert a ;
wherever I am.
The other way you described seems to work very good but it requires the additional step of marking and hitting M-;
.
I think that it is safe to map ; to sp-comment
in all Lisp related modes in default Smartparens config. Paredit does this, and I think most users actually expect it to work this way as well.
And it seems that sp-comment
works the same as paredit-semicolon
in all cases defined in Paredit documentation:
|(frob grovel)
->
;|(frob grovel)
(frob |grovel)
->
(frob ;|grovel
)
(frob |grovel (bloit
zargh))
->
(frob ;|grovel
(bloit
zargh))
(frob grovel) |
->
(frob grovel) ;|
Personally I'm not a huge fan, I never got used to it. The function only exists because some users asked for it as we didn't aim to emulate paredit completely from the start and the default settings are somewhat more "mainstream".
So I'm not sure if making this default after 8+ years is a good idea :blush:.
Hmm, maybe there's a way of doing this for all lisp modes and other related modes, like REPL modes without breaking Smartparens?
Currently I bind this key in smartparens-strict-mode-map
because I only use strict mode in Lisp related modes, including: clojure-mode
, emacs-lisp-mode
, common-lisp-mode
, scheme-mode
, lisp-mode
, racket-mode
, fennel-mode
, cider-repl-mode
, racket-repl-mode
, and geiser-repl-mode
. Not all of these modes have a *-mode-map
, so I'm unsure how would I approach such thing without binding strict mode map, which makes it impossible for me to use strict mode in non Lisp modes, and as a consequence in lisps that use something other then a semicolon as a comment char (although I've never seen one).
Well, it's the same issue. You can bind to a minor mode map but not based on a major mode. So even if we bind ;
to sp-comment
in smartparens-mode-map it will affect also c-mode
which we definitely don't want.
As you mention with the strict mode map, it's the same issue.
Paredit was from the start ment only for lisp and so they just went ahead and did it. But we can't.
What we can do is create another minor mode, something like smartparens-lisp-minor-mode
where we would bind some additional keys and enable it for the list of lisp modes (either as a global minor mode or each user can do it themselves by iterating over that variable).