Thinking about how to make better use of Yasnippet in my Emacs workflow
Posted: - Modified: | emacs, orgOne of the awesome things that Karl Voit demonstrated in this Emacs Chat was how he used YASnippet and Org Mode to quickly create projects with several related tasks, such as when organizing a group to attend an event. He selected the snippet and filled in different fields like the artist name and the event date, and Emacs generated all these sub-tasks and e-mail templates with the information already filled in.
I’ve used YASnippet once or twice, but mostly I’ve been using org-capture
and org-capture-templates
instead. YASnippet looks like it might be more flexible because you can fill in fields in a non-linear order and you can re-evaluate Emacs Lisp expressions as you type.
Lots of people do cool things with YASnippet. For example, it’s popular for programming because it lets people quickly expand short sequences into longer syntax. Check out this Emacs Rocks episode on YASnippet to get a sense of what it can do. (Note: YASnippet has changed its naming convention slightly, so things like yas/text
have been replaced with yas-text
.) People have used it for e-mail templates and to fill in metadata for blog posts.
I’d like to use YASnippet more. Where can I integrate it into my workflow? Probably wherever checklists and templates make sense. I’ve been thinking about checklists and templates as a way to improve how I do things.
Checklists are good for making sure that you complete tasks more consistently, not missing any important steps. You can work faster when there’s a guide, since you don’t have to keep thinking of the next step each time. The simple act of checking things off can encourage you to put in more effort, since the list shows you your progress. It also makes it easier to remember to follow up.
Templates help you improve the structure of your work. You can make sure you cover all the important parts. If you use similar structures for many things, then people get used to finding information in the same logical places. This doesn’t mean that you’re stuck with cookie-cutter formats. You can still adapt the format to your needs.
I’m particularly interested in using checklists and templates to improve in three areas:
- Programming: I’d like to write with less friction and use best practices like testing
- Helping the Emacs community: Checklists can help me make sure I do all the steps to prepare for and make the most of Emacs Hangouts and Emacs Chats. They might also lower the intimidation factor so that I end up scheduling these more often.
- Writing: I think checklists and templates will help me invest more time into developing thoughts, relationships, and structure.
Programming
As mentioned, YASnippet’s popular for programming. You can take advantage of existing collections of snippets for different programming modes (ex: AndreaCrotti’s collection), or you can define your own.
I’d like to get better at developing single-page applications using AngularJS, Twitter Bootstrap / Zurb Foundation, and NodeJS. YASnippet might let me quickly put together short applications and test suites. If I get my workflow smooth enough, I might even be able to do an app-a-week (or app-a-day) sprint for deliberate practice. There are often lots of fiddly little syntax or keyword things that I look up while writing code. While practising typing those things in again and again will help me memorize them, there’s also some value in automating that part with snippets so that I can focus on the core skills of designing and implementing small web applications.
YASnippet might also be able to help me use Org Mode to keep track of ideas for features or small web applications throughout the implementation process. I wonder if I should implement this using lots of subtasks or using TODO states with logs. TODO states might be easier to filter or visualize with the kanban
package for Org Mode. Maybe I’ll try both approaches. In any case, checklists will help me remember to think about designs and tests before implementing the code, and maybe I can keep track of deployment notes, lessons learned, and follow-up tasks.
Emacs Community
I find checklists to be really helpful when setting up live videocasts. I’m usually too frazzled to think of all the steps I need to do at the last minute. Paper checklists are good because I can refer to them while keeping my screen ready to be recorded. Still, an Org Mode-based checklist (possibly with dynamic date fields and e-mail templates provided by YASnippet) might go a long way towards standardizing the before- and after-event process, and that might in turn reduce the friction enough for me to do more of them. Both Emacs Chats and Emacs Hangouts seem to be popular, so it would be good to get more of these on the go.
The process would be something like:
- Reach out to the person who’s going to be featured on the Emacs Chat, or at least one other person who’s willing to be there for the Emacs Hangout (so that I don’t end up talking to myself for the first ten minutes, which is Awkward)
- Figure out what will be discussed (for Emacs Chats)
- Set up a time, considering timezones
- Set up the Google+ event page
- Update the Google Calendar
- Post a notice on Twitter and on my blog (I’ve been forgetting to do this step)
- On the day of the event
- Do the last-minute push (I’ve been forgetting to do this as well)
- Create the Google Hangout on Air
- Set it up for Q&A
- Invite the other person in for Emacs Chats, or post the URL for Emacs Hangouts
- Host the video chat
- Remind people where the recording can be found
- Update the Google+ page with the link to the next thing
- Extract the MP3 from the video, change the properties, and upload it to archive.org
- Post a blog post with the embedded video, podcast audio, and quick notes
- Transcribe the video or pay for transcription
- Edit the transcript
- Update the post with the transcript
- Update the Google+ event page with the link to the transcript, post to social networks (I’ve been forgetting this)
- Update EmacsLife.com, too (yet another thing I’ve been forgetting)
I think it would be totally awesome to get to the point where I can call an Emacs Lisp function that would Do The Right Thing at that point, like posting to Twitter or using something like org-trello
to make a Trello card and assign it to the person who does my transcriptions.
Writing
I’m getting the hang of using outlines to write (and I should post a video about this soon), but it might be even cooler if I can get the hang of writing with more structure. For example, Michael Hyatt posted this blog post checklist that he had been using with Evernote. I like it because:
- The template asks you to be explicit about the post’s objective and subject.
- It encourages you to add more illustrations, links, and stories.
- It reminds you to take steps that you might otherwise skip, and you might spend several days revising the post.
I might not use it for every post, but it’s good to flesh out some ideas further, especially the ones where I think I’m onto something particularly interesting.
It would be even cooler if I could take advantage of YASnippet’s dynamic Emacs Lisp evaluation to remind me of relevant links from my blog post outline given the category. I remember playing around with the Remembrance Agent, which monitored a few hundred words around your cursor and brought up files that had similar words. Matching on category isn’t going to be anywhere as sophisticated, but it still might be a good way to refresh my memory. Even if I had a quick Emacs Lisp interactive function that read whatever category property I’d set (chosen from the org-refile
-able targets) and displayed the section from my blog post index in another window, I think that would be a pretty neat start.
I tend to draft posts within my sharing outline (which I sporadically publish at http://pages.sachachua.com/sharing/). When I’m done, I delete the subtree, sometimes replacing it with a link to the post to help me follow up on it in the future. This means losing that metadata, though. It might be interesting to keep the metadata so that I can review the goals and backstory of a blog post.
YASnippet can also help me keep track of the TODOs related to a post as well. For example, I might want to come up with sketches, tweet links, or follow up on ideas. If I use a YASnippet to plan my blog post in the first place, then I can create a TODO (possibly with a link back to the blog post) that I could leave in place or refile to the appropriate location in my regular Org Mode files.
I don’t think YASnippet dynamic fields persist after the file is saved and reloaded, though. How would that work if I need to change things? Maybe I can use multiple-cursors
to mark all the matching text in the subtree, or do other clever things with it…
Next steps
Okay. It looks like setting up YASnippet for Emacs checklists would probably give me the quickest win. Programming is also pretty straightforward. Writing might be interesting too, if I can get the hang of working with that kind of structure. Let’s see how that goes. Once I figure out what those snippets will be like, I’ll post them on Github somewhere. =)
Is YASnippet part of your workflow? Have any thoughts, suggestions, or neat stories?
17 comments
TobyHaynes
2015-01-09T16:13:07ZYASnippet is a pretty key part of my perl programming workflow. I have snippets for most repeatable perl activities, from class layouts, member subroutines, validation routines and similar. I find that having the cursor change colour when a yasnippet expansion can fire is helpful. One such setup is at https://github.com/pcmantz/...
sachac
2015-01-09T18:51:50ZOooh, colour-changing is a good idea. I don’t seem to have a yas–current-key, but using (yas–templates-for-key-at-point) works with yas–version 0.8.0beta. =) Thanks!
Now I want to get it to remind me of abbreviations too…
jcs
2015-01-10T16:42:17ZI use yasnippet all the time. Here are a couple snippets that I use every day for writing my blog posts:
Insert Org header for blog post. Prompt for title, category, and tags. Default to General for category.
# -*- mode: snippet -*-
# name: header
# key: bh
# --
#+TITLE: $1
#+CATEGORY: ${2:General}
#+TAGS: $3
#+OPTIONS: ^:{} toc:nil num:nil tex:t
#+STARTUP: entitiespretty
$0
************************************************************
Insert begin_src ... end_src headers. Prompt for language but default
to Elisp.
# -*- mode: snippet -*-
# name: sb
# key: sb
# --
#+BEGIN_SRC ${1:emacs-lisp}
$0
#+END_SRC
sachac
2015-01-12T23:25:05ZThanks for sharing! Yup, blog posts are a common use of Yasnippet. What does ^:{} mean - is that an ORg thing or an Emacs thing? =)
Me, I changed <l to create source blocks for Emacs Lisp instead of LaTeX since I use that for Emacs Lisp more often. But making snippets for things like that makes sense too, especially when it comes to some of the more complicated parameters...
jcs
2015-01-12T23:56:47Z^{} says to not treat ^ and _ as super- and subscripts unless what follows is enclosed in braces. Thus, x^2 is just the three characters x, ^, and 2 not x-squared. To get x-squared, you type x^{2}. This mostly useful when you want to type something like compound_variable or the like.
sachac
2015-01-16T20:35:17ZOh, that's awesome. I keep getting mixed up by _, so I've mostly trained myself to always put them in =...=, but ^{} is better. =)
jcs
2015-01-17T13:35:48ZIf you don't need sub or superscripts, you can turn it off completely with
^:nil
.sachac
2015-01-26T19:29:56ZI found org-export-with-sub-superscripts, which I've now set to nil. Let's see if this keeps my pages better-behaved.
João Távora
2015-01-12T19:25:52ZHi, I'm the author of yasnippet. Can you link to https://github.com/capitaom... instead of the emacswiki link? The latter has a lot of outdated, possibly confusing information, and is not maintained anymore (at least by me). Thanks.
sachac
2015-01-12T23:22:37ZThanks for dropping by! Could you be more specific about the outdated/confusing information on the EmacsWiki page? I see that the EmacsWiki page correctly links to your git repository, and I like that it mentions complementary packages. I updated someone's docstring to refer to yas-prompt-functions instead of yas/prompt-functions. There's some discussion at the bottom regarding yasnippet-config.el and 0.6 vs 0.7, but the linked yasnippet-config.el isn't one of the main links. Since the page might still be useful to other people (and people will definitely come across it in a search), I'm happy to help out with little tweaks if I can.
João Távora
2015-01-13T07:26:01ZThanks for the reply and the article.
`yasnippet-bundle.el` the third item in the list and hasn't existed for a few years. "Install by hand" should be done from a github checkout as it's been a couple of years since the last release. In a more minor scale, there are comments (some of mine) stating that yasnippet has recent entered 0.6, etc... and that's just silly. You can certainly help cleanup the page, but I'd much rather you'd invest that effort in finding and correcting documentation bugs in the official documentation and then link from emacswiki to there. The official doc lives at http://capitaomorte.github...., is driven by the org files under `doc`. Isn't it you who loves org? :-) I bet there are a lot of tricks you could teach us. And then link from emacswiki to there.
We get lots of issues in yasnippet from people that are almost certainly coming from outdated documentation sources. And there being only a little time to dispense on yasnippet, it has to go to the official material, and less to the satellite documentation.
sachac
2015-01-13T15:10:55ZGreat! I've replaced the Emacswiki installation instructions with a reference to the official docs, and I cleaned up the discussion. I see the TODO entries in the docs - I'll add that to my list of things to possibly contribute to as I learn more about Yasnippet. Thanks again for sharing this! =)
João Távora
2015-01-13T15:40:43ZThanks. Your contributions will be much appreciated. If you see a TODO but are unsure how to proceed, do what you can, commit it to your fork and open a pull request with that. We'll help you in the discussion in the pull request so we can add commits and merge it to the mainline.
Xebar Saram
2015-02-07T06:45:27ZHi Sacha
thanks again for your amazing post. i have a Q though. i copied from ypur config the "defun shk-yas/helm-promp" config but it dosent seem to work. it gives me the following error when i eval the whole block:
call-interactively: Wrong number of arguments: (lambda (prompt choices &optional display-fn) "Use helm to select a snippet. Put this into `yas/prompt-functions.'" (interactive) (setq display-fn (or display-fn (quote identity))) (if (require (quote helm-config)) (let (tmpsource cands result rmap) (setq cands (mapcar (function (lambda (x) (funcall display-fn x))) choices)) (setq rmap (mapcar (function (lambda (x) (cons (funcall display-fn x) x))) choices)) (setq tmpsource (list (cons (quote name) prompt) (cons (quote candidates) cands) (quote (action ("Expand" lambda (selection) selection))))) (setq result (helm-other-buffer (quote (tmpsource)) "*helm-select-yasnippet")) (if (null result) (signal (quote quit) "user quit!") (cdr (assoc result rmap)))) nil)), 0
any clue?
thx!
z
sachac
2015-02-09T20:17:48ZOh, you're not supposed to call it yourself. If you press TAB after an ambiguous snippet (something that can expand to multiple things), it should get automatically called by yasnippet.
NerdGGuy
2015-03-14T02:13:32ZHi Sacha! I'm in the exact same situation of trying to explore using yasnippets to speed up my workflow. Did you get any time to look into using this with twitter bootstrap development? I too believe with a few shortcuts my <html/> development time could be greatly reduced. I've recently made the switch to spacemacs to take advantage of the mode/micro-mode workflow it provides for html. I've found a couple of repositories on github with some bootstrap snippets but a lot less then I thought. I'll post back if I have any success!
sachac
2015-03-22T21:46:59ZNope, but year, other probably already have snippet collections for that, or you can come up with some for the ones you use a lot. Good luck!