Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In emacs, can I get comment-region to use a block comment instead of commenting each line?

Tags:

emacs

xml

I have an XML file; opens in nxml-mode in emacs 23.2.

would like comment-region to comment the region as a block, rather than comment each line in the region. It makes for a more readable commented section, in my opinion.

Before:

enter image description here

After `comment-region':

enter image description here

Desired After:

enter image description here

In curly-brace languages like JavaScript and Java, comment-region comments each line, but I find this ok, because it uses the one-line comment prefix, // , which preserves the readability of what follows. For XML I'd like it to be different.


Edit:

I just saw Trey's old answer regarding a similar question for c-mode: Emacs comment-region in C mode Basically there's a new module called newcomment.el which defines a bunch of commenting styles.

This looks promising, but it is not fully sorted with nxml-mode. For example, when I tried box-multi as a style, the commented section looked good but C-u comment-region did not reverse what had been added. :/ Likewise with box style. I'll fiddle around with it some more.


Edit #2

Here's the code I used, thanks to Alex Ott.

(defun dino-xml-comment-region (beg end &optional arg)
  (interactive "*r\nP")
  (if (> beg end)
      (let (tmp) (setq tmp beg beg end end tmp)))
  (save-excursion
    (save-restriction
      (narrow-to-region beg end)
      (goto-char (point-min))
      (cond
       ;; is there a C-u prefix?
       ((and (listp arg) (> (length arg) 0))
        (and (re-search-forward "<!-- *[\n\r]" nil t)
             (goto-char (- (point-max) 1))
             (re-search-backward " *-->" nil t)
             (goto-char (point-min))
             (progn
               (re-search-forward "<!-- *[\n\r]" nil t)
               (replace-match "")
               (goto-char (- (point-max) 1))
               (re-search-backward "[\n\r] *-->" nil t)
               (replace-match ""))))

       (t
        (insert "<!--\n")
        (goto-char (- (point-max) 1))
        (unless (= 10 (following-char))
          (forward-char))
        (insert "\n-->"))))))

Then, in my nxml-mode-fn, I did this:

(local-set-key "\C-c\C-c"  'dino-xml-comment-region)

Actual behavior: enter image description here

Be careful, though: this is completely naive and does not try to "escape" intervening comment starts and stops within the region. If anyone feels the urge to add that to the code above, I'd appreciate it but I won't worry about it further myself.

like image 573
Cheeso Avatar asked Nov 02 '22 20:11

Cheeso


2 Answers

It could be something like:

(defun xml-comment-region (beg end &optional arg)
  (interactive "*r\nP")
  (if (> beg end)
      (let (mid) (setq mid beg beg end end mid)))
  (save-excursion
    (save-restriction
      (narrow-to-region beg end)
      (goto-char (point-min))
      (insert "<!-- ")
      (goto-char (- (point-max) 1))
      (unless (= 10 (following-char))
    (forward-char))
      (insert " -->"))))

bound it to any key in xml-mode hook...

like image 57
Alex Ott Avatar answered Nov 14 '22 20:11

Alex Ott


You might get some mileage out of something like

(add-hook 'nxml-mode-hook
          (lambda ()
            (set (make-local-variable 'comment-style) 'multi-line)
            (set (make-local-variable 'comment-continue) " ")))
like image 27
Stefan Avatar answered Nov 14 '22 21:11

Stefan