Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Espanso: Fix broken module to be compatible with Espanso version 2.x #4066

Merged
merged 10 commits into from Jun 9, 2023
6 changes: 6 additions & 0 deletions modules/lib/maintainers.nix
Expand Up @@ -400,4 +400,10 @@
github = "pedorich-n";
githubId = 15573098;
};
liyangau = {
name = "Li Yang";
email = "d@aufomm.com";
github = "liyangau";
githubId = 71299093;
};
}
120 changes: 83 additions & 37 deletions modules/services/espanso.nix
@@ -1,19 +1,22 @@
{ pkgs, config, lib, ... }:

let

inherit (lib)
mkOption mkEnableOption mkIf maintainers literalExpression types platforms;
mkOption mkEnableOption mkIf maintainers literalExpression types platforms
mkRemovedOptionModule versionAtLeast;

inherit (lib.hm.assertions) assertPlatform;

cfg = config.services.espanso;
espansoVersion = cfg.package.version;

yaml = pkgs.formats.yaml { };

in {
meta.maintainers = with maintainers; [ lucasew ];

imports = [
(mkRemovedOptionModule [ "services" "espanso" "settings" ]
"Use services.espanso.configs and services.espanso.matches instead.")
];
meta.maintainers =
[ lib.hm.maintainers.liyangau maintainers.bobvanderlinden ];
liyangau marked this conversation as resolved.
Show resolved Hide resolved
options = {
services.espanso = {
enable = mkEnableOption "Espanso: cross platform text expander in Rust";
Expand All @@ -25,53 +28,96 @@ in {
defaultText = literalExpression "pkgs.espanso";
};

settings = mkOption {
configs = mkOption {
type = yaml.type;
default = { matches = [ ]; };
default = { default = { }; };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need a default?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am following previous config here. I guess there is no harm to set an empty default when the users do not provide anything.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, sorry, I was unclear. I meant: do we need a default that's not just {}? I.e., why the default inside the default?

Copy link
Contributor Author

@liyangau liyangau Jun 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use default = { }; inside default is to create an empty ~/.config/espanso/config/default.yml when it is not set.

Without it, Espanso will throw below error.

[ERROR] unable to load config

Caused by:
    missing config directory

example = literalExpression ''
{
matches = [
{ # Simple text replacement
trigger = ":espanso";
replace = "Hi there!";
}
{ # Dates
trigger = ":date";
replace = "{{mydate}}";
vars = [{
name = "mydate";
type = "date";
params = { format = "%m/%d/%Y"; };
}];
}
{ # Shell commands
trigger = ":shell";
replace = "{{output}}";
vars = [{
name = "output";
type = "shell";
params = { cmd = "echo Hello from your shell"; };
}];
}
];
}
default = {
show_notifications = false;
};
vscode = {
filter_title = "Visual Studio Code$";
backend = "Clipboard";
};
};
'';
description = ''
The Espanso configuration to use. See
<link xlink:href="https://espanso.org/docs/configuration/"/>
<link xlink:href="https://espanso.org/docs/configuration/basics/"/>
for a description of available options.
'';
};

matches = mkOption {
type = yaml.type;
default = { default.matches = [ ]; };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

example = literalExpression ''
{
base = {
matches = [
{
trigger = ":now";
replace = "It's {{currentdate}} {{currenttime}}";
}
{
trigger = ":hello";
replace = "line1\nline2";
}
{
regex = ":hi(?P<person>.*)\\.";
replace = "Hi {{person}}!";
}
];
};
global_vars = {
global_vars = [
{
name = "currentdate";
type = "date";
params = {format = "%d/%m/%Y";};
}
{
name = "currenttime";
type = "date";
params = {format = "%R";};
}
];
};
};
'';
description = ''
The Espanso matches to use. See
<link xlink:href="https://espanso.org/docs/matches/basics/"/>
for a description of available options.
'';
};
};
};

config = mkIf cfg.enable {
assertions = [ (assertPlatform "services.espanso" pkgs platforms.linux) ];
assertions = [
(assertPlatform "services.espanso" pkgs platforms.linux)
{
assertion = versionAtLeast espansoVersion "2";
message = ''
Only support version Espanso version 2
liyangau marked this conversation as resolved.
Show resolved Hide resolved
'';
}
];

home.packages = [ cfg.package ];

xdg.configFile."espanso/default.yml".source =
yaml.generate "espanso-default.yml" cfg.settings;
xdg.configFile = let
configFiles = lib.mapAttrs' (name: value: {
name = "espanso/config/${name}.yml";
value = { source = yaml.generate "${name}.yml" value; };
}) cfg.configs;
matchesFiles = lib.mapAttrs' (name: value: {
name = "espanso/match/${name}.yml";
value = { source = yaml.generate "${name}.yml" value; };
}) cfg.matches;
in configFiles // matchesFiles;

systemd.user.services.espanso = {
Unit = { Description = "Espanso: cross platform text expander in Rust"; };
Expand Down
63 changes: 38 additions & 25 deletions tests/modules/services/espanso/basic-configuration.nix
Expand Up @@ -3,31 +3,40 @@
{
services.espanso = {
enable = true;
settings = {
matches = [
{ # Simple text replacement
trigger = ":espanso";
replace = "Hi there!";
}
{ # Dates
trigger = ":date";
replace = "{{mydate}}";
vars = [{
name = "mydate";
configs = {
default = { show_notifications = false; };
};
matches = {
base = {
matches = [
{
trigger = ":now";
replace = "It's {{currentdate}} {{currenttime}}";
}
{
trigger = ":hello";
replace = ''
line1
line2'';
}
{
regex = ":hi(?P<person>.*)\\.";
replace = "Hi {{person}}!";
}
];
global_vars = [
{
name = "currentdate";
type = "date";
params = { format = "%d/%m/%Y"; };
}
{
name = "currenttime";
type = "date";
params = { format = "%m/%d/%Y"; };
}];
}
{ # Shell commands
trigger = ":shell";
replace = "{{output}}";
vars = [{
name = "output";
type = "shell";
params = { cmd = "echo Hello from your shell"; };
}];
}
];
params = { format = "%R"; };
}
];
};
};
};

Expand All @@ -38,8 +47,12 @@
assertFileExists "$serviceFile"
assertFileContent "$serviceFile" ${./basic-configuration.service}

configFile=home-files/.config/espanso/default.yml
configFile=home-files/.config/espanso/config/default.yml
assertFileExists "$configFile"
assertFileContent "$configFile" ${./basic-configuration.yaml}

matchFile=home-files/.config/espanso/match/base.yml
assertFileExists "$matchFile"
assertFileContent "$matchFile" ${./basic-matches.yaml}
'';
}
18 changes: 1 addition & 17 deletions tests/modules/services/espanso/basic-configuration.yaml
@@ -1,17 +1 @@
matches:
- replace: Hi there!
trigger: :espanso
- replace: '{{mydate}}'
trigger: :date
vars:
- name: mydate
params:
format: '%m/%d/%Y'
type: date
- replace: '{{output}}'
trigger: :shell
vars:
- name: output
params:
cmd: echo Hello from your shell
type: shell
show_notifications: false
18 changes: 18 additions & 0 deletions tests/modules/services/espanso/basic-matches.yaml
@@ -0,0 +1,18 @@
global_vars:
- name: currentdate
params:
format: '%d/%m/%Y'
type: date
- name: currenttime
params:
format: '%R'
type: date
matches:
- replace: It's {{currentdate}} {{currenttime}}
trigger: :now
- replace: 'line1

line2'
trigger: :hello
- regex: :hi(?P<person>.*)\.
replace: Hi {{person}}!