How do you comment out all or part of a Lisp s-exp

2019-02-04 14:19发布

When editing Lisp code, occasionally it's useful to entirely comment out a top-level definition, like this:

;(defun some-fn-which-is-broken (x)
;  ...)

... or comment out only part of an s-expression, like this:

(foo x
;    y
     z)

... and then recompile the file and test something in the REPL, etc.

With paredit-mode enabled, this doesn't work. Here's what happens, if the point is right before the first paren below:

(defun some-fn (x)
  ...)

and you type a semicolon, what is entered is a semicolon and a newline:

;
(defun some-fn (x)
  ...)

Same with commenting out part of the s-expression:

(foo x
;    
     y
     z)

I think that if the definition is all on one line, this works:

;(defparameter *foo* 10)

... but otherwise I can't find out how to do this. Paredit is great, I would really like to keep using it. Are there any Lispers who know a way around this, or Emacs-wizards who can whip up a bit of Emacs Lisp to bind to something like paredit-comment-out-s-expr?

If there is a more Lispy or Emacsy way of accomplishing essentially the same thing, commenting out parts of source to recompile, please, don't hesitate to suggest them!

4条回答
老娘就宠你
2楼-- · 2019-02-04 14:59

You can use C-M-SPC M-; to mark the S-expression (C-M-SPC for mark-sexp) and then comment it (M-; for comment-dwim).

In paredit 23, just typing ; won't push anything it doesn't have to off the line. So it will do the right thing for your second example. And if you wanted to comment out z instead of y it would push only the closing delimiter to another line.

查看更多
干净又极端
3楼-- · 2019-02-04 15:00

As a stopgap measure, you can use C-q (quoted-insert) to insert an arbitrary character without triggering any mode-related magic. For example, in java-mode, typing parentheses reindents the current line, which is not always what I want; in such cases, I'll insert a parenthesis with C-q to preserve my indentation. (Or more often, I'll type a parenthesis, observe the indentation change, curse, undo, and re-enter with C-q.)

For commenting in general, it would probably be easier to use M-; (comment-dwim) rather than typing the semicolons manually.

查看更多
爷、活的狠高调
4楼-- · 2019-02-04 15:04

Just a side note:

The #+ and #- reader macros are pretty nice for commenting out sexps. They allow ignoring the following sexp, if the given symbol isn't/is found in *FEATURES*. Just pick a symbol not in *FEATURES*, and use it with #+ like this:

#+nil
(defun foo ()
  ...)

Now, the function definition will be ignored (unless NIL is in *FEATURES*, which is not very likely).

查看更多
迷人小祖宗
5楼-- · 2019-02-04 15:10

Position the point on the first character of the whole sexp, mark the whole sexp with C-M-space, and issue M-; to do the commenting. If it is necessary to do so, your source code will also be re-formatted so that only the sexp you marked, and nothing that was also on the same line, is in a comment.

You can very easily make a simple command or even a macro to do that:

(defun comment-sexp ()
  "Comment out the sexp at point."
  (interactive)
  (save-excursion
    (mark-sexp)
    (paredit-comment-dwim)))
查看更多
登录 后发表回答