[comp.emacs] gnu emacs lisp question

jimmy@pyrltd.UUCP (Jimmy Aitken) (07/18/89)

This is my first attempt at a lisp routine for GNU emacs so excuse the
sloppyness/incorrectness.  What I'm trying to do is toggle certain
vlaaues of variables/states in GNU emacs so that they can be changed
via a single keystroke rather than setting the variable manually.  I
wrote the function by looking at the code for other lisp functions in
the lisp directory of GNU.  Things seem to work OK for the readonly
funtion, but for the clt-arrow, wrap, and mode changes the effect of
changing the variable doesn't appear until I redraw the screen.  Can
anybody explain why and, more importantly, how to fix it?  Also if
there are any style improvements I'll gladly accept criticism.

many thanks,

Jimmy
Here's the code:
(defun toggle ()
  "Toggle the values of certain variables."
  (interactive)
  (message
   "toggle: srwct (control^ searchanycase readonly textmode wrap)")
  (let ((char (read-char)))
    (if (char-equal char (string-to-char "c"))
        (set 'ctl-arrow (not ctl-arrow)))
    (if (char-equal char (string-to-char "r"))
        (toggle-read-only))
    (if (char-equal char (string-to-char "s"))
        (setq case-fold-search (not case-fold-search)))
    (if (char-equal char (string-to-char "t"))
        (if (eq major-mode 'fundamental-mode)
            (text-mode)
          (fundamental-mode)))
    (if (char-equal char (string-to-char "w"))
        (setq truncate-lines (not truncate-lines)))
    ))
-- 
      -m-------  Jimmy Aitken                Phone : +44 252 373035
    ---mmm-----  Pyramid Technology Ltd      PSS   : 234248300152
  -----mmmmm---  Concept 2000, Farnboro' Rd. Telex : 859056
-------mmmmmmm-  Farnboro', Hants GU14 7NA   ...!mcvax!ukc!pyrltd!jimmy

rbj@dsys.ncsl.nist.GOV (Root Boy Jim) (07/28/89)

? From: Jimmy Aitken <mcvax!ukc!pyrltd!jimmy@uunet.uu.net>

? This is my first attempt at a lisp routine for GNU emacs so excuse the
? sloppyness/incorrectness.  What I'm trying to do is toggle certain
? vlaaues of variables/states in GNU emacs so that they can be changed
? via a single keystroke rather than setting the variable manually.  I
? wrote the function by looking at the code for other lisp functions in
? the lisp directory of GNU.  Things seem to work OK for the readonly
? funtion, but for the clt-arrow, wrap, and mode changes the effect of
? changing the variable doesn't appear until I redraw the screen.  Can
? anybody explain why and, more importantly, how to fix it?  Also if

Yeah. If you need to redraw the screen, do so in your lisp code.

? there are any style improvements I'll gladly accept criticism.

Consider these gentle criticisms of style.

? many thanks,

? Jimmy
? Here's the code:
? (defun toggle ()
?   "Toggle the values of certain variables."
?   (interactive)
?   (message
?    "toggle: srwct (control^ searchanycase readonly textmode wrap)")
?   (let ((char (read-char)))

The (let), (message), and (read-char) can be done inside (interactive):

	(defun toggle (what)
	  "Toggle ..."
	  (interactive "cToggle: ")

This has the advantage of allowing your function to be called as
(toggle ?c) from other elisp code. BTW, toggle is too generic a name

?     (if (char-equal char (string-to-char "c"))

Characters are denoted as a `?' followed by the character desired.
Thus, (if (char-equal char ?c) ...)
?\C-x is C-x, ?\M-x is M-x, ?\M-C-x is M-C-X, ?\n is \n, ?\e is ESC

In elisp, characters are numbers, and numbers can be compared with
(eq) as well as (=). But if you prefer (char-equal), that's fine,
as it will be more portable and you're saying what you mean.

This sequence of (if)'s should really be coded as a cond. A cond is a
good way to implement a case statement, which is what you are doing.
The format is

	(cond				C language equivalent
		((c1) (e1))	if (c1) { e1; } else
		((c2) (e2))	if (c2) { e2; } else
		....		...
		(t    (en))	{ en; }
	)

?         (set 'ctl-arrow (not ctl-arrow)))

Why don't you use setq instead of set? Perhaps it makes a difference
if a variable is a local one?

?     (if (char-equal char (string-to-char "r"))
?         (toggle-read-only))
?     (if (char-equal char (string-to-char "s"))
?         (setq case-fold-search (not case-fold-search)))
?     (if (char-equal char (string-to-char "t"))
?         (if (eq major-mode 'fundamental-mode)
?             (text-mode)
?           (fundamental-mode)))
?     (if (char-equal char (string-to-char "w"))
?         (setq truncate-lines (not truncate-lines)))
?     ))
? -- 
?       -m-------  Jimmy Aitken                Phone : +44 252 373035
?     ---mmm-----  Pyramid Technology Ltd      PSS   : 234248300152
?   -----mmmmm---  Concept 2000, Farnboro' Rd. Telex : 859056
? -------mmmmmmm-  Farnboro', Hants GU14 7NA   ...!mcvax!ukc!pyrltd!jimmy

	Root Boy Jim
	Have GNU, Will Travel.