Skip to content

Cookbook

The cookbook includes a wide range of examples of Espanso matches, all of which can be copied or adapted. It contains over 145 matches, which range from simple to advanced. Some of the matches have been adapted from examples found online. I have included links to the original source, which usually include a relevant discussion thread.

Cookbook of Espanso matches

Contents

The contents of the EspansoEdit cookbook have been reproduced online here in response to requests from Espanso users on macOS who are unable to run EspansoEdit. The code blocks are rendered with Shiki based on a YAML language grammar. This does not provide the full range of Espanso-specific highlighting that is shown in EspansoEdit.

  1. Espanso essentials
    1.1 Basic examples
    1.2 Regex triggers
    1.3 Tips and tricks

  2. Extensions
    2.1 Choice
    2.2 Date and time
    2.3 Forms

  3. Web related
    3.1 Email
    3.2 HTML and Markdown
    3.3 Outlook

  4. Script and Shell
    4.1 PowerShell inline
    4.2 PowerShell anchors
    4.3 CMD batch files

1. Espanso essentials

1.1 Basic examples

# EspansoEdit 1.9 Cookbook - 1.1 Basic examples
matches:
# Personal
- trigger: ':fn'
replace: 'forename middlename surname'
- trigger: ':adr'
replace: 'address'
- trigger: ':eml'
# Use a word trigger as the next trigger starts with the same letters
replace: 'email address'
word: true
- trigger: ':emla'
replace: 'email address alternate'
- triggers: [':tel', ':cell']
# Multiple triggers can be used to expand a match
replace: 'phone number'
# Search engine queries
- trigger: ':ddg'
replace: 'https://duckduckgo.com/?q='
- trigger: ':ggl'
replace: 'https://google.com/search?q='
- triggers: ':wiki'
replace: 'https://en.wikipedia.org/w/?search='
- trigger: ":yt"
# Insert clipboard content as query term
replace: https://youtube.com/results?q={{clipb}}'
vars: [{ name: "clipb", type: "clipboard"}]
# Miscellaneous
- trigger: ':ax'
# Enter :ax to expand in lower case and :AX to expand in capitals
replace: 'anaphylaxis'
propagate_case: true
word: true
- trigger: "committment"
# A match to correct a word that you sometimes misspell
replace: "commitment"
- trigger: ":ss1"
# A match to insert superscript number
replace: ""
- trigger: ":gcm"
replace: "git commit -m \"$|$\" - {{dat}}"
vars:
- name: dat
type: date
params:
format: "%y%m%d @ %H:%M"
- trigger: ':gom'
replace: 'git push origin main'
- trigger: ':gmo'
replace: 'git pull origin main'
- trigger: ':ip'
replace: '{{output}}'
vars:
- name: output
type: shell
params:
cmd: "curl 'https://api.ipify.org'"
- trigger: ':ecb'
# Insert clipboard text enclosed in braces
replace: '{{{{clipb}}}}'
vars: [{ name: "clipb", type: "clipboard"}]
- trigger: ':ecdq'
# Insert clipboard text enclosed in double quotes
replace: '"{{clipb}}"'
vars: [{ name: "clipb", type: "clipboard"}]
- trigger: ':ecpar'
# Insert clipboard text enclosed in parentheses
replace: '({{clipb}})'
vars: [{ name: "clipb", type: "clipboard"}]
- trigger: ':ecsb'
# Insert clipboard text enclosed in square brackets
replace: "[{{clipb}}]"
vars: [{ name: "clipb", type: "clipboard"}]
- trigger: ':ecsq'
# Insert clipboard text enclose in single quotes
replace: "'{{clipb}}'"
vars: [{ name: "clipb", type: "clipboard"}]
# Text emojis adapted from https://eelinks.short.gy/emoji
- trigger: ':hbd'
# Happy birthday text emoji
replace: "\u12DE\u13DC\u2118\u2118\u13BD \u212C\u2139\u211B\u0288\u12DE\u15EC\u13DC\u13BD"
- trigger: ':hpy'
# Happy square text emoji
replace: "\u3010\u30C4\u3011"
- trigger: ":luv"
# Love eyes text emoji
replace: "\u2665_\u2665"
- trigger: ':wfh'
# Working from home text emoji
replace: "\U0001F3E0 \u03C9\u03BF\u044F\u03BA\u03B9\u03B7g \u0192\u044F\u03BF\u043C\u043D\u03BF\u043C\u03B5"
- trigger: ':weather'
replace: '{{output}}'
vars:
- name: output
type: shell
params:
cmd: "curl 'http://wttr.in/?format=3'"

1.2 Regex triggers

