[Top][All Lists]

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

Re: [Orgmode] Use variable filename for remember template?

From: Nick Dokos
Subject: Re: [Orgmode] Use variable filename for remember template?
Date: Mon, 06 Jul 2009 22:42:36 -0400

Nathan Neff <address@hidden> wrote:

> I am able to successfully read the contents of
> "/Users/nate/personal/booktemp.txt" into a new remember-note.
> (setq org-remember-templates
>      '(("Book" ?b "\n* %^{Book Title} %t :READING:
> \n%[/Users/nate/personal/booktemp.txt]\n"
>               "L:journal.org")
>       ))
> Now, I'd like to be able to specify an environment variable like $HOME
> instead of /Users/nate.
> I'm a lisp beginner, and have tried something like
> (setq personal-home-dir (getenv "HOME"))
> (setq org-remember-templates
>      '(("Book" ?b (concat "\n* %^{Book Title} %t :READING: \n%["
 personal-home-dir "/personal/booktemp.txt]\n")
>               "L:journal.org")
>       ))
> but I keep getting "Wrong type argument char-or-string-p" errors.
> I'm guessing that the org-remember-templates function wants something
> other than a string, but I don't know where to go from here.

No, it requires a string. The problem is that when you quote an expression
in lisp, you are saying "do not evaluate the innards of this expression".
But here you *want*  some of the innards evaluated: in particular, the call
to concat *has* to be evaluated in order to give you the required string.

Note that org-remember-templates is supposed to be a list of lists. Each inner
list has to have the form

     (string char string [string] [string])

where the square brackets indicate optional elements. That's the name of the
template, the char you use to invoke it, the template itself, the destination
file, and the headline.

The trick is to construct such a list without using quote. The lisp function
to construct lists is called (drum roll...) ``list''. So you can construct
the list like this:

    (list "Book" ?b 
          (concat "\n* %^{Book Title} %t :READING: \n%[" personal-home-dir 

When evaluated [1], the above expression gives you the following list:

         ("Book" ?b 
          "\n* %^{Book Title} %t :READING: 

That will serve fine as the inner list, but now we have to set 
to be a list with the inner list as its only element (unless of course you have 
than one template):

(setq org-remember-templates
            (list "Book" ?b 
                  (concat "\n* %^{Book Title} %t :READING: \n%[" 
personal-home-dir "/personal/booktemp.txt]\n")

will do that.

This method will work in general, but it is overkill for the simpler situation
where all of the elements of the inner list(s) are "constants", i.e. when you
evaluate them, they give you back what you started with (e.g. numbers, strings,
chars evaluate to themselves). In this situation, you can form the list like 

      ("Book" ?b "..." "...")

except that when lisp sees such a form, it assumes it's a function call
with arguments, e.g. (+ 2 3) is a call to the function + with args 2 and 3.
It is in order to inhibit *this* evaluation that quoting is used - it makes
the quoted expression self-evaluating:

      '("Book" ?b "..." "...")

Look at the difference:

    (+ 2 3) --> 5
    '(+ 2 3) --> (+ 2 3)

If you have more questions (and you *should*! Even in the highly
unlikely situation that the above is crystal clear, it only scratches
the surface of a deep subject), try an introductory book on lisp,
perhaps "The Little Lisper" by Dan Friedman (the current edition is
called "The Little Schemer", co-authored with Matthias Felleisen, and it
discusses the Scheme dialect of Lisp, but the basic ideas are the
same). Emacs also comes with an Emacs Lisp Intro (which I have not
read) - you might look at that instead (or in addition): do C-h i m
Emacs Lisp Intro <RET>.


[1] Try it: put the cursor at the end of 

(setq personal-home-dir (getenv "HOME"))

i.e. after the closing parenthesis, and press C-x C-e - the result is
displayed in the minibuffer (echo area). Of course, the main object here
is not the result of the expression, but the side effect: setq binds the
variable personal-home-dir to the value of (getenv "HOME"). But now that
personal-home-dir is defined, you can put the cursor at the end of the
list expression , press C-x C-e and you'll see the result of that

reply via email to

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