1

I have a variable that expects a string, and I want to set it to a function that will return a string whenever the variable is used.

Right now, I have

(setq bibtex-autokey-prefix-string (format-time-string "%Y_%m%d-"))

This is close to what I want, but it sets the prefix string once when my variable customizations are evaluated at startup. So the variable holds not the current date but the date when Emacs was started.

When I try

(setq bibtex-autokey-prefix-string '(format-time-string "%Y_%m%d-"))

I get the error:

Wrong type argument: characterp, format-time-string

Is it possible to do what I'm trying to do?

p.s. something else I tried resulted in a stringp wrong type argument error (I think?), but I can't reproduce that any more.

2
  • 1
    Can't you use a function instead of a variable?
    – choroba
    Apr 11, 2021 at 20:08
  • @choroba No, because the value of bibtex-autokey-prefix-string is expected to be a string.
    – Basil
    Apr 11, 2021 at 20:44

1 Answer 1

2

How to use a delayed evaluation function where a string is expected?

Submit a feature request for bibtex.el via M-x report-emacs-bug RET.

Is it possible to do what I'm trying to do?

In the meantime, you can use function advice to temporarily modify bibtex-autokey-prefix-string around the place where it's used, e.g.:

(define-advice bibtex-generate-autokey (:around (&rest args) my-date)
  "Bind `bibtex-autokey-prefix-string' to desired date format."
  (let ((bibtex-autokey-prefix-string (format-time-string "%Y_%m%d-")))
    (apply args)))

Along the same lines, you could permanently update bibtex-autokey-prefix-string just before it's used each time:

(define-advice bibtex-generate-autokey (:before (&rest _) my-date)
  "Set `bibtex-autokey-prefix-string' to desired date format."
  (setq bibtex-autokey-prefix-string (format-time-string "%Y_%m%d-")))

[Disclaimer: these examples are guaranteed 100% untested.]

Edit

Based on the examples above, the OP ended up using the following:

(defun my-bibtex-autokey-wrapper (orig-fun &rest args)
  "Dynamically bind `bibtex-autokey-prefix-string' to current date."
  (let ((bibtex-autokey-prefix-string (format-time-string "%Y_%m%d-")))
    (apply orig-fun args)))

(advice-add 'bibtex-generate-autokey :around #'my-bibtex-autokey-wrapper)

Note

In the first and last example, bibtex-autokey-prefix-string needs to be declared as a special variable in order for the advice to always have the intended effect, regardless of lexical-binding and byte-compilation.

If bibtex.el is already loaded, then happy days: the user option has already been declared. Otherwise, an explicit defvar is needed so that the let-binding doesn't create a local variable with lexical scope:

(def...
  "..."
  (defvar bibtex-autokey-prefix-string)
  (let ((bibtex-autokey-prefix-string ...))
    ...))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.