Dynamically changing file name in org-agenda-export - elisp

I would like to export the agenda view to separate file with a unique name based on the current date. Based on this example code:
(setq org-agenda-custom-commands
'(("X" agenda "" nil ("agenda.ps")))
)
The last argument is the file name so I thought I can put the output of the concat function, e.g.:
(setq org-agenda-custom-commands
'(("X" agenda "" nil (concat (format-time-string "%Y-%m-%d") "-agenda.html")))
)
Unfortunately, this approach fails since the interpreter takes the concat literally, and a string (expected data type) is not generated. I’m not very familiar with LISP, so any help is greatly appreciated.

First of all the last argument is not a filename but rather a list of names, so you must add some extra parentheses.
As you already noted, because of the quote the list is not evaluated, and it's fine since you don't want to evaluate it, except the last element (concat function). To do so you can use backquote:
(setq org-agenda-custom-commands
`(("X" agenda "" nil (,(concat (format-time-string "%Y-%m-%d") "-agenda.html"))))
)
As a side note, I'm not a specialist of the org-mode and I'm just answering the question you asked, but I have a feeling that it is possible to achieve your goal in a more simple way. Not sure how, but maybe you can dig in the documentation of org-mode and probably you'll find something interesting.

Related

In Common Lisp FORMAT how does recursive formatting work

I need to generate a space-padded string with a variable string length. The not-so-clever solution that works involved nesting of format:
(format nil (format nil "~~~d,,a" 10) "asdf")
Now, I wanted to make it a bit more clever by using format's ~? for recursive processing. I would expect that something like this should do what I want:
(format nil "~#?" "~~~d,,a" 10 "asdf")
but what I get is just the formatting string, i.e. ~10,,a, not the padded asdf string. Perhaps I misunderstood the word 'recursive' here, but I would expect that having formed the inner format string, CL should proceed to actually use it. Am I missing something?
Variable arguments to format directives
FORMAT allows you to use v as an argument to a directive in the control string to pop arguments from the argument list.
CL-USER> (format nil "~va" 10 "asdf")
"asdf "
There may be multiple vs used.
CL-USER> (format nil "~v,,,va" 10 #\- "asdf")
"asdf------"
Recursive processing with ~?
The recursive processing directive is meant for embedding a different "call" to FORMAT inside a control string. For example, a function to prompt for a yes or no answer might be implemented with it.
(defun y-or-n-prompt (control-string &rest args)
(format t "~&~? [y/n]: " control-string args)
;;...
)
The caller can now format a prompt with this as they would with FORMAT without having to worry about the details of what the prompt should look like to the user (adding a new line at the beginning or the [y/n]: prompt at the end).
CL-USER> (y-or-n-prompt "foo ~d bar" 12)
foo 12 bar [y/n]:
NIL
The result of ~? will not be processed by FORMAT, so it cannot be used to build a control string. In general, building control strings at run time is a bad idea, because it's error prone (for example, you must escape any unwanted tildes in the string) and prevents the implementation from processing the control string at compile time.

Org Mode: Symbol's function definition is void: \,

I'm trying to create an Org mode capture template that writes each entry to a time-based filename.
First, there is a helper function that works in the scratch buffer:
;; Example input: (capture-date-based-file "~/path/to/logs/" "log")
;; Expected output: "~/path/to/logs/2017-11-27-monday-log.org"
(defun capture-date-based-file (path entry-type)
"Create a date-based file name based on the given type."
(downcase (concat path (format-time-string "%Y-%m-%d-%A-") entry-type ".org")))
Then, it's used in the capture templates list:
(setq org-capture-templates
'(("l" "Log" entry (file+headline ,(capture-date-based-file "~/path/to/logs/" "log"))
"* %?\n%U\n" :clock-in t :clock-resume t) ))
I get an error: Symbol's function definition is void: \,
It's difficult to find an answer in Google, because of the comma character. I've looked over the docs, and I'm not sure what I'm doing wrong.
The comma suggests that you're wanting to evaluate the call to capture-date-based-file, but the surrounding form is quoted rather than backquoted, so that won't work.
i.e. these are two quite different things:
'(foo ,(bar) baz)
`(foo ,(bar) baz)
See C-hig (elisp)Backquote RET
In a backquoted form, the comma causes the form which follows to be evaluated immediately, and the result of that evaluation is then substituted into the backquoted form. In a quoted form, ,(bar) simply remains as a literal ,(bar).
The reason for the specific error you saw is that the lisp reader produces the following:
ELISP> (read ",(bar)")
(\, (bar))
Therefore any attempt to evaluate ,(bar) is actually calling the non-existent function \,
(One of the less-obvious errors you'll encounter, FWIW.)
In your scenario I presume that org pulls that particular form out of the template structure and evaluates it. M-x toggle-debug-on-error would most likely show you exactly where and when this happens.

Call finish-output from format

I noticed that there is no
format directive which would
call force-output/finish-output.
Why?
It does seem to be useful in user interaction, cf.
Lisp format and force-output.
E.g., ~= could translate to finish-output, and ~:= to force-output.
I don't think clear-output makes much sense in this context, but we
might map ~#= to it for completeness.
PS. Cf. CLISP RFE.
Summary from comp.lang.lisp:
An explanation from Steven Haflich
The language defines no portable way to extend the set of format
directives (other then ~/.../) but that's not really the issue here.
The real problem is that it is not well defined to call finish-output or similar functions at arbitrary places during printing.
If pretty-printing is in progress, the stream received by a
pprint-dispatch or print-object method may be an encapsulating stream --
one that delays output temporarily until it can make decisions about
white space and line breaks. (There are also potential problems if
finish-output were called inside a ~< justification, but that directive
is a hairball!) What would one expect finish-output to do if called
inside a pretty print operation? I don't think it's well defined.
The problem isn't particular to format, of course, but a directive for
finish-output from format would just add another sharp edge to the
language. finish-output etc. are only safe to call when completely
outside an actual or implied call to cl:write. Call it as a function
at an appropriate point in your code (where you know execution isn't
inside a nested write) so the intention is clear and you don't mess up
printer internals.
A suggestion from Rob Warnock
Actually, no changes to format are needed. Just add this function somewhere in the COMMON-LISP-USER package:
(defun fo (stream arg colon-p atsign-p &rest params)
(declare (ignore arg params))
(cond
(colon-p (force-output stream))
(atsign-p (clear-output stream))
(t (finish-output stream))))
Then:
(progn
(format t "enter var: ~/fo/" nil)
(read))
enter var: 456
456
The problems with this (portable!) approach are
verbosity (~/fo/ instead of ~=)
need to consume a format argument (nil in the example above)

How do I get a list of functions defined in an emacs-lisp file

Is it possible to get a list of functions defined in an emacs-lisp file? I found this sort of related answer: How do I get a list of Emacs lisp non-interactive functions?, but it involves a map over all of the atoms defined, not just what is in a file.
If the file in question has already been loaded, then you can modify the code in the question you link to filter out the symbols defined in other files:
(let ((funclist ()))
(mapatoms
(lambda (x)
(when (and (fboundp x) ; does x name a function?
(let ((f (symbol-file x)))
(and f (string= (file-name-base f) "my-file.el"))))
(push x funclist))))
funclist)
If the file has not been loaded, you would have to scan it with scan-sexps and find defun forms.
You might, however, prefer to use etags or imenu instead of scanning the file yourself.
Maybe a faster way is to look for the file in load-history, which will then give you the list of variables and functions defined therein.
Not sure if your asking for a non interactive approach.
With M-x occur ENT (defun.* ENT you get a buffer with more or less all function-definitions found in (current-buffer).
The quick&dirty way: extract all defuns via regex. It works instantly on a buffer with 5000 lines.
(-map 'cadr (s-match-strings-all "defun \\(.*?\\) " (buffer-string)))
This returns a list of function names that are defined via defun in the current open buffer. buffer-string returns content of a current buffer in a string, -map and s-match-string-all are taken from dash and s third party libraries (their GitHub pages explain how to install them), cadr returns a 2nd element of a list.
-map is analogous to Emacs built-in mapcar, it applies a function to each element of a list and returns a new list, s-match-string-all returns all possible regex matches in a string, parentheses in a regex denote a group (read more how to form Emacs regular expressions from EmacsWiki).
If you run it in eval-expression (Alt+:), it will just throw it into echo area, but that's not what you need. So below are variations that work with custom buffer or file. with-current-buffer allows to temporarily switch a buffer, while some code does actions inside it, f-read is a file reading function form another third-party library f.
(defun list-defined-functions (buffer)
(with-current-buffer buffer
(-map 'cadr (s-match-strings-all "defun \\(.*?\\) "
(buffer-string)))))
(defun list-defined-functions-in-file (file)
(-map 'cadr (s-match-strings-all "defun \\(.*?\\) "
(f-read file))))
Read Emacs Lisp manual and try to come up with whatever is useful for you.

How do you find the name of the current running funciton: current-function, this-function, current-defun, this-defun

I am trying to dynamically find the name of the current function (this-function) running i.e.
(defun my-func ()
(remove-hook 'some-hook this-function)
(do-something))
I haven't tested this, but why not write a macro to encapsulate what you want? Something like the following, maybe?
(defmacro one-shot-hook (name hook &rest body)
`(defun ,name ()
(remove-hook ',hook ',name)
,#body)
Then, for example
(macroexpand-all-1
'(one-shot-hook test c-mode-hook
(message "Yay!")))
gives
(defun test nil
(remove-hook (quote c-mode-hook) (quote test))
(message "Yay!"))
(when I've reformatted it).
This removes the problem of needing to know the name of the function you're in, which would need nasty macrology anyway (I'm not sure whether it's possible).
One more thing, I'd probably suggest just having a flag variable set to nil initially which your code tests to decide whether to run. Then you don't have to mess around adding and removing hooks all the time: the result will probably be much easier to customise and understand for anyone else using your code.

Resources