help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: elisp exercise: toggle-letter-case


From: Xah
Subject: Re: elisp exercise: toggle-letter-case
Date: Sat, 18 Oct 2008 13:50:30 -0700 (PDT)
User-agent: G2/1.0

Here's the improved version borrowing Andreas and Nikolaj's ideas.

(defun toggle-letter-case ()
  "Toggle the letter case of current word or text selection.
Toggles from 3 cases: UPPER CASE, lower case, Title Case,
in that cyclic order."
(interactive)

(let (pos1 pos2 (deactivate-mark nil) (case-fold-search nil))
  (if (and transient-mark-mode mark-active)
      (setq pos1 (region-beginning)
            pos2 (region-end))
    (setq pos1 (car (bounds-of-thing-at-point 'word))
          pos2 (cdr (bounds-of-thing-at-point 'word))))

  (when (not (eq last-command this-command))
    (save-excursion
      (goto-char pos1)
      (cond
       ((looking-at "[[:lower:]][[:lower:]]") (put this-command 'state
"all lower"))
       ((looking-at "[[:upper:]][[:upper:]]") (put this-command 'state
"all caps") )
       ((looking-at "[[:upper:]][[:lower:]]") (put this-command 'state
"init caps") )
       (t (put this-command 'state "all lower") )
       )
      )
    )

  (cond
   ((string= "all lower" (get this-command 'state)) (upcase-initials-
region pos1 pos2) (put this-command 'state "init caps"))
   ((string= "init caps" (get this-command 'state)) (upcase-region
pos1 pos2) (put this-command 'state "all caps"))
   ((string= "all caps" (get this-command 'state)) (downcase-region
pos1 pos2) (put this-command 'state "all lower"))
   )
)
)

some notes:

it doesn't use (&optional beg end) with the associated
“(interactive ...)” code because i think when a command is designed
only for interactive use, then it makes sense to not support calling
it in elisp as much as possible.

As far as i know, elisp does not have a conventional mechanism to
indicate that a function is ONLY for interactive use. More
specifically, those with “(interactive ...)” clause are properly
called “commands”, meaning that it can be used BOTH by interactive
call as well in elisp code.

Going philosophical on this, i wonder if the system would better if
the presence of “(interactive ...)” is to mean that the command cannot
be allowed in elisp code. This would mean, that all elisp functions
are separated into 2 groups: those commands proper (presence of
“interactive”) and functions proper (no presence of “interactive”).
This also means that some class of functions that are good for both
interactive and elisp use will now have to be separated into 2
versions (i.e. means more coding). But i'm guessing that over all this
is a good thing and does not introduce much more labor.

I think this separation is a good because with that there's a clear
indication which function is for interactive use and which is for
elisp only, and this indication is mechanical, i.e. build into the
system so that calling a command in elisp program won't work. Right
now, when a function is meant for interactive use only, emacs does its
best to warn it in the inline doc or elisp manual.

the above is just musings on the design, of course, in case someone
takes me this to be some modernization of elisp. LOL.

  Xah
∑ http://xahlee.org/

reply via email to

[Prev in Thread] Current Thread [Next in Thread]