# EspansoEdit 1.9 Cookbook - 1.2 Regex triggers
# NB A Regex trigger cannot exceed 30 characters in length
matches:
- regex: :(?P<greet>(?i)h)(?P<beaut>(?i)b)(?P<globe>(?i)w)(?P<end>\W)
# Use Regex to selectively capitalise any or all words in a phrase
# For example :hBW expands to hello Beautiful World
replace: '{{greet}}ello {{beaut}}eautiful {{globe}}orld{{end}}'
- regex: "(?P<month>\\d{2})/(?P<day>\\d{2})/(?P<year>\\d{2})"
# Enter trigger of type 24/11/24
replace: "Date: {{year}}-{{month}}-{{day}}"
- regex: "(?P<user>[a-z0-9._%+-]+)@(?P<domain>[a-z0-9.-]+)\\.(?P<tld>[a-z.]{5,})"
# Enter trigger of type alex@isp.com.au
replace: "User: {{user}}\nDomain: {{domain}}\nTLD: {{tld}}"
- regex: "class-(?P<cat>[a-z]+)-(?P<typ>[a-z]+)-(?P<dat>\\d+)"
# Enter trigger of type class-fiction-romantic-2023
replace: "Classification category: {{cat}}; type: {{typ}}; year: {{dat}}"
- regex: :hor(?P<hor>\d+)ver(?P<ver>\d+)\D
# Enter trigger of type :hor10ver20
# \D looks for any non-digit character to terminate the string
replace: 'Length of horizontal axis = {{hor}} cm; length of vertical axis = {{ver}} cm'
- regex: (?P<word>\S+)\s+(?P<punct>[.,;:!?])
# Removes spaces between a word and a punctuation sign
# From https://eelinks.short.gy/regex_removespaces
replace: "{{word}}{{punct}} "
- regex: "vbl\\((?P<vbl>.*?)\\)"
# Enter trigger of type vbl(xyz) followed by space
replace: "This example uses variable type {{vbl}}."
word: true
- regex: :04(?P<gp1>\d{2})(?P<gp2>\d{3})(?P<gp3>\d{3})
# Reformat an Australian mobile number with trigger of type :0444444444
replace: "04{{gp1}} {{gp2}} {{gp3}}"
- regex: :hor(?P<hor>\d+)ver(?P<ver>\d+)\D
# Enter trigger of type :hor10ver20
# \D looks for any non-digit character to terminate the string
replace: 'Length of horizontal axis = {{hor}} cm; length of vertical axis = {{ver}} cm'
- regex: ":(?P<num>\\d*)\\s*usd" # US Dollar
# Enter trigger of type :33usd
# From https://eelinks.short.gy/regx4currency
replace: "${{num}}"
- regex: ":(?P<num>\\d*)\\s*euro" # Euro
replace: "{{num}}€"
- regex: ":(?P<num>\\d*)\\s*ukp" # British Pound
replace: "£{{num}}"
- regex: ":(?P<num>\\d*)\\s*yen" # Japanese Yen
replace: "{{num}}¥"
- regex: ":(?P<num>\\d*)\\s*inr" # Indian Rupee
replace: "{{num}}?"
- regex: ":(?P<num>\\d*)\\s*swf" # Swiss Franc
replace: "{{num}} CHF"
- regex: ":(?P<num>\\d*)\\s*aud" # Australian Dollar
replace: "AU${{num}}"
- regex: ":(?P<num>\\d*)\\s*cad" # Canadian Dollar
replace: "CA${{num}}"
- regex: ":(?P<num>\\d*)\\s*hkd" # Hong Kong Dollar
replace: "HK${{num}}"
- regex: ":(?P<num>\\d*)\\s*nzd" # New Zealand Dollar
replace: "NZ${{num}}"
- regex: ":(?P<num>\\d*)\\s*won" # South Korean Won
replace: "{{num}}₩"

1.3 Tips and tricks

# EspansoEdit 1.9 Cookbook - 1.3 Tips and tricks
# To prevent a trigger from expanding press the right arrow key after the first character
# The cursor will not move and the trigger can then be entered without expanding
# Tip source: https://eelinks.short.gy/stoptrigger
matches:
- {trigger: abc, replace: def, word: true}
# A match can be entered on a single line using YAML flow style
- trigger: ':clip'
# Use clip chomp modifier + to retain trailing newlines in a block scalar
# This is the Espanso default so the + can be omitted with the same effect
replace: |+
This text will retain
the trailing newline
- trigger: ':strip'
# Use strip chomp modifier - to strip trailing newlines in a block scalar
replace: |-
This text will not retain
the trailing newline
- trigger: ':'
# Use backslash to include a special characters inside a double quoted string
replace: "There are \"known unknowns.\""
- trigger: ':ttxt1'
# Comments below the trigger will fold correctly with EspansoEdit code folding
replace: 'rtxt1'
- trigger: ':ttxt2' # Comments on the same line as the trigger also fold correctly
replace: 'rtxt2'
- trigger: ':ttxt3'
replace: 'rtxt3'
# Comments above the trigger will fold with the previous trigger
- trigger: ':ttxt4'
replace: 'rtxt4'
- trigger: ":dblbr"
comment: |
Match to show how to use replacement text in double braces
See also https://eelinks.short.gy/dblbraces
replace: "{{var}}"
comment: |
Multiple comments can be added to a match as YAML scalars
EspansoEdit wil highlight keyword comment or comments
vars:
- name: var
type: echo
inject_vars: false
params:
echo: 'Person: {{name}}; height: {{cm}} cm'
comment: A comment can be added at any indent level
- trigger: ":smile"
# A match to insert an emoji using Unicode
replace: '\U0001F603'
- trigger: ':iata'
# Labels can be used to create a menu of choices in the Espanso search bar
replace: LHR (London Heathrow Airport)
label: 1. London Heathrow
- trigger: ':iata'
replace: SYD (Sydney Kingsford-Smith Airport)
label: 2. Sydney Kingsford-Smith
- trigger: ':iata'
replace: SIN (Singapore Changi Airport)
label: 3. Singapore Changi

