If you just want to solution, scroll down.
The problem with this function is that function that uncomments a region
doesn't work if commented block is indented. The solution is to modify the
original indent-region so that it removes leading whitespace before
uncommenting the lines. Also global-set-key doesn't work (at least for me)
because jde keybinding override global keybindings.
Step 1:
put following two functions in your .emacs file or preferably in a
separate file (and put (load-file "separate_file") in your .emacs)
(defun comment-region (beg end &optional arg)
"Comment or uncomment each line in the region.
With just C-u prefix arg, uncomment each line in region. If there's
any whitespace before the comment, it is removed before uncommenting.
Numeric prefix arg ARG means use ARG comment characters.
If ARG is negative, delete that many comment characters instead.
Comments are terminated on each line, even for syntax in which newline
does
not end the comment. Blank lines do not get comments."
;; if someone wants it to only put a comment-start at the beginning and
;; comment-end at the end then typing it, C-x C-x, closing it, C-x C-x
;; is easy enough. No option is made here for other than commenting
;; every line.
(interactive "r\nP")
(or comment-start (error "No comment syntax is defined"))
(if (> beg end) (let (mid) (setq mid beg beg end end mid)))
(save-excursion
(save-restriction
(let ((cs comment-start) (ce comment-end)
(cp (when comment-padding
(make-string comment-padding ? )))
numarg)
(if (consp arg) (setq numarg t)
(setq numarg (prefix-numeric-value arg))
;; For positive arg > 1, replicate the comment delims now,
;; then insert the replicated strings just once.
(while (> numarg 1)
(setq cs (concat cs comment-start)
ce (concat ce comment-end))
(setq numarg (1- numarg))))
;; Loop over all lines from BEG to END.
(narrow-to-region beg end)
(goto-char beg)
(if (or (eq numarg t) (< numarg 0))
(while (not (eobp))
(let (found-comment)
;; Delete any leading space before comment
(delete-horizontal-space)
;; Delete comment start from beginning of line.
(if (eq numarg t)
(while (looking-at (regexp-quote cs))
(setq found-comment t)
(delete-char (length cs)))
(let ((count numarg))
(while (and (> 1 (setq count (1+ count)))
(looking-at (regexp-quote cs)))
(setq found-comment t)
(delete-char (length cs)))))
;; Delete comment padding from beginning of line
(when (and found-comment comment-padding
(looking-at (regexp-quote cp)))
(delete-char comment-padding))
;; Delete comment end from end of line.
(if (string= "" ce)
nil
(if (eq numarg t)
(progn
(end-of-line)
;; This is questionable if comment-end ends in
;; whitespace. That is pretty brain-damaged,
;; though.
(while (progn (skip-chars-backward " \t")
(and (>= (- (point) (point-min))
(length ce))
(save-excursion
(backward-char (length ce))
(looking-at (regexp-quote
ce)))))
(delete-char (- (length ce)))))
(let ((count numarg))
(while (> 1 (setq count (1+ count)))
(end-of-line)
;; this is questionable if comment-end ends in
whitespace
;; that is pretty brain-damaged though
(skip-chars-backward " \t")
(if (>= (- (point) (point-min)) (length ce))
(save-excursion
(backward-char (length ce))
(if (looking-at (regexp-quote ce))
(delete-char (length ce)))))))))
(forward-line 1)))
(when comment-padding
(setq cs (concat cs cp)))
(while (not (eobp))
;; Insert at beginning and at end.
(if (looking-at "[ \t]*$") ()
(insert cs)
(if (string= "" ce) ()
(end-of-line)
(insert ce)))
(search-forward "\n" nil 'move)))))))
(defun comment-and-indent-region (beg end &optional arg)
"Runs comment-region and then indent-region on a region"
(interactive "r\nP")
(if (null arg)
(comment-region beg end)
(comment-region beg end arg))
(indent-region beg end nil))
Step 2 -- get the function comment-and-indent-region to run on C-cC-c in
JDE -- put something like the following in your emacs file
(defun my-jde-mode-hook ()
(local-set-key [(control c) (control c)] (quote
comment-and-indent-region))
(add-hook 'jde-mode-hook 'my-jde-mode-hook)
Now \C-c\C-c will comment and indent region, and \C-u\C-c\C-c will
uncomment and indent it again.
Hope this helps
Yaroslav
On Tue, 29 Aug 2000, Kevin Seguin wrote:
> can't say i'm 100% sure what this does, but it works:
>
> (global-set-key [(control c) (c)]
> (lambda()
> (interactive)
> (comment-region (region-beginning) (region-end) '(4))
> (c-region-is-active-p)))
>
> i believe i copied the lisp that uncomments of the cc-mode library (it's the
> code behind the uncomment menu item in your c/c++/java menu).
>
> > -----Original Message-----
> > From: Yaroslav Bulatov [mailto:[EMAIL PROTECTED]]
> > Sent: Tuesday, August 29, 2000 9:24 PM
> > To: Taber H. Smith
> > Cc: Jde@Sunsite. Auc. Dk
> > Subject: Re: Auto-indentation of commented region?
> >
> >
> > The proper way is to do it through Lisp. I wrote a function
> > that tries to
> > accomplish this:
> >
> > (defun comment-and-indent-region (beg end &optional arg)
> > "Runs comment-region and then indent-region on a region"
> > (interactive "r\nP")
> > (if (null arg)
> > (comment-region beg end)
> > (comment-region beg end arg))
> > (indent-region beg end nil))
> >
> > Just put it in your .emacs file and bind it to \C-c\C-c.
> > The problem with it is that it works only one way.
> > It doesn't work to uncomment the code because uncommenting
> > will only work
> > if line starts with a comment, so I would have to remove whitespace on
> > every line in selection, and that's beyond my current
> > knowledge of Lisp.
> > Perhaps somebody on this mailing list is good enough with
> > lisp to solve
> > this problem?
> >
> > Yaroslav
> >
> > On Tue, 29 Aug 2000, Taber H. Smith wrote:
> >
> > > Hi,
> > >
> > > I'm wondering if there is a way to automatically
> > > indent a region that has just been commented out, i.e.
> > >
> > > mark region
> > > C-c C-c
> > >
> > > then automatically run
> > > C-x indent-region
> > >
> > > Also, after you uncomment out a region, it would be
> > > nice if the jde automatically indented the uncommented region.
> > >
> > > Any suggestions?
> > >
> > > Thanks!
> > > Taber
> > >
> > >
> >
>