smartparens icon indicating copy to clipboard operation
smartparens copied to clipboard

How to comment out sexps and stay balanced?

Open TLINDEN opened this issue 5 years ago • 7 comments

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.

TLINDEN avatar Nov 17 '18 10:11 TLINDEN

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)

TLINDEN avatar Nov 17 '18 11:11 TLINDEN

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.

Fuco1 avatar Nov 17 '18 11:11 Fuco1

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-;.

TLINDEN avatar Nov 17 '18 15:11 TLINDEN

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)          ;|

andreyorst avatar Oct 15 '20 16:10 andreyorst

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:.

Fuco1 avatar Oct 16 '20 09:10 Fuco1

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).

andreyorst avatar Oct 17 '20 08:10 andreyorst

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).

Fuco1 avatar Oct 19 '20 20:10 Fuco1