2. Extensions

2.1 Choice

# EspansoEdit 1.9 Cookbook - 2.1 Choice extension
# The global_vars section can be added to any YML file(s)
# Variables in this section are available globally
global_vars:
- name: genre
type: echo
params:
echo: |
Animation
Biography
Musical
matches:
- trigger: ":film"
form: |
[[choices]]
form_fields:
choices:
type: choice
values: "{{genre}}"
- trigger: :em
# From smeech at https://eelinks.short.gy/choice_email
replace: "{{output}}"
vars:
- name: output
type: choice
params:
values:
- label: 1. Gmail
id: xxx@gmail.com
- label: 2. Outlook
id: xxx@outlook.com
- trigger: ':quote'
# Example of use of choice extension
replace: '{{output}}'
vars:
- name: output
type: choice
params:
values:
- 'Every moment is a fresh beginning.'
- 'Everything you can imagine is real.'
- 'Whatever you do, do it well.'
- trigger: :cb3
replace: "First choice:{{output1}}; second choice:{{output2}}; third choice: {{output3}}"
vars:
- name: output1
type: choice
params:
values: [a, b, c]
- name: output2
type: choice
params:
values: [d, e, f]
- name: output3
type: choice
params:
values: [g, h, i]
- trigger: ':f1'
html: |
You voted <span style='color: #318CE7; text-transform:uppercase'>
{{form1.vote}}</span><br>Thanks for your vote!
vars:
- name: 'form1'
type: form
params:
layout: 'Your choice: [[vote]]'
fields:
vote:
type: list
values:
- Yes
- No
- Other
- trigger: ':f3'
form: |
[[choices]]
form_fields:
choices:
type: list
values:
- Yes
- No
- Other

2.2 Date and time

