github espanso/espanso v0.7.0

latest releases: v2.2.1, v2.2.0, v2.1.8...
3 years ago

Version 0.7.0 is here, and brings a few very powerful features!

Forms

Note: this feature is still experimental, so expect a few rough edges. If you encounter any problem, please open an issue :)

One of the most requested features is finally here: forms!

macform

This opens up a world of possibilities, such as creating matches with multiple parameters and scripts with arguments.

Installation

To avoid bloating espanso with unnecessary dependencies, this feature is extracted as a separate component, modulo.

Windows and macOS users

If you are a Windows or macOS user, the latest version of espanso automatically ships with modulo, so you don't have to install anything.

Linux users

Due to the great fragmentation in the linux world, I decided to package modulo as an AppImage. In order to use it from espanso, you'll have to complete these steps:

  1. Download the AppImage from the modulo's Releases page.
  2. Copy it in a reasonable directory, such as $HOME/opt
  3. Make it executable with chmod u+x modulo*.AppImage
  4. In order to make it usable from espanso, modulo has to be visible in the PATH as modulo. The easiest way to achieve it is creating a link with:
sudo ln -s $HOME/opt/modulo*.AppImage /usr/bin/modulo

Simple example

To try out the new feature, create a new match as follows:

  - trigger: ":form"
    form: "Hey {{name}}, how are you?"

Reload the changes and type ":form". If you did everything correctly, you should see a form appear!

form

To submit the value you have 2 alternatives, you can either:

  • Press the CTRL+Enter shortcut
  • Click the "Submit" button

Explanation

As you can see from the example, instead of using the usual replace clause, we used form. This is just syntactic sugar to make it easier to use forms, but in the following sections you will learn the complete syntax, necessary if you want to use forms with scripts.

The only important thing to notice is that where we wanted to put a field in the form, we used the double brakets syntax {{field_name}}.

Controls

In the example we've just seen, only a simple text field was used, but modulo supports other controls, such as multiline text fields, choice boxes and list boxes (with more to come in future versions).

To specify the control type, you have to specify the form_fields param. An example would be:

  - trigger: ":form"
    form: |
      Hey {{name}},
      {{text}}
      {{greet}}
    form_fields:
      text:
        multiline: true
      greet:
        type: choice
        values:
          - First choice
          - Second choice

Which produces this result:

exampleform

Some of you might be confused with the | char. That is used to specify a multiline string in YAML

In this example we can see:

  • The text field is now a multiline text field
  • The greet field is a Choice box

Improvements in the variable system

Before diving into the next section, it might be useful to explain some of the variable system improvements that were introduced to support forms in the first place.

Starting from version 0.7.0, most variables can now use the value of other (previously declared) variables in their body.

Not all variable types support variable injection, but notably Shell and Script extensions do through the use of ad-hoc environment variables. Take the following example:

Let's say we want to reverse the string produced by the Date Extension:

- trigger: ":reversed"
  replace: "Reversed {{myshell}}"
  vars:
    - name: mytime
      type: date
      params:
        format: "%H:%M"
    - name: myshell
      type: shell
      params:
        cmd: "echo $ESPANSO_MYTIME | rev"

This match produces the result we expected. If the current time was 11:54, it produces:

Reversed 45:11

Let's analyze it step by step:

  1. Variable mytime is evaluated first (as it's the first declared in the vars list).
  2. It's output is injected in the myshell shell command, in particular through the $ESPANSO_MYTIME env variable.
  3. The result is piped through the unix rev command
  4. Finally the output is included in the replace text and expanded.

As you might have already guessed, the previous variables are injected in the Shell variable (and the Script extension works in the same way) with the naming ESPANSO_UPPERCASE-VAR-NAME.

Make sure to avoid spaces in the variable names, as they can become problematic in this situation

If you are using global variables, you have to be careful in this case, as they are implicitly evaluated before the local ones.

If you need to evaluate a global variable after a local one (which might be necessary if you want to inject another variable value inside it), you can do so as follows:

# Considering the following global variable
global_vars:
  - name: "reversed"
    type: shell
    params:
      cmd: "echo $ESPANSO_VARNAME | rev"

matches:
  - trigger: ":rev"
    replace: "{{reversed}}"
    vars:
      - name: "varname"
        type: echo
        params:
          echo: "hello"
      - name: "reversed"
        type: "global"

The key element here is the global type, which tells espanso to evaluate variable reversed only at that point, and not before varname.

Using forms with the Script and Shell extension

Hopefully, you now understand how variable values are injected between one another. Turns out, forms are variables as well!

In fact, our first example:

  - trigger: ":form"
    form: "Hey {{name}}, how are you?"

is a shorthand for the following match:

  - trigger: ":form"
    replace: "Hey {{form1.name}}, how are you?"
    vars:
      - name: "form1"
        type: form
        params:
          layout: "Hey {{name}}, how are you?"

What this does is simply generating a form with the given layout, and then injecting the resulting fields (form1.name) into the replacement text.

All right, but how can we use forms with the shell extension?

Let's say that we want to create a match that prompts for user input, and then expands to the reverse of what the user inserted.
That could be implemented with:

  - trigger: ":rev"
    replace: "{{reversed}}"
    vars:
    - name: form1
      type: form
      params:
        layout: |
          Reverse {{name}}
    - name: reversed
      type: shell
      params:
       cmd: "echo $ESPANSO_FORM1_NAME | rev"

The key aspect here is that the value of the form field is injected in the shell variable as ESPANSO_FORM1_NAME. The naming is pretty straightforward, as the form variable is called form1 and the field is called name.

macOS remarks

For the expansion to take place on macOS, you have to release the submit keys (CTRL+Enter) after submitting the form.

Backspace Undo

Another highly requested feature was backspace-to-undo:

If you press backspace immediately after an expansion takes place, the expansion is reversed:

backspace

If for some reason you need to backspace without reverting the expansion, press SHIFT+BACKSPACE instead.

You can disable it with:

undo_backspace: false

Please note that this feature is experimental, so if you notice any problem please open an issue!

Other changes

  • Avoid showing the Console/Powershell window on Windows when using the Shell extension. Fix #249
  • Add offset parameter to Date extension to express dates before/after the current one. See #311
  • The Windows icon now turns red when espanso is disabled. #293
  • Added a debug option to shell commands to understand what is going on under the hoods. Thanks to @deckarep #355
  • General improvements to the Passive Mode. Thanks to @AndydeCleyre See #372
  • Avoid reloading configuration if triggered by hidden files. Fix #393

Don't miss a new espanso release

NewReleases is sending notifications on new releases.