I am trying to setup a snippet to add a src-block header to an emacs org-mode src-block. I want to get a list of possible headers to choose from, which I can get in this snippet (the org-babel-headers function is defined in a .yas-setup.el and just returns a list of the headers).

# -*- mode: snippet -*-
# contributor: John Kitchin <jkitchin@andrew.cmu.edu>
# name: src-block-header
# key: sh
# expand-env: ((headers (org-babel-headers)))
# --
:${1:$$(yas-choose-value headers)} $0

I would also like a second field, right after this, that offers choices that are based on the first choice (i.e. I know the legitimate values each header can take, and I want to offer those as choices).

Is this doable in some way?

  • How about something like a buffer-local or global variable such as (defvar john_kitchin nil "Doc-string.") and then in the snippet instead of (yas-choose-value headers) use (setq john_kitchin (yas-choose-value headers)) and then your second field would be something like (yas-choose-value--john-kitchin john_kitchin)? As you know, setq returns a value -- so in theory, you would be good go ... You can also create a new function yas-choose-value--john_kitchen (based on yas--choose-value) and modify that variable as needed to offer custom choices.
    – lawlist
    May 11 '18 at 1:08
  • Here is an example of something I have been using today: ${3:$$(unless (or yas-moving-away-p yas-modified-p) (let ((result (some #'(lambda (fn) (funcall fn "Are there any transactions >= $1,000.00? " '("n" "y"))) yas-prompt-functions))) (cond ((equal result "n") (setq result "\n+ No individual transactions >= $1,000.00.")) ((equal result "y") (setq result nil))) result))} You can take in/use the result of john-kitchen variable, do whatever needs to be done, and then present a list of choices during that function -- so that when you press enter, the value/string desired is returned.
    – lawlist
    May 11 '18 at 1:20
  • this seems like a good idea, but I have not been able to get it to work. The setq does not seem to be affecting a global variable value. I found another way though. If I can post an answer I will. May 11 '18 at 3:59
  • It seems I can't post an answer yet. The way I found to do it was to use a command type. like described here: groups.google.com/forum/#!topic/smart-snippet/8Og-1U5zJ2E May 11 '18 at 4:00
  • Thank you for posting the link -- I'll hold off with an alternative answer since it sounds like you found a better way of doing it.
    – lawlist
    May 11 '18 at 5:06

Here is how I was able to achieve this goal. It is basically like writing an elisp function that gets the information you want, and then constructs the string to put in the buffer. I adapted the idea from https://groups.google.com/forum/#!topic/smart-snippet/8Og-1U5zJ2E.

# -*- mode: snippet -*-
# contributor: John Kitchin <jkitchin@andrew.cmu.edu>
# name: dependent-choices
# key: exm
# type: command
# --
(let* ((choices '(("a" . ("1" "2" "3"))
          ("b" . ("4" "5" "6"))))
       (choice1 (completing-read "Choice 1: " (mapcar 'car choices)))
       (choice2 (completing-read "Choice 2: " (cdr (assoc choice1 choices)))))
  (yas-expand-snippet (format "${1:%s} ${2:%s} " choice1 choice2)))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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