commit
82771dd761
1
.github/FUNDING.yml
vendored
1
.github/FUNDING.yml
vendored
|
@ -1,4 +1,3 @@
|
||||||
# These are supported funding model platforms
|
# These are supported funding model platforms
|
||||||
|
|
||||||
github: ['federico-terzi']
|
|
||||||
custom: ['https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FHNLR5DRS267E&source=url']
|
custom: ['https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FHNLR5DRS267E&source=url']
|
||||||
|
|
4
.github/scripts/ubuntu/build_deb.sh
vendored
4
.github/scripts/ubuntu/build_deb.sh
vendored
|
@ -8,10 +8,10 @@ cargo install cargo-deb --version 1.34.0
|
||||||
cd espanso
|
cd espanso
|
||||||
|
|
||||||
echo "Building X11 deb package"
|
echo "Building X11 deb package"
|
||||||
cargo deb -p espanso
|
cargo deb -p espanso -- --no-default-features --features "modulo vendored-tls"
|
||||||
|
|
||||||
echo "Building Wayland deb package"
|
echo "Building Wayland deb package"
|
||||||
cargo deb -p espanso --variant wayland -- --features wayland
|
cargo deb -p espanso --variant wayland -- --no-default-features --features "modulo wayland vendored-tls"
|
||||||
|
|
||||||
cd ..
|
cd ..
|
||||||
cp espanso/target/debian/espanso_*.deb espanso-debian-x11-amd64.deb
|
cp espanso/target/debian/espanso_*.deb espanso-debian-x11-amd64.deb
|
||||||
|
|
1
.github/workflows/ci.yml
vendored
1
.github/workflows/ci.yml
vendored
|
@ -16,6 +16,7 @@ env:
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
strategy:
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [windows-latest, macos-latest, ubuntu-latest]
|
os: [windows-latest, macos-latest, ubuntu-latest]
|
||||||
|
|
||||||
|
|
87
.github/workflows/release.yml
vendored
87
.github/workflows/release.yml
vendored
|
@ -24,7 +24,7 @@ jobs:
|
||||||
- name: "Extract version"
|
- name: "Extract version"
|
||||||
id: "version"
|
id: "version"
|
||||||
run: |
|
run: |
|
||||||
ESPANSO_VERSION=$(cat espanso/Cargo.toml | grep version | head -1 | awk -F '"' '{ print $2 }')
|
ESPANSO_VERSION=$(grep '^version' espanso/Cargo.toml | awk -F '"' '{ print $2 }')
|
||||||
echo version: $ESPANSO_VERSION
|
echo version: $ESPANSO_VERSION
|
||||||
echo "::set-output name=version::v$ESPANSO_VERSION"
|
echo "::set-output name=version::v$ESPANSO_VERSION"
|
||||||
|
|
||||||
|
@ -65,8 +65,24 @@ jobs:
|
||||||
cargo install --force cargo-make --version 0.34.0
|
cargo install --force cargo-make --version 0.34.0
|
||||||
- name: Test
|
- name: Test
|
||||||
run: cargo make test-binary --profile release
|
run: cargo make test-binary --profile release
|
||||||
- name: Build
|
- name: Build resources
|
||||||
run: cargo make build-windows-all --profile release
|
run: cargo make build-windows-resources --profile release
|
||||||
|
- name: Sign resources
|
||||||
|
run: cargo make sign-windows-resources
|
||||||
|
env:
|
||||||
|
CODESIGN_PWD: ${{ secrets.WIN_CODESIGN_PWD }}
|
||||||
|
CODESIGN_CROSS_SIGNED_B64: ${{ secrets.WIN_CODESIGN_INTERMEDIATE_B64 }}
|
||||||
|
CODESIGN_CERTIFICATE_B64: ${{ secrets.WIN_CODESIGN_CERTIFICATE_B64 }}
|
||||||
|
- name: Build installer
|
||||||
|
run: cargo make build-windows-installer --profile release --skip-tasks build-windows-resources
|
||||||
|
- name: Sign installer
|
||||||
|
run: cargo make sign-windows-installer
|
||||||
|
env:
|
||||||
|
CODESIGN_PWD: ${{ secrets.WIN_CODESIGN_PWD }}
|
||||||
|
CODESIGN_CROSS_SIGNED_B64: ${{ secrets.WIN_CODESIGN_INTERMEDIATE_B64 }}
|
||||||
|
CODESIGN_CERTIFICATE_B64: ${{ secrets.WIN_CODESIGN_CERTIFICATE_B64 }}
|
||||||
|
- name: Build portable mode archive
|
||||||
|
run: cargo make build-windows-portable --profile release --skip-tasks build-windows-resources
|
||||||
- name: Create portable mode archive
|
- name: Create portable mode archive
|
||||||
shell: powershell
|
shell: powershell
|
||||||
run: |
|
run: |
|
||||||
|
@ -167,6 +183,37 @@ jobs:
|
||||||
run: cargo make create-bundle --profile release
|
run: cargo make create-bundle --profile release
|
||||||
env:
|
env:
|
||||||
MACOSX_DEPLOYMENT_TARGET: "10.13"
|
MACOSX_DEPLOYMENT_TARGET: "10.13"
|
||||||
|
- name: Codesign executable
|
||||||
|
env:
|
||||||
|
MACOS_CERTIFICATE: ${{ secrets.PROD_MACOS_CERTIFICATE }}
|
||||||
|
MACOS_CERTIFICATE_PWD: ${{ secrets.PROD_MACOS_CERTIFICATE_PWD }}
|
||||||
|
MACOS_CERTIFICATE_NAME: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }}
|
||||||
|
MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }}
|
||||||
|
run: |
|
||||||
|
echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12
|
||||||
|
security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" buildespanso.keychain
|
||||||
|
security default-keychain -s buildespanso.keychain
|
||||||
|
security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" buildespanso.keychain
|
||||||
|
security import certificate.p12 -k buildespanso.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign
|
||||||
|
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" buildespanso.keychain
|
||||||
|
/usr/bin/codesign --force -s "$MACOS_CERTIFICATE_NAME" --options runtime target/mac/Espanso.app -v
|
||||||
|
- name: "Notarize executable"
|
||||||
|
env:
|
||||||
|
PROD_MACOS_NOTARIZATION_APPLE_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_APPLE_ID }}
|
||||||
|
PROD_MACOS_NOTARIZATION_TEAM_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_TEAM_ID }}
|
||||||
|
PROD_MACOS_NOTARIZATION_PWD: ${{ secrets.PROD_MACOS_NOTARIZATION_PWD }}
|
||||||
|
run: |
|
||||||
|
echo "Create keychain profile"
|
||||||
|
xcrun notarytool store-credentials "espanso-notarytool-profile" --apple-id "$PROD_MACOS_NOTARIZATION_APPLE_ID" --team-id "$PROD_MACOS_NOTARIZATION_TEAM_ID" --password "$PROD_MACOS_NOTARIZATION_PWD"
|
||||||
|
|
||||||
|
echo "Creating temp notarization archive"
|
||||||
|
ditto -c -k --keepParent "target/mac/Espanso.app" "notarization.zip"
|
||||||
|
|
||||||
|
echo "Notarize app"
|
||||||
|
xcrun notarytool submit "notarization.zip" --keychain-profile "espanso-notarytool-profile" --wait
|
||||||
|
|
||||||
|
echo "Attach staple"
|
||||||
|
xcrun stapler staple "target/mac/Espanso.app"
|
||||||
- name: Create ZIP archive
|
- name: Create ZIP archive
|
||||||
run: |
|
run: |
|
||||||
ditto -c -k --sequesterRsrc --keepParent target/mac/Espanso.app Espanso-Mac-Intel.zip
|
ditto -c -k --sequesterRsrc --keepParent target/mac/Espanso.app Espanso-Mac-Intel.zip
|
||||||
|
@ -204,17 +251,35 @@ jobs:
|
||||||
run: cargo make create-bundle --profile release --env BUILD_ARCH=aarch64-apple-darwin
|
run: cargo make create-bundle --profile release --env BUILD_ARCH=aarch64-apple-darwin
|
||||||
- name: Codesign executable
|
- name: Codesign executable
|
||||||
env:
|
env:
|
||||||
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
|
MACOS_CERTIFICATE: ${{ secrets.PROD_MACOS_CERTIFICATE }}
|
||||||
MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
|
MACOS_CERTIFICATE_PWD: ${{ secrets.PROD_MACOS_CERTIFICATE_PWD }}
|
||||||
MACOS_CI_KEYCHAIN_PWD: ${{ secrets.MACOS_CI_KEYCHAIN_PWD }}
|
MACOS_CERTIFICATE_NAME: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }}
|
||||||
|
MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }}
|
||||||
run: |
|
run: |
|
||||||
echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12
|
echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12
|
||||||
security create-keychain -p $MACOS_CI_KEYCHAIN_PWD buildespanso.keychain
|
security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" buildespanso.keychain
|
||||||
security default-keychain -s buildespanso.keychain
|
security default-keychain -s buildespanso.keychain
|
||||||
security unlock-keychain -p $MACOS_CI_KEYCHAIN_PWD buildespanso.keychain
|
security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" buildespanso.keychain
|
||||||
security import certificate.p12 -k buildespanso.keychain -P $MACOS_CERTIFICATE_PWD -T /usr/bin/codesign
|
security import certificate.p12 -k buildespanso.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign
|
||||||
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $MACOS_CI_KEYCHAIN_PWD buildespanso.keychain
|
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" buildespanso.keychain
|
||||||
/usr/bin/codesign --force -s "Espanso CI Self-Signed" target/mac/Espanso.app -v
|
/usr/bin/codesign --force -s "$MACOS_CERTIFICATE_NAME" --options runtime target/mac/Espanso.app -v
|
||||||
|
- name: "Notarize executable"
|
||||||
|
env:
|
||||||
|
PROD_MACOS_NOTARIZATION_APPLE_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_APPLE_ID }}
|
||||||
|
PROD_MACOS_NOTARIZATION_TEAM_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_TEAM_ID }}
|
||||||
|
PROD_MACOS_NOTARIZATION_PWD: ${{ secrets.PROD_MACOS_NOTARIZATION_PWD }}
|
||||||
|
run: |
|
||||||
|
echo "Create keychain profile"
|
||||||
|
xcrun notarytool store-credentials "espanso-notarytool-profile" --apple-id "$PROD_MACOS_NOTARIZATION_APPLE_ID" --team-id "$PROD_MACOS_NOTARIZATION_TEAM_ID" --password "$PROD_MACOS_NOTARIZATION_PWD"
|
||||||
|
|
||||||
|
echo "Creating temp notarization archive"
|
||||||
|
ditto -c -k --keepParent "target/mac/Espanso.app" "notarization.zip"
|
||||||
|
|
||||||
|
echo "Notarize app"
|
||||||
|
xcrun notarytool submit "notarization.zip" --keychain-profile "espanso-notarytool-profile" --wait
|
||||||
|
|
||||||
|
echo "Attach staple"
|
||||||
|
xcrun stapler staple "target/mac/Espanso.app"
|
||||||
- name: Create ZIP archive
|
- name: Create ZIP archive
|
||||||
run: |
|
run: |
|
||||||
ditto -c -k --sequesterRsrc --keepParent target/mac/Espanso.app Espanso-Mac-M1.zip
|
ditto -c -k --sequesterRsrc --keepParent target/mac/Espanso.app Espanso-Mac-M1.zip
|
||||||
|
|
123
Cargo.lock
generated
123
Cargo.lock
generated
|
@ -582,7 +582,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "espanso"
|
name = "espanso"
|
||||||
version = "2.1.6-beta"
|
version = "2.1.7-beta"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"caps",
|
"caps",
|
||||||
|
@ -1042,6 +1042,19 @@ version = "0.3.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377"
|
checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-macro"
|
||||||
|
version = "0.3.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"proc-macro-hack",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote 1.0.9",
|
||||||
|
"syn 1.0.67",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-sink"
|
name = "futures-sink"
|
||||||
version = "0.3.17"
|
version = "0.3.17"
|
||||||
|
@ -1063,10 +1076,13 @@ dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-io",
|
"futures-io",
|
||||||
|
"futures-macro",
|
||||||
"futures-task",
|
"futures-task",
|
||||||
"memchr",
|
"memchr",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"pin-utils",
|
"pin-utils",
|
||||||
|
"proc-macro-hack",
|
||||||
|
"proc-macro-nested",
|
||||||
"slab",
|
"slab",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1246,6 +1262,21 @@ dependencies = [
|
||||||
"want",
|
"want",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hyper-rustls"
|
||||||
|
version = "0.22.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64"
|
||||||
|
dependencies = [
|
||||||
|
"futures-util",
|
||||||
|
"hyper",
|
||||||
|
"log",
|
||||||
|
"rustls",
|
||||||
|
"tokio",
|
||||||
|
"tokio-rustls",
|
||||||
|
"webpki",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper-tls"
|
name = "hyper-tls"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
|
@ -2043,6 +2074,12 @@ version = "0.5.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
|
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-nested"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.24"
|
version = "1.0.24"
|
||||||
|
@ -2297,6 +2334,7 @@ dependencies = [
|
||||||
"http",
|
"http",
|
||||||
"http-body",
|
"http-body",
|
||||||
"hyper",
|
"hyper",
|
||||||
|
"hyper-rustls",
|
||||||
"hyper-tls",
|
"hyper-tls",
|
||||||
"ipnet",
|
"ipnet",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
|
@ -2306,17 +2344,35 @@ dependencies = [
|
||||||
"native-tls",
|
"native-tls",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
"rustls",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-native-tls",
|
"tokio-native-tls",
|
||||||
|
"tokio-rustls",
|
||||||
"url",
|
"url",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"wasm-bindgen-futures",
|
"wasm-bindgen-futures",
|
||||||
"web-sys",
|
"web-sys",
|
||||||
|
"webpki-roots",
|
||||||
"winreg 0.7.0",
|
"winreg 0.7.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ring"
|
||||||
|
version = "0.16.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"libc",
|
||||||
|
"once_cell",
|
||||||
|
"spin",
|
||||||
|
"untrusted",
|
||||||
|
"web-sys",
|
||||||
|
"winapi 0.3.9",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rust-argon2"
|
name = "rust-argon2"
|
||||||
version = "0.8.3"
|
version = "0.8.3"
|
||||||
|
@ -2329,6 +2385,19 @@ dependencies = [
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls"
|
||||||
|
version = "0.19.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7"
|
||||||
|
dependencies = [
|
||||||
|
"base64",
|
||||||
|
"log",
|
||||||
|
"ring",
|
||||||
|
"sct",
|
||||||
|
"webpki",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.5"
|
version = "1.0.5"
|
||||||
|
@ -2366,6 +2435,16 @@ version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sct"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce"
|
||||||
|
dependencies = [
|
||||||
|
"ring",
|
||||||
|
"untrusted",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "security-framework"
|
name = "security-framework"
|
||||||
version = "2.3.1"
|
version = "2.3.1"
|
||||||
|
@ -2514,6 +2593,12 @@ dependencies = [
|
||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spin"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "squote"
|
name = "squote"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
|
@ -2795,6 +2880,17 @@ dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-rustls"
|
||||||
|
version = "0.22.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6"
|
||||||
|
dependencies = [
|
||||||
|
"rustls",
|
||||||
|
"tokio",
|
||||||
|
"webpki",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-util"
|
name = "tokio-util"
|
||||||
version = "0.6.7"
|
version = "0.6.7"
|
||||||
|
@ -2916,6 +3012,12 @@ version = "0.1.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f14ee04d9415b52b3aeab06258a3f07093182b88ba0f9b8d203f211a7a7d41c7"
|
checksum = "f14ee04d9415b52b3aeab06258a3f07093182b88ba0f9b8d203f211a7a7d41c7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "untrusted"
|
||||||
|
version = "0.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "url"
|
name = "url"
|
||||||
version = "2.2.2"
|
version = "2.2.2"
|
||||||
|
@ -3145,6 +3247,25 @@ dependencies = [
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "webpki"
|
||||||
|
version = "0.21.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea"
|
||||||
|
dependencies = [
|
||||||
|
"ring",
|
||||||
|
"untrusted",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "webpki-roots"
|
||||||
|
version = "0.21.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940"
|
||||||
|
dependencies = [
|
||||||
|
"webpki",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "widestring"
|
name = "widestring"
|
||||||
version = "0.4.3"
|
version = "0.4.3"
|
||||||
|
|
|
@ -50,6 +50,16 @@ dependencies = ["build-windows-resources"]
|
||||||
[tasks.build-windows-all]
|
[tasks.build-windows-all]
|
||||||
dependencies = ["build-windows-portable", "build-windows-installer"]
|
dependencies = ["build-windows-portable", "build-windows-installer"]
|
||||||
|
|
||||||
|
[tasks.sign-windows-resources]
|
||||||
|
env = { "TARGET_SIGNTOOL_FILE" = "target/windows/resources/espansod.exe" }
|
||||||
|
script_runner = "@rust"
|
||||||
|
script = { file = "scripts/sign_windows_exe.rs" }
|
||||||
|
|
||||||
|
[tasks.sign-windows-installer]
|
||||||
|
env = { "TARGET_SIGNTOOL_FILE" = "target/windows/installer/Espanso-Win-Installer-x86_64.exe" }
|
||||||
|
script_runner = "@rust"
|
||||||
|
script = { file = "scripts/sign_windows_exe.rs" }
|
||||||
|
|
||||||
# macOS
|
# macOS
|
||||||
|
|
||||||
[tasks.build-macos-arm-binary]
|
[tasks.build-macos-arm-binary]
|
||||||
|
|
|
@ -34,7 +34,7 @@ ___
|
||||||
* **Custom scripts** support
|
* **Custom scripts** support
|
||||||
* **Shell commands** support
|
* **Shell commands** support
|
||||||
* **App-specific** configurations
|
* **App-specific** configurations
|
||||||
* Support [Forms](https://espanso.org/docs/forms/)
|
* Support [Forms](https://espanso.org/docs/matches/forms/)
|
||||||
* Expandable with **packages**
|
* Expandable with **packages**
|
||||||
* Built-in **package manager** for [espanso hub](https://hub.espanso.org/)
|
* Built-in **package manager** for [espanso hub](https://hub.espanso.org/)
|
||||||
* File based configuration
|
* File based configuration
|
||||||
|
|
|
@ -64,7 +64,7 @@ impl ErrorRecord {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum ErrorLevel {
|
pub enum ErrorLevel {
|
||||||
Error,
|
Error,
|
||||||
Warning,
|
Warning,
|
||||||
|
|
|
@ -386,7 +386,7 @@ impl LegacyConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Eq)]
|
||||||
pub enum BackendType {
|
pub enum BackendType {
|
||||||
Inject,
|
Inject,
|
||||||
Clipboard,
|
Clipboard,
|
||||||
|
@ -740,7 +740,7 @@ impl LegacyConfigSet {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error handling
|
// Error handling
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub enum ConfigLoadError {
|
pub enum ConfigLoadError {
|
||||||
FileNotFound,
|
FileNotFound,
|
||||||
|
|
|
@ -21,7 +21,7 @@ use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[allow(clippy::upper_case_acronyms)]
|
#[allow(clippy::upper_case_acronyms)]
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Eq)]
|
||||||
pub enum KeyModifier {
|
pub enum KeyModifier {
|
||||||
CTRL,
|
CTRL,
|
||||||
SHIFT,
|
SHIFT,
|
||||||
|
|
|
@ -119,7 +119,7 @@ pub struct YAMLMatch {
|
||||||
pub search_terms: Option<Vec<String>>,
|
pub search_terms: Option<Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
|
||||||
pub struct YAMLVariable {
|
pub struct YAMLVariable {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ pub trait MatchStore: Send {
|
||||||
fn loaded_paths(&self) -> Vec<String>;
|
fn loaded_paths(&self) -> Vec<String>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct MatchSet<'a> {
|
pub struct MatchSet<'a> {
|
||||||
pub matches: Vec<&'a Match>,
|
pub matches: Vec<&'a Match>,
|
||||||
pub global_vars: Vec<&'a Variable>,
|
pub global_vars: Vec<&'a Variable>,
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use enum_as_inner::EnumAsInner;
|
use enum_as_inner::EnumAsInner;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
#[cfg_attr(test, derive(EnumAsInner))]
|
#[cfg_attr(test, derive(EnumAsInner))]
|
||||||
pub enum InputEvent {
|
pub enum InputEvent {
|
||||||
Mouse(MouseEvent),
|
Mouse(MouseEvent),
|
||||||
|
@ -32,7 +32,7 @@ pub enum InputEvent {
|
||||||
AllModifiersReleased,
|
AllModifiersReleased,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum MouseButton {
|
pub enum MouseButton {
|
||||||
Left,
|
Left,
|
||||||
Right,
|
Right,
|
||||||
|
@ -44,25 +44,25 @@ pub enum MouseButton {
|
||||||
Button5,
|
Button5,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct MouseEvent {
|
pub struct MouseEvent {
|
||||||
pub button: MouseButton,
|
pub button: MouseButton,
|
||||||
pub status: Status,
|
pub status: Status,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum Status {
|
pub enum Status {
|
||||||
Pressed,
|
Pressed,
|
||||||
Released,
|
Released,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum Variant {
|
pub enum Variant {
|
||||||
Left,
|
Left,
|
||||||
Right,
|
Right,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct KeyboardEvent {
|
pub struct KeyboardEvent {
|
||||||
pub key: Key,
|
pub key: Key,
|
||||||
pub value: Option<String>,
|
pub value: Option<String>,
|
||||||
|
@ -72,7 +72,7 @@ pub struct KeyboardEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
// A subset of the Web's key values: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values
|
// A subset of the Web's key values: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum Key {
|
pub enum Key {
|
||||||
// Modifiers
|
// Modifiers
|
||||||
Alt,
|
Alt,
|
||||||
|
@ -141,7 +141,7 @@ pub enum Key {
|
||||||
Other(i32),
|
Other(i32),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct HotKeyEvent {
|
pub struct HotKeyEvent {
|
||||||
pub hotkey_id: i32,
|
pub hotkey_id: i32,
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ lazy_static! {
|
||||||
static ref RAW_PARSER: Regex = Regex::new(r"^RAW\((\d+)\)$").unwrap();
|
static ref RAW_PARSER: Regex = Regex::new(r"^RAW\((\d+)\)$").unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone, Eq)]
|
||||||
pub enum ShortcutKey {
|
pub enum ShortcutKey {
|
||||||
Alt,
|
Alt,
|
||||||
Control,
|
Control,
|
||||||
|
|
|
@ -32,7 +32,7 @@ static MODIFIERS: &[ShortcutKey; 4] = &[
|
||||||
ShortcutKey::Meta,
|
ShortcutKey::Meta,
|
||||||
];
|
];
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone, Eq)]
|
||||||
pub struct HotKey {
|
pub struct HotKey {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub key: ShortcutKey,
|
pub key: ShortcutKey,
|
||||||
|
|
|
@ -19,13 +19,13 @@
|
||||||
|
|
||||||
use super::input::Key;
|
use super::input::Key;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct TriggerCompensationEvent {
|
pub struct TriggerCompensationEvent {
|
||||||
pub trigger: String,
|
pub trigger: String,
|
||||||
pub left_separator: Option<String>,
|
pub left_separator: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct CursorHintCompensationEvent {
|
pub struct CursorHintCompensationEvent {
|
||||||
pub cursor_hint_back_count: usize,
|
pub cursor_hint_back_count: usize,
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ pub struct HtmlInjectRequest {
|
||||||
pub html: String,
|
pub html: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone, Eq)]
|
||||||
pub enum TextInjectMode {
|
pub enum TextInjectMode {
|
||||||
Keys,
|
Keys,
|
||||||
Clipboard,
|
Clipboard,
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct MatchExecRequestEvent {
|
pub struct MatchExecRequestEvent {
|
||||||
pub trigger: Option<String>,
|
pub trigger: Option<String>,
|
||||||
pub args: HashMap<String, String>,
|
pub args: HashMap<String, String>,
|
||||||
|
|
|
@ -17,19 +17,19 @@
|
||||||
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone, Eq)]
|
||||||
pub enum Status {
|
pub enum Status {
|
||||||
Pressed,
|
Pressed,
|
||||||
Released,
|
Released,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone, Eq)]
|
||||||
pub enum Variant {
|
pub enum Variant {
|
||||||
Left,
|
Left,
|
||||||
Right,
|
Right,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone, Eq)]
|
||||||
pub struct KeyboardEvent {
|
pub struct KeyboardEvent {
|
||||||
pub key: Key,
|
pub key: Key,
|
||||||
pub value: Option<String>,
|
pub value: Option<String>,
|
||||||
|
@ -37,7 +37,7 @@ pub struct KeyboardEvent {
|
||||||
pub variant: Option<Variant>,
|
pub variant: Option<Variant>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum MouseButton {
|
pub enum MouseButton {
|
||||||
Left,
|
Left,
|
||||||
Right,
|
Right,
|
||||||
|
@ -49,13 +49,13 @@ pub enum MouseButton {
|
||||||
Button5,
|
Button5,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct MouseEvent {
|
pub struct MouseEvent {
|
||||||
pub button: MouseButton,
|
pub button: MouseButton,
|
||||||
pub status: Status,
|
pub status: Status,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum Key {
|
pub enum Key {
|
||||||
// Modifiers
|
// Modifiers
|
||||||
Alt,
|
Alt,
|
||||||
|
@ -124,12 +124,12 @@ pub enum Key {
|
||||||
Other(i32),
|
Other(i32),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct ContextMenuClickedEvent {
|
pub struct ContextMenuClickedEvent {
|
||||||
pub context_item_id: u32,
|
pub context_item_id: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct HotKeyEvent {
|
pub struct HotKeyEvent {
|
||||||
pub hotkey_id: i32,
|
pub hotkey_id: i32,
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,13 +19,13 @@
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct MatchesDetectedEvent {
|
pub struct MatchesDetectedEvent {
|
||||||
pub matches: Vec<DetectedMatch>,
|
pub matches: Vec<DetectedMatch>,
|
||||||
pub is_search: bool,
|
pub is_search: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Default)]
|
#[derive(Debug, Clone, PartialEq, Default, Eq)]
|
||||||
pub struct DetectedMatch {
|
pub struct DetectedMatch {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub trigger: Option<String>,
|
pub trigger: Option<String>,
|
||||||
|
@ -34,17 +34,17 @@ pub struct DetectedMatch {
|
||||||
pub args: HashMap<String, String>,
|
pub args: HashMap<String, String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct MatchSelectedEvent {
|
pub struct MatchSelectedEvent {
|
||||||
pub chosen: DetectedMatch,
|
pub chosen: DetectedMatch,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct CauseCompensatedMatchEvent {
|
pub struct CauseCompensatedMatchEvent {
|
||||||
pub m: DetectedMatch,
|
pub m: DetectedMatch,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct RenderingRequestedEvent {
|
pub struct RenderingRequestedEvent {
|
||||||
pub match_id: i32,
|
pub match_id: i32,
|
||||||
pub trigger: Option<String>,
|
pub trigger: Option<String>,
|
||||||
|
@ -54,38 +54,38 @@ pub struct RenderingRequestedEvent {
|
||||||
pub format: TextFormat,
|
pub format: TextFormat,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum TextFormat {
|
pub enum TextFormat {
|
||||||
Plain,
|
Plain,
|
||||||
Markdown,
|
Markdown,
|
||||||
Html,
|
Html,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct ImageRequestedEvent {
|
pub struct ImageRequestedEvent {
|
||||||
pub match_id: i32,
|
pub match_id: i32,
|
||||||
pub image_path: String,
|
pub image_path: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct ImageResolvedEvent {
|
pub struct ImageResolvedEvent {
|
||||||
pub image_path: String,
|
pub image_path: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct RenderedEvent {
|
pub struct RenderedEvent {
|
||||||
pub match_id: i32,
|
pub match_id: i32,
|
||||||
pub body: String,
|
pub body: String,
|
||||||
pub format: TextFormat,
|
pub format: TextFormat,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct DiscardPreviousEvent {
|
pub struct DiscardPreviousEvent {
|
||||||
// All Events with a source_id smaller than this one will be discarded
|
// All Events with a source_id smaller than this one will be discarded
|
||||||
pub minimum_source_id: u32,
|
pub minimum_source_id: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct DiscardBetweenEvent {
|
pub struct DiscardBetweenEvent {
|
||||||
// All Events with a source_id between start_id (included) and end_id (excluded)
|
// All Events with a source_id between start_id (included) and end_id (excluded)
|
||||||
// will be discarded
|
// will be discarded
|
||||||
|
@ -93,13 +93,13 @@ pub struct DiscardBetweenEvent {
|
||||||
pub end_id: u32,
|
pub end_id: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct SecureInputEnabledEvent {
|
pub struct SecureInputEnabledEvent {
|
||||||
pub app_name: String,
|
pub app_name: String,
|
||||||
pub app_path: String,
|
pub app_path: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct UndoEvent {
|
pub struct UndoEvent {
|
||||||
pub match_id: i32,
|
pub match_id: i32,
|
||||||
pub trigger: String,
|
pub trigger: String,
|
||||||
|
|
|
@ -29,7 +29,7 @@ pub enum MenuItem {
|
||||||
Separator,
|
Separator,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct SimpleMenuItem {
|
pub struct SimpleMenuItem {
|
||||||
pub id: u32,
|
pub id: u32,
|
||||||
pub label: String,
|
pub label: String,
|
||||||
|
@ -41,19 +41,19 @@ pub struct SubMenuItem {
|
||||||
pub items: Vec<MenuItem>,
|
pub items: Vec<MenuItem>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct IconStatusChangeEvent {
|
pub struct IconStatusChangeEvent {
|
||||||
pub status: IconStatus,
|
pub status: IconStatus,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum IconStatus {
|
pub enum IconStatus {
|
||||||
Enabled,
|
Enabled,
|
||||||
Disabled,
|
Disabled,
|
||||||
SecureInputDisabled,
|
SecureInputDisabled,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct ShowTextEvent {
|
pub struct ShowTextEvent {
|
||||||
pub title: String,
|
pub title: String,
|
||||||
pub text: String,
|
pub text: String,
|
||||||
|
|
|
@ -44,7 +44,7 @@ pub enum MatcherEvent {
|
||||||
VirtualSeparator,
|
VirtualSeparator,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct MatchResult {
|
pub struct MatchResult {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub trigger: String,
|
pub trigger: String,
|
||||||
|
@ -104,7 +104,7 @@ impl<'a, State> Middleware for MatcherMiddleware<'a, State> {
|
||||||
if is_event_of_interest(&event.etype) {
|
if is_event_of_interest(&event.etype) {
|
||||||
let mut matcher_states = self.matcher_states.borrow_mut();
|
let mut matcher_states = self.matcher_states.borrow_mut();
|
||||||
let prev_states = if !matcher_states.is_empty() {
|
let prev_states = if !matcher_states.is_empty() {
|
||||||
matcher_states.get(matcher_states.len() - 1)
|
matcher_states.back()
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,7 +20,7 @@ pub const KeyPress: c_int = 2;
|
||||||
#[allow(non_upper_case_globals)]
|
#[allow(non_upper_case_globals)]
|
||||||
pub const KeyRelease: c_int = 3;
|
pub const KeyRelease: c_int = 3;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct XKeyEvent {
|
pub struct XKeyEvent {
|
||||||
pub type_: c_int,
|
pub type_: c_int,
|
||||||
|
@ -40,7 +40,7 @@ pub struct XKeyEvent {
|
||||||
pub same_screen: Bool,
|
pub same_screen: Bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct XModifierKeymap {
|
pub struct XModifierKeymap {
|
||||||
pub max_keypermod: c_int,
|
pub max_keypermod: c_int,
|
||||||
|
|
|
@ -17,13 +17,13 @@
|
||||||
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum Event {
|
pub enum Event {
|
||||||
Key { key: Key, chars: Option<String> },
|
Key { key: Key, chars: Option<String> },
|
||||||
VirtualSeparator,
|
VirtualSeparator,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum Key {
|
pub enum Key {
|
||||||
// Modifiers
|
// Modifiers
|
||||||
Alt,
|
Alt,
|
||||||
|
|
|
@ -26,7 +26,7 @@ pub mod regex;
|
||||||
pub mod rolling;
|
pub mod rolling;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct MatchResult<Id> {
|
pub struct MatchResult<Id> {
|
||||||
pub id: Id,
|
pub id: Id,
|
||||||
pub trigger: String,
|
pub trigger: String,
|
||||||
|
|
|
@ -185,7 +185,7 @@ impl<Id: Clone> RollingMatcher<Id> {
|
||||||
// in the state.
|
// in the state.
|
||||||
if !has_previous_state {
|
if !has_previous_state {
|
||||||
if let Some(MatcherTreeRef::Node(node)) = node.word_separators.as_ref() {
|
if let Some(MatcherTreeRef::Node(node)) = node.word_separators.as_ref() {
|
||||||
refs.extend(self.find_refs(&*node, event, true));
|
refs.extend(self.find_refs(node, event, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ pub mod matcher;
|
||||||
mod tree;
|
mod tree;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum RollingItem {
|
pub enum RollingItem {
|
||||||
WordSeparator,
|
WordSeparator,
|
||||||
Key(Key),
|
Key(Key),
|
||||||
|
@ -31,7 +31,7 @@ pub enum RollingItem {
|
||||||
CharInsensitive(String),
|
CharInsensitive(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct RollingMatch<Id> {
|
pub struct RollingMatch<Id> {
|
||||||
pub id: Id,
|
pub id: Id,
|
||||||
pub items: Vec<RollingItem>,
|
pub items: Vec<RollingItem>,
|
||||||
|
|
|
@ -90,7 +90,7 @@ fn build_native() {
|
||||||
)
|
)
|
||||||
.args(&[
|
.args(&[
|
||||||
"/k",
|
"/k",
|
||||||
&vcvars_path.to_string_lossy().to_string(),
|
&vcvars_path.to_string_lossy(),
|
||||||
"&",
|
"&",
|
||||||
"nmake",
|
"nmake",
|
||||||
"/f",
|
"/f",
|
||||||
|
@ -320,7 +320,7 @@ fn convert_fat_libraries_to_arm(lib_dir: &Path) {
|
||||||
|
|
||||||
// Make sure it's a fat library
|
// Make sure it's a fat library
|
||||||
let lipo_output = std::process::Command::new("lipo")
|
let lipo_output = std::process::Command::new("lipo")
|
||||||
.args(&["-detailed_info", &path.to_string_lossy().to_string()])
|
.args(&["-detailed_info", &path.to_string_lossy()])
|
||||||
.output()
|
.output()
|
||||||
.expect("unable to check if library is fat");
|
.expect("unable to check if library is fat");
|
||||||
let lipo_output = String::from_utf8_lossy(&lipo_output.stdout);
|
let lipo_output = String::from_utf8_lossy(&lipo_output.stdout);
|
||||||
|
@ -339,9 +339,9 @@ fn convert_fat_libraries_to_arm(lib_dir: &Path) {
|
||||||
.args(&[
|
.args(&[
|
||||||
"-thin",
|
"-thin",
|
||||||
"arm64",
|
"arm64",
|
||||||
&path.to_string_lossy().to_string(),
|
&path.to_string_lossy(),
|
||||||
"-output",
|
"-output",
|
||||||
&path.to_string_lossy().to_string(),
|
&path.to_string_lossy(),
|
||||||
])
|
])
|
||||||
.output()
|
.output()
|
||||||
.expect("unable to extract arm64 slice from library");
|
.expect("unable to extract arm64 slice from library");
|
||||||
|
|
|
@ -25,7 +25,7 @@ lazy_static! {
|
||||||
static ref FIELD_REGEX: Regex = Regex::new(r"\{\{(.*?)\}\}|\[\[(.*?)\]\]").unwrap();
|
static ref FIELD_REGEX: Regex = Regex::new(r"\{\{(.*?)\}\}|\[\[(.*?)\]\]").unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum Token {
|
pub enum Token {
|
||||||
Text(String), // Text
|
Text(String), // Text
|
||||||
Field(String), // id: String
|
Field(String), // id: String
|
||||||
|
|
|
@ -21,11 +21,10 @@ use std::collections::HashSet;
|
||||||
|
|
||||||
use crate::sys::search::types::SearchItem;
|
use crate::sys::search::types::SearchItem;
|
||||||
|
|
||||||
pub fn get_algorithm(
|
type FilterCallback = dyn Fn(&str, &[SearchItem]) -> Vec<usize>;
|
||||||
name: &str,
|
|
||||||
use_command_filter: bool,
|
pub fn get_algorithm(name: &str, use_command_filter: bool) -> Box<FilterCallback> {
|
||||||
) -> Box<dyn Fn(&str, &[SearchItem]) -> Vec<usize>> {
|
let search_algorithm: Box<FilterCallback> = match name {
|
||||||
let search_algorithm: Box<dyn Fn(&str, &[SearchItem]) -> Vec<usize>> = match name {
|
|
||||||
"exact" => Box::new(exact_match),
|
"exact" => Box::new(exact_match),
|
||||||
"iexact" => Box::new(case_insensitive_exact_match),
|
"iexact" => Box::new(case_insensitive_exact_match),
|
||||||
"ikey" => Box::new(case_insensitive_keyword),
|
"ikey" => Box::new(case_insensitive_keyword),
|
||||||
|
@ -100,9 +99,7 @@ fn case_insensitive_keyword(query: &str, items: &[SearchItem]) -> Vec<usize> {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn command_filter(
|
fn command_filter(search_algorithm: Box<FilterCallback>) -> Box<FilterCallback> {
|
||||||
search_algorithm: Box<dyn Fn(&str, &[SearchItem]) -> Vec<usize>>,
|
|
||||||
) -> Box<dyn Fn(&str, &[SearchItem]) -> Vec<usize>> {
|
|
||||||
Box::new(move |query, items| {
|
Box::new(move |query, items| {
|
||||||
let (valid_ids, trimmed_query) = if query.starts_with('>') {
|
let (valid_ids, trimmed_query) = if query.starts_with('>') {
|
||||||
(
|
(
|
||||||
|
|
|
@ -147,16 +147,15 @@ mod interop {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SearchAlgorithmCallback = dyn Fn(&str, &[types::SearchItem]) -> Vec<usize>;
|
||||||
|
|
||||||
struct SearchData {
|
struct SearchData {
|
||||||
owned_search: interop::OwnedSearch,
|
owned_search: interop::OwnedSearch,
|
||||||
items: Vec<types::SearchItem>,
|
items: Vec<types::SearchItem>,
|
||||||
algorithm: Box<dyn Fn(&str, &[types::SearchItem]) -> Vec<usize>>,
|
algorithm: Box<SearchAlgorithmCallback>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn show(
|
pub fn show(search: types::Search, algorithm: Box<SearchAlgorithmCallback>) -> Option<String> {
|
||||||
search: types::Search,
|
|
||||||
algorithm: Box<dyn Fn(&str, &[types::SearchItem]) -> Vec<usize>>,
|
|
||||||
) -> Option<String> {
|
|
||||||
use super::interop::*;
|
use super::interop::*;
|
||||||
|
|
||||||
let owned_search: interop::OwnedSearch = (&search).into();
|
let owned_search: interop::OwnedSearch = (&search).into();
|
||||||
|
|
|
@ -44,7 +44,9 @@ pub enum ErrorLevel {
|
||||||
Warning,
|
Warning,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type OpenFileCallback = dyn Fn(&Path) + Send;
|
||||||
|
|
||||||
pub struct TroubleshootingHandlers {
|
pub struct TroubleshootingHandlers {
|
||||||
pub dont_show_again_changed: Option<Box<dyn Fn(bool) + Send>>,
|
pub dont_show_again_changed: Option<Box<dyn Fn(bool) + Send>>,
|
||||||
pub open_file: Option<Box<dyn Fn(&Path) + Send>>,
|
pub open_file: Option<Box<OpenFileCallback>>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ serde_yaml = "0.8.17"
|
||||||
tempdir = "0.3.7"
|
tempdir = "0.3.7"
|
||||||
glob = "0.3.0"
|
glob = "0.3.0"
|
||||||
natord = "1.0.9"
|
natord = "1.0.9"
|
||||||
reqwest = { version = "0.11.4", features = ["blocking"] }
|
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
regex = "1.4.3"
|
regex = "1.4.3"
|
||||||
zip = "0.5.13"
|
zip = "0.5.13"
|
||||||
|
@ -22,3 +21,12 @@ scopeguard = "1.1.0"
|
||||||
fs_extra = "1.2.0"
|
fs_extra = "1.2.0"
|
||||||
sha2 = "0.9.6"
|
sha2 = "0.9.6"
|
||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
|
reqwest = { version = "0.11.4", features = ["blocking"], default-features = false}
|
||||||
|
|
||||||
|
# On Linux we don't want to depend on openssl to avoid dependency issues
|
||||||
|
# https://github.com/espanso/espanso/issues/1056
|
||||||
|
# We need to use features to control this behavior instead of targets due to this Cargo bug:
|
||||||
|
# https://github.com/rust-lang/cargo/issues/1197
|
||||||
|
[features]
|
||||||
|
default-tls=["reqwest/default-tls"]
|
||||||
|
rustls-tls=["reqwest/rustls-tls"]
|
|
@ -30,7 +30,7 @@ mod util;
|
||||||
|
|
||||||
pub const PACKAGE_SOURCE_FILE: &str = "_pkgsource.yml";
|
pub const PACKAGE_SOURCE_FILE: &str = "_pkgsource.yml";
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct ArchivedPackage {
|
pub struct ArchivedPackage {
|
||||||
// Metadata
|
// Metadata
|
||||||
pub manifest: Manifest,
|
pub manifest: Manifest,
|
||||||
|
@ -39,12 +39,12 @@ pub struct ArchivedPackage {
|
||||||
pub source: PackageSource,
|
pub source: PackageSource,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct LegacyPackage {
|
pub struct LegacyPackage {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum StoredPackage {
|
pub enum StoredPackage {
|
||||||
Legacy(LegacyPackage),
|
Legacy(LegacyPackage),
|
||||||
Modern(ArchivedPackage),
|
Modern(ArchivedPackage),
|
||||||
|
@ -67,7 +67,7 @@ pub struct SaveOptions {
|
||||||
pub overwrite_existing: bool,
|
pub overwrite_existing: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, PartialEq)]
|
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum PackageSource {
|
pub enum PackageSource {
|
||||||
Hub,
|
Hub,
|
||||||
|
|
|
@ -22,7 +22,7 @@ use std::path::Path;
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, PartialEq, Serialize, Deserialize, Eq)]
|
||||||
pub struct Manifest {
|
pub struct Manifest {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub title: String,
|
pub title: String,
|
||||||
|
|
|
@ -23,7 +23,7 @@ use anyhow::{anyhow, bail, Context, Result};
|
||||||
|
|
||||||
use crate::manifest::Manifest;
|
use crate::manifest::Manifest;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct ResolvedPackage {
|
pub struct ResolvedPackage {
|
||||||
pub manifest: Manifest,
|
pub manifest: Manifest,
|
||||||
pub base_dir: PathBuf,
|
pub base_dir: PathBuf,
|
||||||
|
|
|
@ -82,7 +82,7 @@ fn extract_zip(data: Vec<u8>, dest_dir: &Path) -> Result<()> {
|
||||||
None => continue,
|
None => continue,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (&*file.name()).ends_with('/') {
|
if file.name().ends_with('/') {
|
||||||
std::fs::create_dir_all(&outpath)?;
|
std::fs::create_dir_all(&outpath)?;
|
||||||
} else {
|
} else {
|
||||||
if let Some(p) = outpath.parent() {
|
if let Some(p) = outpath.parent() {
|
||||||
|
|
|
@ -28,7 +28,7 @@ lazy_static! {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct GitHubParts {
|
pub struct GitHubParts {
|
||||||
author: String,
|
author: String,
|
||||||
name: String,
|
name: String,
|
||||||
|
|
|
@ -28,7 +28,7 @@ lazy_static! {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct GitLabParts {
|
pub struct GitLabParts {
|
||||||
author: String,
|
author: String,
|
||||||
name: String,
|
name: String,
|
||||||
|
|
|
@ -66,16 +66,13 @@ impl Extension for ScriptExtension {
|
||||||
// Also replace %CONFIG% and %PACKAGES% path. See issue #380
|
// Also replace %CONFIG% and %PACKAGES% path. See issue #380
|
||||||
args.iter_mut().for_each(|arg| {
|
args.iter_mut().for_each(|arg| {
|
||||||
if arg.contains("%HOME%") {
|
if arg.contains("%HOME%") {
|
||||||
*arg = arg.replace("%HOME%", &self.home_path.to_string_lossy().to_string());
|
*arg = arg.replace("%HOME%", &self.home_path.to_string_lossy());
|
||||||
}
|
}
|
||||||
if arg.contains("%CONFIG%") {
|
if arg.contains("%CONFIG%") {
|
||||||
*arg = arg.replace("%CONFIG%", &self.config_path.to_string_lossy().to_string());
|
*arg = arg.replace("%CONFIG%", &self.config_path.to_string_lossy());
|
||||||
}
|
}
|
||||||
if arg.contains("%PACKAGES%") {
|
if arg.contains("%PACKAGES%") {
|
||||||
*arg = arg.replace(
|
*arg = arg.replace("%PACKAGES%", &self.packages_path.to_string_lossy());
|
||||||
"%PACKAGES%",
|
|
||||||
&self.packages_path.to_string_lossy().to_string(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// On Windows, correct paths separators
|
// On Windows, correct paths separators
|
||||||
|
|
|
@ -48,7 +48,7 @@ pub struct Context<'a> {
|
||||||
pub templates: Vec<&'a Template>,
|
pub templates: Vec<&'a Template>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct RenderOptions {
|
pub struct RenderOptions {
|
||||||
pub casing_style: CasingStyle,
|
pub casing_style: CasingStyle,
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ impl Default for RenderOptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum CasingStyle {
|
pub enum CasingStyle {
|
||||||
None,
|
None,
|
||||||
Capitalize,
|
Capitalize,
|
||||||
|
@ -123,7 +123,7 @@ pub trait Extension {
|
||||||
|
|
||||||
pub type Scope<'a> = HashMap<&'a str, ExtensionOutput>;
|
pub type Scope<'a> = HashMap<&'a str, ExtensionOutput>;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum ExtensionOutput {
|
pub enum ExtensionOutput {
|
||||||
Single(String),
|
Single(String),
|
||||||
Multiple(HashMap<String, String>),
|
Multiple(HashMap<String, String>),
|
||||||
|
|
|
@ -78,7 +78,7 @@ pub(crate) fn render_variables(body: &str, scope: &Scope) -> Result<String> {
|
||||||
ExtensionOutput::Multiple(results) => match var_subname {
|
ExtensionOutput::Multiple(results) => match var_subname {
|
||||||
Some(var_subname) => {
|
Some(var_subname) => {
|
||||||
let var_subname = var_subname.as_str();
|
let var_subname = var_subname.as_str();
|
||||||
results.get(var_subname).map_or("", |value| &*value)
|
results.get(var_subname).map_or("", |value| value)
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
error!(
|
error!(
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone, Eq)]
|
||||||
pub enum UIEvent {
|
pub enum UIEvent {
|
||||||
TrayIconClick,
|
TrayIconClick,
|
||||||
ContextMenuClick(u32),
|
ContextMenuClick(u32),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "espanso"
|
name = "espanso"
|
||||||
version = "2.1.6-beta"
|
version = "2.1.7-beta"
|
||||||
authors = ["Federico Terzi <federicoterzi96@gmail.com>"]
|
authors = ["Federico Terzi <federicoterzi96@gmail.com>"]
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
description = "Cross-platform Text Expander written in Rust"
|
description = "Cross-platform Text Expander written in Rust"
|
||||||
|
@ -9,7 +9,14 @@ homepage = "https://github.com/federico-terzi/espanso"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["modulo"]
|
default = ["modulo", "native-tls"]
|
||||||
|
|
||||||
|
# These features control whether Espanso will use the native TLS functionality
|
||||||
|
# or not. On some platforms (currently Linux) we prefer vendoring the SSL
|
||||||
|
# logic used by the packages to avoid dependency issues.
|
||||||
|
# https://github.com/espanso/espanso/issues/1056
|
||||||
|
native-tls = ["espanso-package/default-tls"]
|
||||||
|
vendored-tls = ["espanso-package/rustls-tls"]
|
||||||
|
|
||||||
# If the wayland feature is enabled, all X11 dependencies will be dropped
|
# If the wayland feature is enabled, all X11 dependencies will be dropped
|
||||||
# and only methods suitable for Wayland will be used
|
# and only methods suitable for Wayland will be used
|
||||||
|
|
|
@ -67,7 +67,7 @@ impl Default for CliModule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum LogMode {
|
pub enum LogMode {
|
||||||
Read,
|
Read,
|
||||||
AppendOnly,
|
AppendOnly,
|
||||||
|
|
|
@ -42,10 +42,8 @@ pub fn register() -> Result<()> {
|
||||||
info_println!("creating service file in {:?}", service_file);
|
info_println!("creating service file in {:?}", service_file);
|
||||||
let espanso_path = get_binary_path().expect("unable to get espanso executable path");
|
let espanso_path = get_binary_path().expect("unable to get espanso executable path");
|
||||||
|
|
||||||
let service_content = String::from(LINUX_SERVICE_CONTENT).replace(
|
let service_content = String::from(LINUX_SERVICE_CONTENT)
|
||||||
"{{{espanso_path}}}",
|
.replace("{{{espanso_path}}}", &espanso_path.to_string_lossy());
|
||||||
&espanso_path.to_string_lossy().to_string(),
|
|
||||||
);
|
|
||||||
|
|
||||||
std::fs::write(service_file, service_content)?;
|
std::fs::write(service_file, service_content)?;
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,13 @@ fn main() {
|
||||||
if !avoid_modulo {
|
if !avoid_modulo {
|
||||||
features.push("modulo");
|
features.push("modulo");
|
||||||
}
|
}
|
||||||
|
// On linux, we don't want to rely on OpenSSL to avoid dependency issues
|
||||||
|
// https://github.com/espanso/espanso/issues/1056
|
||||||
|
if cfg!(target_os = "linux") {
|
||||||
|
features.push("vendored-tls")
|
||||||
|
} else {
|
||||||
|
features.push("native-tls")
|
||||||
|
}
|
||||||
|
|
||||||
let features_flag = features.join(" ");
|
let features_flag = features.join(" ");
|
||||||
|
|
||||||
|
|
|
@ -111,13 +111,10 @@ fn main() {
|
||||||
.to_string_lossy()
|
.to_string_lossy()
|
||||||
.to_string(),
|
.to_string(),
|
||||||
);
|
);
|
||||||
iss_setup = iss_setup.replace(
|
iss_setup = iss_setup.replace("{{{output_name}}}", &format!("{}-{}", INSTALLER_NAME, arch));
|
||||||
"{{{output_name}}}",
|
|
||||||
&format!("{}-{}", INSTALLER_NAME, arch),
|
|
||||||
);
|
|
||||||
iss_setup = iss_setup.replace(
|
iss_setup = iss_setup.replace(
|
||||||
"{{{executable_path}}}",
|
"{{{executable_path}}}",
|
||||||
&dunce::canonicalize(&format!("{}.exe", envmnt::get_or_panic("EXEC_PATH")))
|
&dunce::canonicalize(&resources_dir.join("espansod.exe"))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_string_lossy()
|
.to_string_lossy()
|
||||||
.to_string(),
|
.to_string(),
|
||||||
|
|
138
scripts/sign_windows_exe.rs
Normal file
138
scripts/sign_windows_exe.rs
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
//! ```cargo
|
||||||
|
//! [dependencies]
|
||||||
|
//! glob = "0.3.0"
|
||||||
|
//! fs_extra = "1.2.0"
|
||||||
|
//! base64 = "0.13.0"
|
||||||
|
//! anyhow = "1.0.38"
|
||||||
|
//! ```
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
|
const WINDOWS_KITS_LOCATION: &str = "C:/Program Files (x86)/Windows Kits/10/bin";
|
||||||
|
const CERTIFICATE_TARGET_DIR: &str = "target/codesign";
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _ = std::fs::remove_dir_all(CERTIFICATE_TARGET_DIR);
|
||||||
|
std::fs::create_dir_all(CERTIFICATE_TARGET_DIR).expect("unable to create target directory");
|
||||||
|
let certificate_target_dir = PathBuf::from(CERTIFICATE_TARGET_DIR);
|
||||||
|
if !certificate_target_dir.is_dir() {
|
||||||
|
panic!("expected target directory, found none");
|
||||||
|
}
|
||||||
|
|
||||||
|
let signtool_path = get_signtool_location().expect("unable to locate signtool exe");
|
||||||
|
println!("using signtool location: {:?}", signtool_path);
|
||||||
|
|
||||||
|
let target_exe_file =
|
||||||
|
std::env::var("TARGET_SIGNTOOL_FILE").expect("TARGET_SIGNTOOL_FILE env variable not found");
|
||||||
|
let target_exe_path = PathBuf::from(target_exe_file);
|
||||||
|
if !target_exe_path.is_file() {
|
||||||
|
panic!(
|
||||||
|
"target file '{}' cannot be found",
|
||||||
|
target_exe_path.display()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("signing file: {:?}", target_exe_path);
|
||||||
|
|
||||||
|
let certificate_pwd = std::env::var("CODESIGN_PWD").expect("CODESIGN_PWD env variable not found");
|
||||||
|
let cross_signed_certificate_b64 = std::env::var("CODESIGN_CROSS_SIGNED_B64")
|
||||||
|
.expect("CODESIGN_CROSS_SIGNED_B64 env variable not found");
|
||||||
|
let codesign_certificate_b64 = std::env::var("CODESIGN_CERTIFICATE_B64")
|
||||||
|
.expect("CODESIGN_CERTIFICATE_B64 env variable not found");
|
||||||
|
|
||||||
|
let cross_signed_certificate = DecodedCertificate::new(
|
||||||
|
&cross_signed_certificate_b64,
|
||||||
|
certificate_target_dir.join("SectigoPublicCodeSigningRootR46_AAA.crt"),
|
||||||
|
)
|
||||||
|
.expect("unable to decode intermediate cross-signed certificate");
|
||||||
|
let codesign_certificate = DecodedCertificate::new(
|
||||||
|
&codesign_certificate_b64,
|
||||||
|
certificate_target_dir.join("codesign.pfx"),
|
||||||
|
)
|
||||||
|
.expect("unable to decode codesign certificate");
|
||||||
|
|
||||||
|
let mut cmd = Command::new(signtool_path);
|
||||||
|
cmd.args(&[
|
||||||
|
"sign",
|
||||||
|
"/fd",
|
||||||
|
"SHA256",
|
||||||
|
"/p",
|
||||||
|
&certificate_pwd,
|
||||||
|
"/ac",
|
||||||
|
&cross_signed_certificate.path(),
|
||||||
|
"/f",
|
||||||
|
&codesign_certificate.path(),
|
||||||
|
"/tr",
|
||||||
|
"http://timestamp.sectigo.com/rfc3161",
|
||||||
|
"/td",
|
||||||
|
"sha256",
|
||||||
|
&target_exe_path.to_string_lossy(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
let mut handle = cmd.spawn().expect("signtool spawn failed");
|
||||||
|
let result = handle.wait().expect("unable to read signtool exit status");
|
||||||
|
if !result.success() {
|
||||||
|
panic!("signtool failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inspired by: https://github.com/dlemstra/code-sign-action/blob/main/index.ts#L143
|
||||||
|
fn get_signtool_location() -> Option<PathBuf> {
|
||||||
|
let mut path: Option<PathBuf> = None;
|
||||||
|
let mut max_version = 0;
|
||||||
|
for entry in glob::glob(&format!("{}/*", WINDOWS_KITS_LOCATION))
|
||||||
|
.expect("unable to glob windows kits location")
|
||||||
|
{
|
||||||
|
let entry = entry.expect("unable to unwrap glob entry");
|
||||||
|
if !entry.is_dir() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if !entry.to_string_lossy().ends_with(".0") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let folder_name = entry.file_name().expect("unable to extract folder_name");
|
||||||
|
let folder_version_str = folder_name.to_string_lossy().replace(".", "");
|
||||||
|
let folder_version = folder_version_str
|
||||||
|
.parse::<i32>()
|
||||||
|
.expect("invalid folder version string");
|
||||||
|
if folder_version > max_version {
|
||||||
|
let signtool_path_candidate = entry.join("x86").join("signtool.exe");
|
||||||
|
if signtool_path_candidate.is_file() {
|
||||||
|
path = Some(signtool_path_candidate);
|
||||||
|
max_version = folder_version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DecodedCertificate {
|
||||||
|
decoded_file: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DecodedCertificate {
|
||||||
|
pub fn new(b64: &str, target_file: PathBuf) -> Result<Self> {
|
||||||
|
// Keys and certificates are encoded with whitespaces/newlines in them, but we need to remove them
|
||||||
|
let filtered_b64: String = b64.chars().filter(|c| !c.is_whitespace()).collect();
|
||||||
|
let decoded = base64::decode(filtered_b64)?;
|
||||||
|
std::fs::write(&target_file, &decoded)?;
|
||||||
|
Ok(Self {
|
||||||
|
decoded_file: target_file,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn path(&self) -> String {
|
||||||
|
self.decoded_file.to_string_lossy().to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the certificate files when they are not needed anymore
|
||||||
|
// to minimize the attack surface
|
||||||
|
impl Drop for DecodedCertificate {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
std::fs::remove_file(&self.decoded_file).expect("unable to remove certificate file")
|
||||||
|
}
|
||||||
|
}
|
|
@ -48,6 +48,13 @@ fn main() {
|
||||||
if wayland {
|
if wayland {
|
||||||
features.push("wayland");
|
features.push("wayland");
|
||||||
}
|
}
|
||||||
|
// On linux, we don't want to rely on OpenSSL to avoid dependency issues
|
||||||
|
// https://github.com/espanso/espanso/issues/1056
|
||||||
|
if cfg!(target_os = "linux") {
|
||||||
|
features.push("vendored-tls")
|
||||||
|
} else {
|
||||||
|
features.push("native-tls")
|
||||||
|
}
|
||||||
|
|
||||||
let features_flag = features.join(" ");
|
let features_flag = features.join(" ");
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
name: espanso
|
name: espanso
|
||||||
version: 2.1.6-beta
|
version: 2.1.7-beta
|
||||||
summary: A Cross-platform Text Expander written in Rust
|
summary: A Cross-platform Text Expander written in Rust
|
||||||
description: |
|
description: |
|
||||||
espanso is a Cross-platform, Text Expander written in Rust.
|
espanso is a Cross-platform, Text Expander written in Rust.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user