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

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

Re: reading a variable from the user


From: Eric Abrahamsen
Subject: Re: reading a variable from the user
Date: Thu, 11 Oct 2012 11:27:41 +0800
User-agent: Gnus/5.130006 (Ma Gnus v0.6) Emacs/24.2.50 (gnu/linux)

On Thu, Oct 11 2012, drain wrote:

> strings.el and simple+.el are new to me: thanks. They may contain the answer,
> and I need to pick through them carefully, but I'll just be forthright about
> what I am trying to do. Very new to Emacs Lisp...
>
> I want to prompt myself with "To:", enter a contact name and a topic, then
> pass them as arguments to compose-mail.
>
> This was no problem, but the goal right now is to cut out the redundant
> conditional statement, and instead match the name string I enter to its
> variable directly, for example "William" to the William variable. Might
> require pointers or arrays of some sort, but I haven't gotten that far in
> the Emacs Lisp Intro.

There are many, many ways to do this obviously (hash tables, BBDB, etc),
but for the purposes of learning elisp it might be best to start with
some kind of association list (alist, section 5.8 of the Elisp manual).
That would look like this:

(setq names '((william "xx@xxxxxxxxxxx.org")
              (david "xxxxxxxxxxx@gmail.com")
              (carl "xxxxxxxxxx@gmail.com")))

or like this:


(setq names '((william . "xx@xxxxxxxxxxx.org")
              (david . "xxxxxxxxxxx@gmail.com")
              (carl . "xxxxxxxxxx@gmail.com")))

The difference, as far as I know, is that in the first method you can
have multiple values per list (so something like (william "William"
"White" "xx@xxxxxx.org")), whereas the dotted cons cell notation (the
second one) only allows two atoms.

If you look at the association list section of the manual, you'll see a
bunch of functions for working with lists like these. The main one is
`assoc':

(assoc 'william names) -> (william "sdfsdf@sdfsdf")

(second (assoc 'william names)) -> "sdfsdf@sdfsdf"

It's generally better to use a `let' instead of a `setq' to make
temporary variables in your functions. Here I've used let*, which is
only different in that it evaluates the statements one by one, so later
statements can refer to values established in earlier statements.

As far as I can tell you can't use symbols in the assoc list set up by
`let' (is this wrong?). So your function might look like:

(defun custom-compose-mail (contact topic)
  (interactive "sTo: \nsTopic: ")
  (let* ((names '(("William" "xx@xxxxxxxxxxx.org")
                  ("David" "xxxxxxxxxxx@gmail.com")
                  ("Jason" "xxxxxxxxxx@gmail.com")
                  ("Carl" "xxxxxx@gmail.com")))
         (contact (second (assoc contact names))))
    (compose-mail contact topic)
    (end-of-buffer)
    (newline)))

The next thing to do, for the sake of usability, would be to choose a
name using `completing-read', so that you could type a few letters and
use TAB to complete.

Hope that's useful,

Eric

-- 
GNU Emacs 24.2.50.1 (i686-pc-linux-gnu, GTK+ Version 3.4.4)
 of 2012-10-10 on pellet




reply via email to

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