refactor(tazjin/gio-list-apps): refactor into dynamic Emacs module
Instead of producing a binary that gets called by Emacs, with input/output serialisation, use a dynamic Emacs module that lets Emacs more-or-less directly call the relevant GTK functions. I'm doing this mostly as an experiment. Might be interesting to end up with a dynamic module that I can dump some experimental code into that improves my workflows. To do this, I've exposed the emacs binary used by my Emacs configuration in an additional `passthru` field. This ensures that the module is linked against the right version of Emacs. Change-Id: I1426994fe3455ed1b2a685c5a09705e29fa40950 Reviewed-on: https://cl.tvl.fyi/c/depot/+/9163 Tested-by: BuildkiteCI Reviewed-by: tazjin <tazjin@tvl.su> Autosubmit: tazjin <tazjin@tvl.su>
This commit is contained in:
parent
d6bce3f83d
commit
e5f7fe430d
7 changed files with 178 additions and 52 deletions
|
@ -2,6 +2,8 @@
|
||||||
(require 'dash)
|
(require 'dash)
|
||||||
(require 'map)
|
(require 'map)
|
||||||
|
|
||||||
|
(require 'gio-list-apps) ;; native module!
|
||||||
|
|
||||||
(defun goto-line-with-feedback ()
|
(defun goto-line-with-feedback ()
|
||||||
"Show line numbers temporarily, while prompting for the line number input"
|
"Show line numbers temporarily, while prompting for the line number input"
|
||||||
(interactive)
|
(interactive)
|
||||||
|
@ -336,12 +338,7 @@ names, instead of only their names (which might change)."
|
||||||
"Use `//users/tazjin/gio-list-apps' to retrieve a list of
|
"Use `//users/tazjin/gio-list-apps' to retrieve a list of
|
||||||
installed (and visible) XDG apps, and let users launch them."
|
installed (and visible) XDG apps, and let users launch them."
|
||||||
(interactive)
|
(interactive)
|
||||||
(let* ((apps-json (s-lines (s-trim (shell-command-to-string "gio-list-apps"))))
|
(let* ((apps (taz-list-xdg-apps))
|
||||||
(apps (seq-map (lambda (app)
|
|
||||||
(let ((parsed (json-parse-string app :object-type 'alist)))
|
|
||||||
(cons (cdr (assoc 'name parsed))
|
|
||||||
(cdr (assoc 'commandline parsed)))))
|
|
||||||
apps-json))
|
|
||||||
|
|
||||||
;; Display the command that will be run as an annotation
|
;; Display the command that will be run as an annotation
|
||||||
(completion-extra-properties
|
(completion-extra-properties
|
||||||
|
|
|
@ -13,7 +13,6 @@ pkgs.makeOverridable
|
||||||
|
|
||||||
# $PATH for binaries that need to be available to Emacs
|
# $PATH for binaries that need to be available to Emacs
|
||||||
emacsBinPath = lib.makeBinPath [
|
emacsBinPath = lib.makeBinPath [
|
||||||
depot.users.tazjin.gio-list-apps
|
|
||||||
(currentTelega pkgs.emacsPackages)
|
(currentTelega pkgs.emacsPackages)
|
||||||
pkgs.libwebp # for dwebp, required by telega
|
pkgs.libwebp # for dwebp, required by telega
|
||||||
];
|
];
|
||||||
|
@ -100,6 +99,9 @@ pkgs.makeOverridable
|
||||||
tvlPackages.rcirc
|
tvlPackages.rcirc
|
||||||
tvlPackages.term-switcher
|
tvlPackages.term-switcher
|
||||||
tvlPackages.tvl
|
tvlPackages.tvl
|
||||||
|
|
||||||
|
# Dynamic/native modules
|
||||||
|
depot.users.tazjin.gio-list-apps
|
||||||
])));
|
])));
|
||||||
|
|
||||||
# Tired of telega.el runtime breakages through tdlib
|
# Tired of telega.el runtime breakages through tdlib
|
||||||
|
@ -138,6 +140,12 @@ pkgs.makeOverridable
|
||||||
'').overrideAttrs
|
'').overrideAttrs
|
||||||
(_: {
|
(_: {
|
||||||
passthru = {
|
passthru = {
|
||||||
|
# Expose original Emacs used for my configuration.
|
||||||
|
inherit emacs;
|
||||||
|
|
||||||
|
# Expose the pure emacs with all packages.
|
||||||
|
emacsWithPackages = tazjinsEmacs f;
|
||||||
|
|
||||||
# Call overrideEmacs with a function (pkgs -> pkgs) to modify the
|
# Call overrideEmacs with a function (pkgs -> pkgs) to modify the
|
||||||
# packages that should be included in this Emacs distribution.
|
# packages that should be included in this Emacs distribution.
|
||||||
overrideEmacs = f': self l f';
|
overrideEmacs = f': self l f';
|
||||||
|
|
146
users/tazjin/gio-list-apps/Cargo.lock
generated
146
users/tazjin/gio-list-apps/Cargo.lock
generated
|
@ -2,6 +2,12 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyhow"
|
||||||
|
version = "1.0.75"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
@ -24,12 +30,96 @@ dependencies = [
|
||||||
"target-lexicon",
|
"target-lexicon",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ctor"
|
||||||
|
version = "0.1.26"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling"
|
||||||
|
version = "0.10.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858"
|
||||||
|
dependencies = [
|
||||||
|
"darling_core",
|
||||||
|
"darling_macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling_core"
|
||||||
|
version = "0.10.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b"
|
||||||
|
dependencies = [
|
||||||
|
"fnv",
|
||||||
|
"ident_case",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"strsim",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling_macro"
|
||||||
|
version = "0.10.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72"
|
||||||
|
dependencies = [
|
||||||
|
"darling_core",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "emacs"
|
||||||
|
version = "0.18.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6797a940189d353de79bec32abe717aeeecd79a08236e84404c888354e040665"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"ctor",
|
||||||
|
"emacs-macros",
|
||||||
|
"emacs_module",
|
||||||
|
"once_cell",
|
||||||
|
"rustc_version",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "emacs-macros"
|
||||||
|
version = "0.17.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "69656fdfe7c2608b87164964db848b5c3795de7302e3130cce7131552c6be161"
|
||||||
|
dependencies = [
|
||||||
|
"darling",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "emacs_module"
|
||||||
|
version = "0.18.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b3067bc974045ed2c6db333bd4fc30d3bdaafa6421a9a889fa7b2826b6f7f2fa"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "equivalent"
|
name = "equivalent"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fnv"
|
||||||
|
version = "1.0.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-channel"
|
name = "futures-channel"
|
||||||
version = "0.3.28"
|
version = "0.3.28"
|
||||||
|
@ -116,8 +206,8 @@ dependencies = [
|
||||||
name = "gio-list-apps"
|
name = "gio-list-apps"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"emacs",
|
||||||
"gio",
|
"gio",
|
||||||
"serde_json",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -203,6 +293,12 @@ version = "0.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ident_case"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
|
@ -213,12 +309,6 @@ dependencies = [
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "itoa"
|
|
||||||
version = "1.0.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.147"
|
version = "0.2.147"
|
||||||
|
@ -308,10 +398,28 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "rustc_version"
|
||||||
version = "1.0.15"
|
version = "0.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
|
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||||
|
dependencies = [
|
||||||
|
"semver",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||||
|
dependencies = [
|
||||||
|
"semver-parser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver-parser"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
|
@ -333,17 +441,6 @@ dependencies = [
|
||||||
"syn 2.0.29",
|
"syn 2.0.29",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde_json"
|
|
||||||
version = "1.0.105"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360"
|
|
||||||
dependencies = [
|
|
||||||
"itoa",
|
|
||||||
"ryu",
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_spanned"
|
name = "serde_spanned"
|
||||||
version = "0.6.3"
|
version = "0.6.3"
|
||||||
|
@ -368,6 +465,12 @@ version = "1.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
|
checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strsim"
|
||||||
|
version = "0.9.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.109"
|
version = "1.0.109"
|
||||||
|
@ -375,6 +478,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,9 @@ name = "gio-list-apps"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
[lib]
|
||||||
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
emacs = "0.18.0"
|
||||||
gio = "0.18.1"
|
gio = "0.18.1"
|
||||||
serde_json = "1.0.105"
|
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
{ pkgs, lib, ... }:
|
{ depot, pkgs, lib, ... }:
|
||||||
|
|
||||||
pkgs.rustPlatform.buildRustPackage {
|
pkgs.rustPlatform.buildRustPackage {
|
||||||
name = "gio-list-apps";
|
name = "gio-list-apps";
|
||||||
src = lib.cleanSource ./.;
|
src = lib.cleanSource ./.;
|
||||||
cargoLock.lockFile = ./Cargo.lock;
|
cargoLock.lockFile = ./Cargo.lock;
|
||||||
nativeBuildInputs = [ pkgs.pkg-config ];
|
nativeBuildInputs = [ pkgs.pkg-config ];
|
||||||
buildInputs = [ pkgs.gtk3 ];
|
buildInputs = [ pkgs.gtk3 depot.users.tazjin.emacs.emacs ];
|
||||||
|
|
||||||
|
postInstall = ''
|
||||||
|
mkdir -p $out/share/emacs/site-lisp
|
||||||
|
ln -s $out/lib/libgio_list_apps.so $out/share/emacs/site-lisp/gio-list-apps.so
|
||||||
|
'';
|
||||||
}
|
}
|
||||||
|
|
31
users/tazjin/gio-list-apps/src/lib.rs
Normal file
31
users/tazjin/gio-list-apps/src/lib.rs
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
use emacs::{defun, Env, IntoLisp, Result, Value};
|
||||||
|
use gio::traits::AppInfoExt;
|
||||||
|
use gio::AppInfo;
|
||||||
|
|
||||||
|
emacs::plugin_is_GPL_compatible!();
|
||||||
|
|
||||||
|
#[emacs::module(defun_prefix = "taz", mod_in_name = false)]
|
||||||
|
fn init(_: &Env) -> Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns an alist of the currently available XDG applications (through their
|
||||||
|
/// `.desktop' shortcuts), and the command line parameters needed to start them.
|
||||||
|
///
|
||||||
|
/// Hidden applications or applications without specified command-line
|
||||||
|
/// parameters are not included.
|
||||||
|
#[defun]
|
||||||
|
fn list_xdg_apps(env: &Env) -> Result<Value> {
|
||||||
|
let mut visible_apps: Vec<Value> = vec![];
|
||||||
|
|
||||||
|
for app in AppInfo::all().into_iter().filter(AppInfo::should_show) {
|
||||||
|
if let Some(cmd) = app
|
||||||
|
.commandline()
|
||||||
|
.and_then(|p| Some(p.to_str()?.to_string()))
|
||||||
|
{
|
||||||
|
visible_apps.push(env.cons(app.name().as_str().into_lisp(env)?, cmd.into_lisp(env)?)?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
env.list(&visible_apps)
|
||||||
|
}
|
|
@ -1,20 +0,0 @@
|
||||||
use gio::traits::AppInfoExt;
|
|
||||||
use gio::AppInfo;
|
|
||||||
use serde_json::json;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
for app in AppInfo::all() {
|
|
||||||
if app.should_show() {
|
|
||||||
if let Some(cmd) = app.commandline() {
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
json!({
|
|
||||||
"name": app.name().as_str(),
|
|
||||||
"display_name": app.display_name().as_str(),
|
|
||||||
"commandline": cmd,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue