Fun with espanso

I use epsanso on macOS to do text expansion. It uses a YAML file syntax and can do a lot of really powerful things through scripting. Here’s how I use it to put a breadcrumb trail at the top of my daily notes, which looks like this

[[2020-06-21|<< Yesterday]] | [[2020-06-23|Tomorrow >>]]

 # Breadcrumb
  - trigger: ":bc"
    word: true
    replace: "{{output}}"
    vars:
      - name: output
        type: shell
        params:
          cmd: "echo `date -v -1d \"+[[%Y-%m-%d|<< Yesterday]]\"`' | '`date -v +1d \"+[[%Y-%m-%d|Tommorrow >>]]\"`"

I had to use the shell command date to automatically generate Yesterday and Tomorrow’s dates.

As a bonus, here is the template I use when tracking meetings

 # Meeting
  - trigger: ":meet"
    word: true
    replace: |
             ## 0000 Meeting
             - Tags:
             Meeting Link:
             Attendees:
             Tasks:
             Notes:

Obsidian and espanso fight over the bullet markdown tag, so in order to make a bulleted list, you start with one bullet, and then don’t use the bullet tag thingy for the rest of the list.

Edit: More fun!

So my use of Obsidian revolves heavily around Daily Notes. Everything I do links from them and one of the things I’ve kind of wanted was the ability to take thoughts from today and apply them to something I will be working on in the future. The problem is that Daily Notes work off date strings and I hate doing date math in my head. So why not let espanso do it for me?

Below are two examples from my ever expanding espanso config. The first is a dual trigger expansion that creates the link to next Monday’s daily note. I really like the hotkey :>mon because it helps illustrate time passing in one direction. I use this with Tomorrow (:>1d) and Yesterday (:<1d).

Additionally, if I just want to generally schedule something for next week, it also links to next Monday’s daily note, much like the Next Week option Gmail uses for snoozing emails.

  # Next Week
  - triggers: [ ":>w", ":>mon" ]
    word: true
    replace: "{{output}}"
    vars:
      - name: output
        type: shell
        params:
          cmd: "echo `date -v +Mon \"+[[%Y-%m-%d]]\"`"

Note in the date command, the option -v +Mon forwards to next Monday. I use this in similar triggers. This is one for the upcoming Friday:

  # Next Friday
  - trigger: ":>fri"
    word: true
    replace: "{{output}}"
    vars:
      - name: output
        type: shell
        params:
          cmd: "echo `date -v +Fri \"+[[%Y-%m-%d]]\"`"

This allows me to create links to Daily Notes that haven’t been created yet, and when I finally get there, there will be a backlink to the thing I wanted to work on… and I didn’t have to try and do date math in my head!

25 Likes

Wow, that’s incredible. And to think I use Espanso only for basic text expansion.
Thanks for sharing.

1 Like

So when you create a daily note it links yesterday and tomorrow automatically or would you have to press something? pardon me I just use windows

In his script @mitzimbj after he creates the daily note he just types :bc and it outputs the links for the ‘Yesterday’ and ‘Tomorrow’ notes relative to the current daily note (the daily note related to the current day).

1 Like

Hello. Sorry to revive this old post with a somewhat unrelated question.

Is there a way to use espanso to copy two different texts and type something to paste them all at once? Here’s an example:

In Obsidian, if I wanted to link to an article or YT video, I’d type []() and copy & paste the URL into (), then do the same for the article/vid’s title in [] so that it only displays the title. But that’s twice the time and effort of copying, pasting and moving between windows.

To reduce that time & effort, I made this script:

- trigger: ":url"
    replace: "[{{title}}]()"
    vars:
      - name: "title"
        type: "clipboard"

I’ve currently set up espanso so that if I copy the article’s title and type :url in Obsidian, the output would be [{{title}}]() where {{title}} is the copied title pasted in []. I’d then manually copy & paste the URL in ().

While this is somewhat faster, it’s not that much, it still requires me to go back and forth between the browser and Obsidian windows.

I was wondering if there’s a way to copy the title first and immediately copy the URL after (or vice versa) and type :url to have espanso paste the two separate texts into the two different brackets all at once: [TITLE](URL). This requires me to only move from browser to Obsidian once.

Hope that makes sense. So far, I’ve found that you could only do this for what’s currently on the clipboard and not what was copied before it.

Also: should this be a separate post instead?

I know this isn’t strictly on point, but Alfred (mac app) does that and a hell of a lot more. I created a workflow that even takes a snapshot of the webpage using the Internet Archive. Glass Dome: prevent link rot inside markdown notes

Anyway, if you like the idea, maybe you can look at the code and adapt it to your software.

2 Likes

For Alfred’s text expansion you need the Powerpack, if I’m not wrong, which needs to be purchased. Correct?

FWIW, to grab markdown links, eg from a browser page, I use a utility called Hook – Find without searching …I used it just now for that link.

While on browser, it’s 2 key strokes, then toggle over to Obsidian and paste yields []() properly filled in. (With Keyboard Maestro (or Alfred), you could make it 1 key stroke.)

Hook btw is designed for more than that, but it has convenient side effect of easily grabbing links as markdown.

Are you on a Mac? I’ve a simple AppleScript that I trigger with ⌘⇧C in Safari and it automatically generates the link [TITLE](URL) and put it on my clipboard. More can be done to it for example I copy a lot of YouTube links this way and remove the (20) type text which YouTube puts in the title to show notifications. This is as quick as I can get and perhaps faster than using ⌘C, which would first require me to click the address bar or use another shortcut for it.

That’s right. It’s £45 for a lifetime license, which isn’t cheap, but It’s one of the best software purchases I’ve ever made. I’ve used it so much over the past 4 years that it’s become as essential as macOS itself. I’m kind of an unpaid Alfred evangelist, these days.

2 Likes

I just started using Espanso today for an atomic note template!

Just in case: If Espanso happens to expand text inconsistently, I just found a compatibility issue with running Unshaky in parallel.

Details on Reddit

Breadcrumbs is a great idea. Below is the version for Windows, written in PowerShell:

  # Breadcrumb
  - trigger: ":bc"
    word: true
    replace: "{{output}}"
    vars:
      - name: output
        type: shell
        params:
          cmd: (echo "[[$((Get-Date).AddDays(-1) | Get-Date -UFormat "%Y-%m-%d")|<< Yesterday]] | [[$((Get-Date).AddDays(+1) | Get-Date -UFormat "%Y-%m-%d")|Tomorrow >>]]")
7 Likes

Here’s a breadcrumb for Keyboard Maestro.

  • My custom version includes a separate link to a file named after the week number (at the beginning of the line, since I keep a weekly to-do list that includes the daily lists), but you can just delete that first segment.
  • I also like having the day of the week, but you can just remove the %EEEE% to get rid of it. Thought I’d save others the unicode date math in case it’s helpful.

[[2020w%ICUDateTime%ww%]] | %ICUDateTimeMinus%1%Days%EEEE% [[%ICUDateTimeMinus%1%Days%yyy-MM-dd% ]] | %ICUDateTime%EEEE yyy-MM-dd% | %ICUDateTimePlus%1%Days%EEEE% [[%ICUDateTimePlus%1%Days%yyy-MM-dd%]]

  • I have it triggered with a typed string of 3 letters. The result looks like this:

[[2020w28]] | Friday [[2020-07-10 ]] | Saturday 2020-07-11 | Sunday [[2020-07-12]]

3 Likes

Recreated OP’s in Keyboard Maestro, like the minimalistic look. Added the current date as a header to make it stand out when reminiscing.

[[%ICUDateTimeMinus%1%Days%yyy-MM-dd%|<< Yesterday]] | 
[[%ICUDateTimePlus%1%Days%yyy-MM-dd%|Tommorrow >>]]

---
#  %ICUDateTime%EEE, MMM d, yyyy%
1 Like

Thanks for the ideas in this thread.

I’ve been using fastkeys (skin for autohotkey) for a few years and taken these ideas and implemented them in fastkeys

1 Like

Thank you for this one!

Breadcrumbs for daily notes in Autohotkey for Windows:

; To run: CTRL + SHIFT + D

^+d:: 
	yesterday := a_now
	yesterday += -1, days

	tomorrow := a_now
	tomorrow += 1, days

	FormatTime, tomorrow, %tomorrow%, yyyy-MM-dd
	FormatTime, yesterday, %yesterday%, yyyy-MM-dd
	
	SendInput, << Yesterday [[Daily notes/%yesterday%|%yesterday%]] | [[Daily notes/%tomorrow%|%tomorrow%]] Tomorrow >> 
	
	Send, {Enter} {Enter} ---
Return

Depending on where your daily notes are stored you have to modify the folder indication (Daily notes/) of the backlink.

3 Likes

@chopivy, thank you so much for this - I had no idea I could combine Windows PowerShell and espanso in this way until I saw your post. Adding a day of the week calculation for Windows users, following @mitzimbj suggestions above:

 # This Monday
 - trigger: ":>mon"
   word: true
   replace: "{{output}}"
   vars:
   - name: output
     type: shell
     params:
       cmd: (echo "[[$(if([Int] (Get-Date).DayOfWeek.value__ -gt [Int] [DayOfWeek] 'Monday') {(((Get-Date).AddDays(7- ([Int] (Get-Date).DayOfWeek.value__ - [Int] [DayOfWeek] 'Monday'))) | Get-Date -UFormat "%Y-%m-%d")} Else {((Get-Date).AddDays(([Int] [DayOfWeek] 'Monday') - (Get-Date).DayOfWeek.value__) | Get-Date -UFormat "%Y-%m-%d")})]]")   

This will return [[2020-07-20]]

Limitations: I wasn’t able to find the equivalent of @mitzimbj’s -v command for Windows, so I used an if statement instead. This means that you can’t do a properly formatted link [[2020-07-20 | Monday 20 July, 2020]] as PowerShell throws an error when you try and open a second pipe | (Get-Date) inside the if and else curly { } braces. If anyone knows of a more elegant solution, I would love to hear it.

In situations where today is Monday and I want to fast-forward by a week instead (i.e. Monday > Monday) I use the # Next Week script:

# Next Week
- trigger: ":>w"
  word: true
  replace: "{{output}}"
  vars:
  - name: output
    type: shell
    params:
      cmd: (echo "[[$((Get-Date).AddDays(+7) | Get-Date -UFormat "%Y-%m-%d") | $((Get-Date).AddDays(+7) | Get-Date -UFormat "%A %d %B, %Y")]]")

Please feel free to amend and improve.

1 Like

Hi, I tried using your script in Windows and I changed it to include week name abbreviated:

FormatTime, tomorrow, %tomorrow%, yyyy-MM-dd_ddd
FormatTime, yesterday, %yesterday%, yyyy-MM-dd_ddd

So it matches by Odisidian daily notes pattern. However, when I run the script, the weekday is in lowercase, so instead of Mon I get mon, different from Obisidian behavior.

Do you know how to fix it?

_ddd is short day, try _dddd