Emacs customization woes... HELP!

The SDMB may not be the ideal place to ask questions about emacs, so I’m also wondering if anybody knows of any forums (or whatever) where I can get help with emacs – a place where you can ask stupid new questions, but also get complex technical help if necessary.

Anyway, so I just started using emacs, and I’m mainly using the Windows version (the ‘version’ command says “GNU Emacs 21.3.1 (i386-mingw-nt5.1.2600) of 2004-03-10 on NYAUMO”, for whatever that’s worth).

I’ve been reading the GNU Emacs Manual, the Introduction to Emacs Lisp Programming, and the GNU Emacs Lisp Reference Manual, (warning – all those links are to the manuals that include the entire manual on one HTML page, which is handy for searching but takes a long time to load – here are links to other versions of the GNU Emacs Manual, the Introduction to Emacs Lisp Programming, and the GNU Emacs Lisp Reference Manual, in case you don’t want to open those up as one big file), and I still can’t quite figure out what I’m doing wrong.

See, I’m trying to write a lisp function that I can bind to the key ctrl-shift-c that will do the following:

  • If there’s a selected region, it should comment out the region.
  • If there’s no selected region, it should comment out the line.

The “comment-dwim” function is almost what I want, but instead of commenting out the line if there’s no region selected, it just starts a new comment after the existing line comments – so you can explain that line in the comment, or whatever.

I wrote a lisp function that I think should work, but I can’t figure out how to make it work. Every time I try to run it, it gives me bizarre errors filled with garbage characters. The function, which I wrote in my .emacs file, is:



(defun my-corul ()      ;; function definition
  "If region is set, [un]comments it. Otherwise [un]comments current line."   ;; description for help file
  (interactive)  ;; apparently I need this line so it can move the cursor
  (if (eq mark-active nil)  ;; if the variable "mark-active" is nil, there's no region active
	(progn  ;; if it is indeed nil, execute the following commands
	  (beginning-of-line)  ;; go to beginning of current line
	  (set-mark (point))  ;; set the mark there
	  (next-line))  ;; go down one line
	  (comment-dwim))  ;; comment that region (i.e., previous line), end the "mark is nil" sequence of commands
      (comment-dwim)  ;; else, just comment the region
))  ;; end function


But when I run that, regardless of whether a region is defined or not, I get:


progn: Wrong number of arguments: #[(arg) "<two lines of garbage characters here>" [next-line-add-newlines arg abbrev-mode 1 nil "
" line-move (line-move arg) (((beginning-of-buffer end-of-buffer) (ding)))] 3 1337315 "p"], 0


That error, or a similar “wrong number of arguments” error, seems to come up regardless of what variations I try (although if I eliminate the “(progn” part, it just tells me “if: Invalid function: (beginning-of-line)” instead. Huh.

So while trying to figure this out, I found this lisp file, which is called “comment-uncomment-line-or-region.el”, which seems to be what I want. But I don’t know how to make this work. I tried hitting alt-x and running the command “load-library comment-uncomment-line-or-region.el”, and it loads it and says “Done”, but when I try to actually execute the command comment-uncomment-line-or-region (or bind it to a key and hit the key), it tells me “comment-uncomment-line-or-region: Symbol’s function definition is void: comment-normalize-vars.”

I grepped the c:\emacs\lisp directory and found that function defined in newcomment.el, so I did “load-library newcomment.el” and tried it again.

Now it says “comment-uncomment-line-or-region: Symbol’s function definition is void: comment-normalize-vars”. ARGH!

Any help, no matter how stupid it makes me feel when the answer turns out to be my … uh … stupidness … will be greatly appreciated.

My preferred emacs lisp programming style is “poke it until it does what I want, and then forget about it,” so, while I can’t say exactly what was going on with your code segment, I think this does what you want:


(defun my-corul ()      ;; function definition
  "If region is set, [un]comments it. Otherwise [un]comments current line."   ;; description for help file
  (interactive)  ;; apparently I need this line so it can move the cursor
  (save-excursion  ;; don't mess with mark
    (if (eq mark-active nil)  ;; if the variable "mark-active" is nil, there's no region active
	(progn (beginning-of-line)  ;; go to beginning of current line
	       (set-mark (point))  ;; set the mark there
	       (next-line 1)))  ;; go down one line
    (comment-dwim nil)  ;;  [un]comment
    (deactivate-mark nil))) ;; don't mess with selection

My best guess is that in the previously posted definition, something was trying to extract an argument from the selected region. Any deeper analysis, though, would violate the “and then forget about it” clause of my creed.

I’m not aware of any forums regarding e-lisp programming, but I haven’t looked either.

Thanks Kyrie – I modified yours very slightly and got it to work for me. The main difference was that I deleted the “save-excursion” function, because I actually want it to end up on the next line; that way I could just hit the key repeatedly to comment multiple lines one after another. Oh, and I had to add the 1 after “beginning-of-line” or it complained about arguments still.

Here’s what I got to work:


(defun my-corul ()      ;; function definition
  "If region is set, [un]comments it. Otherwise [un]comments current line."   ;; description for help file
  (interactive)  ;; apparently I need this line so it can move the cursor
;;  (save-excursion  ;; don't mess with mark
    (if (eq mark-active nil)  ;; if the variable "mark-active" is nil, there's no region active
	(progn (beginning-of-line 1)  ;; go to beginning of current line
	       (set-mark (point))  ;; set the mark there
	       (next-line 1)
	       (comment-dwim nil))  ;; go down one line
    (comment-dwim nil))  ;;  [un]comment
    (deactivate-mark)) ;; don't mess with selection


Thanks for your help. I would never have figured it out otherwise.