# EspansoEdit 1.9 Cookbook - 2.2 Date and time
matches:
- trigger: ':dat'
replace: '{{mydate}}'
vars:
- name: mydate
type: date
params:
format: '%d/%m/%y'
- trigger: ':datmod'
# Match to illustrate use of modifier to suppress padding of day number
# Day number is entered using %-e instead of usual %e
replace: '{{datemod}}'
vars:
- name: datemod
type: date
params:
format: "%b %-e %Y"
- trigger: ':tim'
replace: '{{time}}'
vars:
- name: time
type: date
params:
format: '%H:%M'
- trigger: ':now'
replace: "It is now {{mytime}}"
vars:
- name: mytime
type: date
params:
format: '%H.%M'
- trigger: ':tdf'
replace: '{{today}}'
label: 'Date today forwards'
vars:
- name: today
type: date
params:
format: '%-e/%-m/%y'
- trigger: ':tdb'
replace: '{{today}}'
label: 'Date today backwards'
vars:
- name: today
type: date
params:
format: '%y%m%d'
- trigger: ":tdau"
replace: "{{mydate}}"
label: 'Date today in Australian format dd/mm/YYYY'
vars:
- name: mydate
type: date
params:
format: '%x'
locale: 'en-AU'
- trigger: ':tdx'
replace: '{{today}}'
label: 'Date today forwards expanded'
vars:
- name: today
type: date
params:
format: '%a %-e %b %Y'
- trigger: ":tdto"
# Expanded example: 2024-11-14 17:23:55 UTC+11:00
replace: "{{mydate}}"
label: 'Date and time with timezone offset'
vars:
- name: mydate
type: date
params:
format: "%F %T UTC%:z"
- trigger: ':tmw'
replace: 'tomorrow'
word: true
- trigger: ':tmwf'
replace: '{{mytime}}'
vars:
- name: mytime
type: date
params:
format: '%x'
offset: 86400 # The offset parameter must be specified in seconds
- trigger: ':yd'
replace: 'yesterday'
word: true
- trigger: ':ydf'
replace: '{{mytime}}'
vars:
- name: mytime
type: date
params:
format: '%x'
offset: -86400
- trigger: :tdsel
# Date selector from https://eelinks.short.gy/dateselector
replace: "{{Output.Date}}"
vars:
- {name: Day, type: date, params: {format: '%d'}}
- {name: Month, type: date, params: {format: '%m'}}
- {name: Year2, type: date, params: {format: '%y'}}
- {name: Year4, type: date, params: {format: '%Y'}}
- {name: Another, type: date, params: {format: '%A, %B %d, %Y'}}
- name: Output
type: form
params:
layout: '[[Date]]'
fields:
Date:
type: list
values:
- '{{Day}}/{{Month}}/{{Year2}}'
- '{{Day}}-{{Month}}-{{Year2}}'
- '{{Day}}/{{Month}}/{{Year4}}'
- '{{Another}}'
- trigger: ':datcap'
replace: "{{output}}"
comment: 'Powershell script to get today in format 01FEB25'
vars:
- name: output
type: script
params:
args:
- C:\Program Files\PowerShell\7\pwsh.exe
- -Command
- |
"$((Get-Date).ToString('ddMMMyy').ToUpper())"
- regex: (?P<offset>[+-]\d+)(?P<unit>[dwmy])
# Run PowerShell script to perform date arithmetic
# Includes form for selection of date format
# Regex trigger responds to keyboard entries such as -70d or +12w
# Adapted from https://eelinks.short.gy/regex_datecalc
replace: '{{output}}'
label: Date arithmetic with extended format choice
vars:
- name: format
type: choice
params:
values:
- label: Format like Thu 27 Feb 2025
id: 'ddd d MMM yyyy'
- label: Format like 27 Feb 2025
id: 'd MMM yyyy'
- label: Format like 27/12/25
id: 'dd/MM/yy'
- name: output
type: script
params:
args:
- C:\Program Files\PowerShell\7\pwsh.exe
- -Command
- |
$OutputEncoding = [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
$format = "{{format}}"
$culture = [System.Globalization.CultureInfo]::CreateSpecificCulture("en-AU")
switch ("{{unit}}") {
"d" { $date = (Get-Date).AddDays({{offset}}).ToString($format, $culture) }
"w" { $date = (Get-Date).AddDays({{offset}} * 7).ToString($format, $culture) }
"m" { $date = (Get-Date).AddMonths({{offset}}).ToString($format, $culture) }
"y" { $date = (Get-Date).AddYears({{offset}}).ToString($format, $culture) }
}
Write-Output $date
- trigger: ':tzdat'
# Powershell script to get date and time for selected timezone
# Adapted from Python code at https://eelinks.short.gy/tzdate
replace: "{{output}}"
vars:
- name: zones
type: script
params:
args:
- C:\Program Files\PowerShell\7\pwsh.exe
- -Command
- |
[System.TimeZoneInfo]::GetSystemTimeZones() | ForEach-Object { Write-Host $_.Id }
- name: zonepick
type: form
params:
layout: 'Pick a time-zone: [[zone]]'
fields:
zone:
type: list
values: '{{zones}}'
default: AUS Eastern Standard Time
- name: output
type: script
params:
args:
- C:\Program Files\PowerShell\7\pwsh.exe
- -Command
- |
$tzId = "{{zonepick.zone}}"
$tzSysTime = [System.TimeZoneInfo]::FindSystemTimeZoneById($tzId)
$utcTime = (Get-Date).ToUniversalTime()
$tzUniTime = [System.TimeZoneInfo]::ConvertTimeFromUtc($utcTime, $tzSysTime)
Write-Output "{{zonepick.zone}}: $($tzUniTime.ToString("yyyy-MM-dd HH:mm:ss tt"))"

2.3 Forms

# EspansoEdit 1.9 Cookbook - 2.3 Forms
matches:
- trigger: ":greet"
form: |
Hi. My name is [[name]] and my email address is [[email]].
Please send me a message if you need any further details.
- trigger: :mvt
# Set the default to the last item to force the drop-down box to show all items without a scrollbar
form: "[[arrows]]"
form_fields:
arrows:
type: choice
values:
- "\u2190"
- "\u2191"
- "\u2192"
- "\u2193"
- "\u2194"
- "\u2195"
- "\u2196"
- "\u2197"
- "\u2198"
- "\u2199"
default: "\u2199"
- trigger: ':f2'
markdown: |
**{{form1.vote}}**
vars:
- name: 'form1'
type: form
params:
layout: '[[vote]]'
fields:
vote:
type: list
values:
- 1
- Yes
- 2
- No
- 3
- Other
- trigger: ':fmix'
# Example of a form trigger that combines a text field with a list field
replace: |
Name: {{form1.name}}
Gender: {{form1.gender}}
vars:
- name: 'form1'
type: form
params:
layout: |
What is your name?: [[name]]
What is your gender?: [[gender]]
fields:
gender:
type: list
values:
- Male
- Female
- Other
- trigger: ":fprompt"
# Include prompt text in multiline text boxes
# Adapted from: https://eelinks.short.gy/textbox_prompt
form: |
What is your issue?
[[text1]]
What are your contact details?
[[text2]]
form_fields:
text1:
type: textarea
default: |
Add details of your issue here
Add contact details below
multiline: true
text2:
type: textarea
default: |
Add your best contact here
Add issue details above
multiline: true
- trigger: ":outflow"
# Example of a form trigger that wraps outputs with a folded text scalar
# To make the form easy to read and edit the layout uses a literal block scalar
replace: >
The first item was depicted in {{form1.color1}};
the second item was depicted in {{form1.color2}};
the third item was depicted in {{form1.color3}};.
vars:
- name: "form1"
type: form
params:
layout: |
The first item was depicted in [[color1]];
the second item was depicted in [[color2]];
the third item was depicted in [[color3]].
- trigger: ':bing'
replace: 'https://www.bing.com/search?q={{fm.to}}{{fm.cc}}{{fm.fs}}{{fm.ft}}{{fm.wl}}{{fm.tx}}'
vars:
- name: fm
type: form
params:
layout: |
Submit ONE of the following options for Bing search
Topic - e.g. espanso
[[to]]
Topic by country - e.g. espanso loc:uk
[[cc]]
Files of type on site - e.g. espanso.org contains:pdf
[[fs]]
Files of type on topic - e.g espanso contains:pdf
[[ft]]
Weather at location - e.g. weather seoul
[[wl]]
Topic but exclude keyword - e.g. face NOT facebook
[[tx]]

3.1 Email

# EspansoEdit 1.9 Cookbook - 3.1 Email
matches:
- regex: ':em(;|a)'
# Enter :em; to display a menu of email addresses in the Espanso search bar
# Or enter a trigger such as :ema to expand a single email address directly
replace: 'alex@contacts.com'
- regex: ':em(;|b)'
replace: 'blake@contacts.com'
- regex: ':em(;|c)'
replace: 'chris@contacts.com'
- trigger: ':sig'
replace: |
My name
My personal blog: https://mydomain.com/
_.~"~._.~"~._.~"~._.~"~._
word: true
- trigger: ':sig2'
# Signature from image file
image_path: '$CONFIG/img/signature.png'
- trigger: ':soc'
replace: "Twitter: @mydomain\nFacebook: https://www.facebook.com/mydomain\nLinkedIn: https://www.linkedin.com/in/mydomain"

3.2 HTML and Markdown

# EspansoEdit 1.9 Cookbook - 3.2 HTML and Markdown
matches:
- trigger: ':bold'
replace: '<b>$|$</b>'
- trigger: ':br'
replace: '<br />'
- trigger: ':div'
replace: '<div>$|$</div>'
- trigger: ':fraction'
replace: '<sup>$|$</sup>&frasl;<sub></sub>'
- trigger: ':h1'
replace: '<h1>$|$</h1>'
- trigger: ':h2'
replace: '<h2>$|$</h2>'
- trigger: ':h3'
replace: '<h3>$|$</h3>'
- trigger: ':hr'
replace: '<hr />'
- trigger: ':img'
replace: "<img src=\"$|$\" alt=\"\" />"
- trigger: ":link"
# Create HTML link using URL from clipboard
replace: "<a href=\"{{clipb}}\" />$|$</a>"
vars:
- name: "clipb"
type: "clipboard"
- trigger: ':list'
replace: "<ol>\n <li>$|$"
- trigger: ':para'
replace: '<p>$|$</p>'
- trigger: ':span'
replace: '<span>$|$</span>'
- trigger: ':sub'
replace: '<sub>$|$</sub>'
word: true
- trigger: ':subsml'
replace: '<sub><small>$|$</small></sub>'
- trigger: ':sup'
replace: '<sup>$|$</sup>'
word: true
- trigger: 'supsml'
replace: '<sup><small>$|$</small></sup>'
- trigger: ':mdcb'
# Insert a Markdown code block
replace: "```\n$|$\n```"
- trigger: ':mdexp'
# Markdown expandable/collapsible section
# Cursor positioned for heading; add content below
replace: "<details>\n<summary>$|$</summary>\n<p></p>\n</details>"
- trigger: ':mdimg'
# Insert a Markdown image link
replace: '[$|$]()'
- trigger: ':mdlnk'
# Create Markdown link using URL from clipboard
replace: "[$|$]({{clipb}})"
vars:
- name: "clipb"
type: "clipboard"
- trigger: ':mdformlnk'
# Create Markdown link from form input
replace: '[{{form1.title}}]({{form1.link}})'
vars:
- name: form1
type: form
params:
layout: |
Title:[[title]]
URL:[[link]]
- trigger: ':mdtbl'
# Create a two column table
replace: |
| {{frm.hdr1}} | {{frm.hdr2}} |
| --- | --- |
vars:
- name: 'frm'
type: form
params:
layout: |
Column1 header: [[hdr1]]
Column2 header: [[hdr2]]
- regex: ':ml(?P<page>.*?):'
# Create Markdown link to page on your domain
# Enter trigger of type :mlpage:
replace: "[{{page}}](https://mydomain.com/{{page}})"
- regex: code:(?P<lang>.*)\s
# Convert a copied code block into a Markdown code block with syntax highlighting
# Enter trigger code:{lang} to specify the relevant code language
# For plain text enter trigger code:
# Adapted from https://eelinks.short.gy/md2txt
replace: |-
```{{lang}}
{{clipb}}
```
vars:
- name: "clipb"
type: "clipboard"
- trigger: ":mfn"
# Create a Markdown footnote
# Adapted from https://eelinks.short.gy/mdfootnote
replace: "[^{{form1.ref}}]\n\n[^{{form1.ref}}]: {{form1.def}}"
vars:
- name: "form1"
type: form
params:
layout: |
Footnote elements
Reference identifier: [[ref]]
Definition text: [[def]]
- trigger: ':md2txt'
# Convert Markdown to plain text
# Adapted from https://eelinks.short.gy/md2txt
replace: "{{output}}"
vars:
- name: output
type: script
params:
args:
- C:\Program Files\PowerShell\7\pwsh.exe
- -Command
- |
# Function to convert Markdown to plain text
function Convert-MarkdownToText {
param (
[string]$markdown
)
# Split the input into lines to process each line individually
$lines = $markdown -split "`n"
$inCodeBlock = $false
$plainTextLines = $lines | ForEach-Object {
# Toggle code block flag when encountering ``` lines
if ($_ -match '^\s*```') {
$inCodeBlock = -not $inCodeBlock
# Skip the ``` lines themselves
return
}
# Capture content without modification if in a code block
if ($inCodeBlock) {
return $_
}
# Process each line for Markdown syntax if not in a code block
$_ -replace '^\s*#{1,6}\s*(.+)$', '$1' | # Headers
ForEach-Object { $_ -replace '\*\*([^\*]+)\*\*', '$1' } | # Bold
ForEach-Object { $_ -replace '\*([^\*]+)\*', '$1' } | # Italic
ForEach-Object { $_ -replace '__(.+?)__', '$1' } | # Bold underline
ForEach-Object { $_ -replace '_(.+?)_', '$1' } | # Italic underline
ForEach-Object { $_ -replace '\[([^\]]+)\]\([^\)]+\)', '$1' } | # Links
ForEach-Object { $_ -replace '!\[([^\]]*)\]\([^\)]+\)', '$1' } | # Images
ForEach-Object { $_ -replace '`(.+?)`', '$1' } | # Inline code
ForEach-Object { $_ -replace '``(.+?)``', '$1' } | # More inline code
ForEach-Object { $_ -replace '^\s*[-\*\+]\s+', '' } | # Unordered list markers
ForEach-Object { $_ -replace '^\s*\d+\.\s+', '' } | # Ordered list markers
ForEach-Object { $_ -replace '^\s*>\s+', '' } | # Blockquotes
ForEach-Object { $_ -replace '\[\[([^\]]+)\]\]', '$1' } # [[Text]]
}
# Join the processed lines back into a single string
$plainText = ($plainTextLines -join "`n").Trim()
return $plainText
}
# Convert input from Markdown to plain text
$markdownText = Get-Clipboard
$plainText = Convert-MarkdownToText -markdown $markdownText
Write-Output $plainText

3.3 Outlook

# EspansoEdit 1.9 Cookbook - 3.3 Outlook
matches:
# Outlook search filter shortcuts
- regex: ':ol(;|b)'
replace: 'body:'
label: 'Outlook body'
- regex: ':ol(;|f)'
replace: 'from:'
label: 'Outlook from'
- regex: ':ol(;|ha)'
replace: 'hasattachment:true'
label: 'Outlook has attachment'
- regex: ':ol(;|hf)'
replace: 'hasflag:true'
label: 'Outlook has flag'
- regex: ':ol(;|s)'
replace: 'subject:'
label: 'Outlook subject'
- regex: ':ol(;|t)'
replace: 'to:'
label: 'Outlook to'
# Other Outlook shortcuts
- regex: ':ol(;|tf)'
# Replace MyUserName with your actual username
replace: '{{output}}'
label: 'Open Outlook template folder'
vars:
- name: output
type: shell
params:
cmd: "start \"C:\\Users\\MyUserName\\AppData\\Roaming\\Microsoft\\Templates\\\""
- trigger: ':olevent'
# Run PowerShell script to add an Outlook event
replace: '{{output}}'
vars:
- name: output
type: script
params:
args:
- C:\Program Files\PowerShell\7\pwsh.exe
- -Command
- |
# Adapted from https://eelinks.short.gy/ps_olevent
$outlook = new-object -com outlook.application
$CalItem = "1"
$newAppt = $outlook.CreateItem($CalItem)
$newAppt.Body = "Test text from EspansoEdit Cookbook using PowerShell"
$newAppt.Subject = "Test event from EspansoEdit Cookbook"
$DateString = Get-Date
$newAppt.Start = $DateString
$newAppt.AllDayEvent = 1
$newAppt.ReminderSet = 0
$newAppt.BusyStatus = 0
$newAppt.Save()

4. Script and Shell

4.1 PowerShell inline

# EspansoEdit 1.9 Cookbook - 4.1 PowerShell inline scripts
# There are additional PowerShell inline scripts in section 2.2 Date and time
matches:
- trigger: ':wex'
# Run Windows Explorer
replace: "{{output}}"
vars:
- name: output
type: script
params:
args:
- C:\Program Files\PowerShell\7\pwsh.exe
- -Command
- Start-Process -FilePath "c:\windows\explorer.exe"
- trigger: ':dato'
# Output today's date in ordinal format Friday November 1st 2024
# Function adapted from: https://eelinks.short.gy/ps_dateordinal
replace: '{{output}}'
vars:
- name: output
type: script
params:
args:
- C:\Program Files\PowerShell\7\pwsh.exe
- -Command
- |
function Get-DaySuffix {
Param([System.DateTime]$date)
switch ($date.Day) {
{$_ -in 1,21,31} { 'st'}
{$_ -in 2,22} { 'nd'}
{$_ -in 3,23} { 'rd'}
Default {'th'}
}
}
$d = (Get-Date).AddDays(0)
$ds = Get-DaySuffix $d
"{0} {1:MMMM} {2}{3} {4}" -f $d.DayOfWeek, $d, $d.Day, $ds, $d.Year
- regex: (?P<count>[+]\d+)(?P<unit>[n])
# Output clipboard text n times with numbering
# Trigger is of type +3n
replace: "{{output}}"
vars:
- name: output
type: script
params:
args:
- C:\Program Files\PowerShell\7\pwsh.exe
- -Command
- |
$raw = Get-Clipboard
1..{{count}} | ForEach-Object {Write-Host "$raw" $_.ToString().PadLeft(2, '0') -separator ''}
- trigger: ":e2new"
# Use a form as a basic GUI to add a new match to a match file
# Adapted from https://eelinks.short.gy/form_addmatch
replace: "{{output}}"
vars:
- name: 'form1'
type: form
params:
layout: |
Add a new match
Trigger [[trig]]
Replace [[repl]]
Word [[word]]
fields:
word:
type: list
values: |
true
false
default: 'false'
- name: output
type: script
params:
args:
- C:\Program Files\PowerShell\7\pwsh.exe
- -Command
- |
$trig = '{{form1.trig}}'
$repl = "{{form1.repl}}"
$word = "{{form1.word}}"
"`n` - trigger: $trig`n` replace: $repl`n` word: $word" `
| Out-File -FilePath $env:APPDATA\\espanso\\match\\base.yml `
-Append -Encoding Utf8
- trigger: :getnum
# Example of use of a trigger with Excel automation
# A form is used to prompt for client name
# The name is then matched in a spreadsheet and client file number is obtained
replace: "{{output}}"
vars:
- name: "form1"
type: form
params:
layout: |
Client name: [[cname]]
- name: output
type: script
params:
args:
- C:\Program Files\PowerShell\7\pwsh.exe
- -Command
- |
$raw = "{{form1.cname}}"
$Excel = New-Object -ComObject Excel.Application
$Workbook = $Excel.Workbooks.Open('c:\YourPath\YourSpreadsheet.xlsx')
$WorkSheet = $Workbook.Sheets.Item(IndexOfYourWorksheet)
$Found = $WorkSheet.Cells.Find($raw)
# Next line applies if file number is in next column
$FileNum = $WorkSheet.Cells($Found.Row, $Found.Column + 1)
Write-Host "Client name:" $raw "; client file number:" $FileNum.Value()
- trigger: ':fillform'
# Example of use of a trigger to tab between fields on a form
replace: '{{output}}'
vars:
- name: output
type: script
params:
args:
- C:\Program Files\PowerShell\7\pwsh.exe
- -Command
- |
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.SendKeys]::SendWait("{BACKSPACE}{BACKSPACE}{BACKSPACE}A")
Start-Sleep -Milliseconds 50
[System.Windows.Forms.SendKeys]::SendWait("{TAB}")
Start-Sleep -Milliseconds 50
[System.Windows.Forms.SendKeys]::SendWait("B")
Start-Sleep -Milliseconds 50
[System.Windows.Forms.SendKeys]::SendWait("{TAB}")
Start-Sleep -Milliseconds 50
[System.Windows.Forms.SendKeys]::SendWait("C")
Start-Sleep -Milliseconds 50
[System.Windows.Forms.SendKeys]::SendWait("{TAB}")
- trigger: ':ee'
# Example of use of a trigger to launch a program
replace: "{{output}}"
vars:
- name: output
type: script
params:
args:
- C:\Program Files\PowerShell\7\pwsh.exe
- -Command
- Start-Process -FilePath "C:\Users\Cam\AppData\Local\Programs\EspansoEdit\EspansoEdit.exe"

4.2 PowerShell anchors

# EspansoEdit 1.9 Cookbook - 4.2 Powershell anchor scripts
# These scripts make use of YAML anchors and aliases
# The keywords anchors: and anchor: are arbitrary
# It is essential to use & to denote an anchor and * to reference an anchor
anchors:
- anchor: &crew1 |
Name: John Doe
Date of birth: 27/1/59
Record number: 123456
- anchor: &crew2 |
Name: Jane Doe
Date of birth: 22/2/72
Record number: 654321
- anchor: &e2log |
# Output Espanso log
$e2 = 'C:\Users\Cam\AppData\Local\Programs\Espanso\espansod.exe'
&$e2 log | Out-File -FilePath $env:TEMP\tmp.log
$Array = Get-Content -Path $env:TEMP\tmp.log
[array]::Reverse($Array)
$Length = $Array.count
$Line = 1
$1..$Length | ForEach-Object {$Array[-$Line]; $Line++}
- anchor: &e2log10 |
# Output last 10 lines of Espanso log
$Array = Get-Content -Path $env:LocalAppData\espanso\espanso.log -Tail 10
$Length = $Array.count
$Line = 1
$1..$Length | ForEach-Object {$Array[-$Line]; $Line++}
# An anchor can be used to reference a file containing a PowerShell script
# Here the reference is to a script (not included) used to list installed apps
# Such a script (and more) can be found at https://eelinks.short.gy/ps_fleschutz
- anchor: &listapps |
& d:\temp\ps_listapps.ps1
- anchor: &quotestr |
$raw = Get-Clipboard
Write-Host ("""$raw""")
- anchor: &tempconv |
# Conversion functions from https://eelinks.short.gy/ps_tempconv
function Convert-CelsiusToFahrenheit {
param (
[double]$celsius
)
$fahrenheit = ($celsius * 9/5) + 32
return $fahrenheit }
function Convert-FahrenheitToCelsius {
param (
[double]$fahrenheit
)
$celsius = ($fahrenheit - 32) * 5/9
return $celsius }
$tmp = {{tmp}}
$f = Convert-CelsiusToFahrenheit -celsius $tmp
$f = [math]::Round($f, 2)
$c = Convert-FahrenheitToCelsius -fahrenheit $tmp
$c = [math]::Round($c, 2)
$result = switch ("{{unit}}") {
"c" {Write-Host $tmp{c =}$f{f}; break}
"f" {Write-Host $tmp{f =}$c{c}; break}
default {Write-Host "Correctly formatted entry not detected"; break} }
- anchor: &wordcount |
$filePath = "D:\temp\test.bat"
$stats = Get-Content $filePath | Measure-Object -Word -Line -Character
"Words: $($stats.Words); Lines: $($stats.Lines); Characters: $($stats.Characters)"
matches:
- regex: !tempconv (?P<tmp>[+-]\d+)(?P<unit>[cf])
# Run PowerShell script to perform temperature conversion
# Regex trigger responds to keyboard entries such as -3c or +100f
replace: '{{output}}'
label: Temperature conversion with PowerShell
vars:
- name: output
type: script
params:
args: [C:\Program Files\PowerShell\7\pwsh.exe, -Command, *tempconv]
- trigger: ':crew'
form: '[[crew]]'
form_fields:
crew:
type: choice
values:
- *crew1
- *crew2
default: *crew2
- trigger: 'e2log'
# Use shell extension to get Espanso log forwards - latest at bottom
replace: '{{output}}'
word: true
vars:
- name: output
type: script
params:
args: [C:\Program Files\PowerShell\7\pwsh.exe, -Command, *e2log]
- trigger: 'e2log10'
# Run PowerShell script to get last 10 lines of Espanso log using shell extension
replace: '{{output}}'
vars:
- name: output
type: script
params:
args: [C:\Program Files\PowerShell\7\pwsh.exe, -Command, *e2log10]
- trigger: ':listapps'
replace: '{{output}}'
label: PowerShell test
vars:
- name: output
type: script
params:
args: [C:\Program Files\PowerShell\7\pwsh.exe, -Command, *listapps]
- trigger: ':quotestr'
replace: '{{output}}'
vars:
- name: output
type: script
params:
args: [C:\Program Files\PowerShell\7\pwsh.exe, -Command, *quotestr]
- trigger: ':wordcount'
replace: '{{output}}'
vars:
- name: output
type: script
params:
args: [C:\Program Files\PowerShell\7\pwsh.exe, -Command, *wordcount]

4.3 CMD batch files

# EspansoEdit 1.9 Cookbook - 4.3 CMD batch files
matches:
- trigger: ':inln'
# Example of inline use of batch commands
replace: '{{output}}'
vars:
- name: output
type: shell
params:
cmd: >
cmd /v:on /c
"echo. &
echo ***DIR*** &
echo. &
dir *.*"
- trigger: ':ipc'
# Another example of inline use of batch commands
replace: '{{output}}'
vars:
- name: output
type: shell
params:
cmd: >
cmd /v:on /c
"echo. &
echo ***DIR*** &
echo. &
dir *.* &
echo. &
echo ***IPCONFIG*** &
ipconfig"
- trigger: ':bfm'
# Example of form entry with batch commands
replace: '{{output}}'
vars:
- name: 'form1'
type: form
params:
layout: 'Enter a number with at least 4 digits: [[anum]]'
- name: 'output'
type: 'shell'
params:
cmd: >
cmd /v:on /c
"echo. &
echo ***Last 3 digits of your number*** &
set input={{form1.anum}} &
set result=!input:~-4! & echo !result!"