This commit is contained in:
2026-08-04 15:43:12 +09:00
parent 1f1d46ea2a
commit a44a83a587
9 changed files with 270 additions and 30 deletions
Generated
+163 -30
View File
@@ -91,6 +91,32 @@
} }
}, },
"bun2nix": { "bun2nix": {
"inputs": {
"flake-parts": "flake-parts_2",
"import-tree": "import-tree",
"nixpkgs": [
"handy",
"nixpkgs"
],
"systems": "systems_4",
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1770895533,
"narHash": "sha256-v3QaK9ugy9bN9RXDnjw0i2OifKmz2NnKM82agtqm/UY=",
"owner": "nix-community",
"repo": "bun2nix",
"rev": "c843f477b15f51151f8c6bcc886954699440a6e1",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "2.0.8",
"repo": "bun2nix",
"type": "github"
}
},
"bun2nix_2": {
"inputs": { "inputs": {
"flake-parts": [ "flake-parts": [
"llm-agents", "llm-agents",
@@ -292,6 +318,24 @@
} }
}, },
"flake-parts_2": { "flake-parts_2": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib_2"
},
"locked": {
"lastModified": 1769996383,
"narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "57928607ea566b5db3ad13af0e57e921e6b12381",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-parts_3": {
"inputs": { "inputs": {
"nixpkgs-lib": [ "nixpkgs-lib": [
"llm-agents", "llm-agents",
@@ -312,7 +356,7 @@
"type": "github" "type": "github"
} }
}, },
"flake-parts_3": { "flake-parts_4": {
"inputs": { "inputs": {
"nixpkgs-lib": [ "nixpkgs-lib": [
"nixvim", "nixvim",
@@ -333,7 +377,7 @@
"type": "github" "type": "github"
} }
}, },
"flake-parts_4": { "flake-parts_5": {
"inputs": { "inputs": {
"nixpkgs-lib": [ "nixpkgs-lib": [
"stylix", "stylix",
@@ -470,6 +514,27 @@
"type": "gitlab" "type": "gitlab"
} }
}, },
"handy": {
"inputs": {
"bun2nix": "bun2nix",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1785763469,
"narHash": "sha256-YHfOchlPBKbBbeoaT1amrjKBHJTYMXmcR1Gm31E7TLE=",
"owner": "cjpais",
"repo": "Handy",
"rev": "b1b2d9f9072e55902a46ca6cc655e5893ed7a91d",
"type": "github"
},
"original": {
"owner": "cjpais",
"repo": "Handy",
"type": "github"
}
},
"home-manager": { "home-manager": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@@ -533,6 +598,21 @@
"type": "github" "type": "github"
} }
}, },
"import-tree": {
"locked": {
"lastModified": 1763762820,
"narHash": "sha256-ZvYKbFib3AEwiNMLsejb/CWs/OL/srFQ8AogkebEPF0=",
"owner": "vic",
"repo": "import-tree",
"rev": "3c23749d8013ec6daa1d7255057590e9ca726646",
"type": "github"
},
"original": {
"owner": "vic",
"repo": "import-tree",
"type": "github"
}
},
"lanzaboote": { "lanzaboote": {
"inputs": { "inputs": {
"crane": "crane", "crane": "crane",
@@ -558,11 +638,11 @@
}, },
"llm-agents": { "llm-agents": {
"inputs": { "inputs": {
"bun2nix": "bun2nix", "bun2nix": "bun2nix_2",
"flake-parts": "flake-parts_2", "flake-parts": "flake-parts_3",
"nixpkgs": "nixpkgs_4", "nixpkgs": "nixpkgs_4",
"systems": "systems_4", "systems": "systems_5",
"treefmt-nix": "treefmt-nix" "treefmt-nix": "treefmt-nix_2"
}, },
"locked": { "locked": {
"lastModified": 1785753922, "lastModified": 1785753922,
@@ -765,6 +845,21 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs-lib_2": {
"locked": {
"lastModified": 1769909678,
"narHash": "sha256-cBEymOf4/o3FD5AZnzC3J9hLbiZ+QDT/KDuyHXVJOpM=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "72716169fe93074c333e8d0173151350670b824c",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs.lib",
"type": "github"
}
},
"nixpkgs-libxml2": { "nixpkgs-libxml2": {
"locked": { "locked": {
"lastModified": 1751274312, "lastModified": 1751274312,
@@ -982,11 +1077,11 @@
}, },
"nixvim": { "nixvim": {
"inputs": { "inputs": {
"flake-parts": "flake-parts_3", "flake-parts": "flake-parts_4",
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
], ],
"systems": "systems_5" "systems": "systems_6"
}, },
"locked": { "locked": {
"lastModified": 1782919967, "lastModified": 1782919967,
@@ -1077,6 +1172,7 @@
"flake-parts": "flake-parts", "flake-parts": "flake-parts",
"ghostty": "ghostty", "ghostty": "ghostty",
"git-hooks-nix": "git-hooks-nix", "git-hooks-nix": "git-hooks-nix",
"handy": "handy",
"home-manager": "home-manager_2", "home-manager": "home-manager_2",
"lanzaboote": "lanzaboote", "lanzaboote": "lanzaboote",
"llm-agents": "llm-agents", "llm-agents": "llm-agents",
@@ -1093,8 +1189,8 @@
"services-flake": "services-flake", "services-flake": "services-flake",
"sops-nix": "sops-nix", "sops-nix": "sops-nix",
"stylix": "stylix", "stylix": "stylix",
"systems": "systems_7", "systems": "systems_8",
"treefmt-nix": "treefmt-nix_2", "treefmt-nix": "treefmt-nix_3",
"vicinae": "vicinae", "vicinae": "vicinae",
"vicinae-extensions": "vicinae-extensions" "vicinae-extensions": "vicinae-extensions"
} }
@@ -1181,13 +1277,13 @@
"base16-helix": "base16-helix", "base16-helix": "base16-helix",
"base16-vim": "base16-vim", "base16-vim": "base16-vim",
"firefox-gnome-theme": "firefox-gnome-theme", "firefox-gnome-theme": "firefox-gnome-theme",
"flake-parts": "flake-parts_4", "flake-parts": "flake-parts_5",
"gnome-shell": "gnome-shell", "gnome-shell": "gnome-shell",
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
], ],
"nur": "nur", "nur": "nur",
"systems": "systems_6", "systems": "systems_7",
"tinted-kitty": "tinted-kitty", "tinted-kitty": "tinted-kitty",
"tinted-schemes": "tinted-schemes", "tinted-schemes": "tinted-schemes",
"tinted-tmux": "tinted-tmux", "tinted-tmux": "tinted-tmux",
@@ -1222,6 +1318,21 @@
"type": "github" "type": "github"
} }
}, },
"systems_10": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_2": { "systems_2": {
"locked": { "locked": {
"lastModified": 1681028828, "lastModified": 1681028828,
@@ -1284,6 +1395,21 @@
} }
}, },
"systems_6": { "systems_6": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_7": {
"locked": { "locked": {
"lastModified": 1774449309, "lastModified": 1774449309,
"narHash": "sha256-brhZ8DmuGtzkCYHJg4HEd602amKm89Y9ytsFZ5uWD1w=", "narHash": "sha256-brhZ8DmuGtzkCYHJg4HEd602amKm89Y9ytsFZ5uWD1w=",
@@ -1299,21 +1425,6 @@
"type": "github" "type": "github"
} }
}, },
"systems_7": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_8": { "systems_8": {
"locked": { "locked": {
"lastModified": 1681028828, "lastModified": 1681028828,
@@ -1409,6 +1520,28 @@
} }
}, },
"treefmt-nix": { "treefmt-nix": {
"inputs": {
"nixpkgs": [
"handy",
"bun2nix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1770228511,
"narHash": "sha256-wQ6NJSuFqAEmIg2VMnLdCnUc0b7vslUohqqGGD+Fyxk=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "337a4fe074be1042a35086f15481d763b8ddc0e7",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
},
"treefmt-nix_2": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
"llm-agents", "llm-agents",
@@ -1429,7 +1562,7 @@
"type": "github" "type": "github"
} }
}, },
"treefmt-nix_2": { "treefmt-nix_3": {
"inputs": { "inputs": {
"nixpkgs": "nixpkgs_10" "nixpkgs": "nixpkgs_10"
}, },
@@ -1451,7 +1584,7 @@
"inputs": { "inputs": {
"nixpkgs": "nixpkgs_11", "nixpkgs": "nixpkgs_11",
"soulver-cpp": "soulver-cpp", "soulver-cpp": "soulver-cpp",
"systems": "systems_8" "systems": "systems_9"
}, },
"locked": { "locked": {
"lastModified": 1785733880, "lastModified": 1785733880,
@@ -1473,7 +1606,7 @@
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
], ],
"systems": "systems_9", "systems": "systems_10",
"vicinae": "vicinae_2" "vicinae": "vicinae_2"
}, },
"locked": { "locked": {
+6
View File
@@ -38,6 +38,12 @@
url = "github:ghostty-org/ghostty"; url = "github:ghostty-org/ghostty";
}; };
# Speech to text
handy = {
url = "github:cjpais/Handy";
inputs.nixpkgs.follows = "nixpkgs";
};
# Shell / Launcher # Shell / Launcher
vicinae.url = "github:vicinaehq/vicinae"; vicinae.url = "github:vicinaehq/vicinae";
+8
View File
@@ -0,0 +1,8 @@
{
homebrew.casks = [ "handy" ];
launchd.agents.handy = {
command = "/usr/bin/open -gja Handy --args --start-hidden";
serviceConfig.RunAtLoad = true;
};
}
+74
View File
@@ -0,0 +1,74 @@
{
config,
inputs,
lib,
pkgs,
...
}:
let
handy = inputs.handy.packages.${pkgs.stdenv.hostPlatform.system}.handy;
settingsFile = "${config.xdg.configHome}/com.pais.handy/settings_store.json";
in
{
home.packages = [
handy
pkgs.wtype
];
# Handy has no disabled-shortcut setting. Empty bindings are rejected before
# registration, leaving niri and labwc as the sole owners of Ctrl+Space.
home.activation.disableHandyGlobalShortcuts = {
after = [ "writeBoundary" ];
before = [ ];
data = ''
settingsFile=${lib.escapeShellArg settingsFile}
mkdir -p "$(dirname "$settingsFile")"
if [ -f "$settingsFile" ]; then
${lib.getExe pkgs.jq} \
'.settings.bindings.transcribe.current_binding = ""
| .settings.bindings.transcribe_with_post_process.current_binding = ""' \
"$settingsFile" > "$settingsFile.tmp"
else
${lib.getExe pkgs.jq} -n '
{
settings: {
bindings: {
transcribe: {
id: "transcribe",
name: "Transcribe",
description: "Converts your speech into text.",
default_binding: "ctrl+space",
current_binding: ""
},
transcribe_with_post_process: {
id: "transcribe_with_post_process",
name: "Transcribe with Post-Processing",
description: "Converts your speech into text and applies AI post-processing.",
default_binding: "ctrl+shift+space",
current_binding: ""
}
}
}
}
' > "$settingsFile.tmp"
fi
mv "$settingsFile.tmp" "$settingsFile"
'';
};
systemd.user.services.handy = {
Unit = {
Description = "Handy speech-to-text";
After = [ "graphical-session.target" ];
PartOf = [ "graphical-session.target" ];
};
Service = {
ExecStart = "${lib.getExe handy} --start-hidden";
Restart = "on-failure";
RestartSec = 5;
};
Install.WantedBy = [ "graphical-session.target" ];
};
}
+3
View File
@@ -0,0 +1,3 @@
{
description = "Handy offline speech-to-text";
}
+1
View File
@@ -127,6 +127,7 @@ in
(execute "W-space" "ghostty +toggle-quick-terminal") (execute "W-space" "ghostty +toggle-quick-terminal")
(execute "W-p" "wdisplays") (execute "W-p" "wdisplays")
(execute "W-z" "wl-find-cursor -c 0xCCFF453A -s 160 -d 1200") (execute "W-z" "wl-find-cursor -c 0xCCFF453A -s 160 -d 1200")
(execute "C-space" "handy --toggle-transcription")
# Function keys (sync with niri modules/applications/niri/home.nix) # Function keys (sync with niri modules/applications/niri/home.nix)
(execute "XF86AudioRaiseVolume" "noctalia msg volume-up") (execute "XF86AudioRaiseVolume" "noctalia msg volume-up")
+7
View File
@@ -119,6 +119,13 @@ in
]; ];
hotkey-overlay.title = "Find Cursor"; hotkey-overlay.title = "Find Cursor";
}; };
"Ctrl+Space" = {
action.spawn = [
"handy"
"--toggle-transcription"
];
hotkey-overlay.title = "Toggle Handy Transcription";
};
# Function keys (sync with labwc modules/applications/labwc/home.nix) # Function keys (sync with labwc modules/applications/labwc/home.nix)
"XF86AudioRaiseVolume".action.spawn = [ "XF86AudioRaiseVolume".action.spawn = [
+7
View File
@@ -63,6 +63,13 @@ enables performance improvements, synced lyrics, tracker blocking, the album
color theme, and custom output-device selection while preserving user-owned color theme, and custom output-device selection while preserving user-owned
settings such as the selected device. settings such as the selected device.
`workload.personal` also provides Handy for offline speech-to-text. It starts
hidden when the graphical session begins. On niri and labwc, `Ctrl+Space` is
owned by the compositor and invokes Handy's `--toggle-transcription` command;
Handy's own shortcut bindings are disabled on NixOS so it does not monitor
keyboard events under Wayland. Handy uses the Homebrew cask and starts at login
on macOS.
On NixOS, `workload.game` provides Steam with Valve Proton and Proton-GE, On NixOS, `workload.game` provides Steam with Valve Proton and Proton-GE,
Protontricks, Wayland-compatible Steam Input, GameMode, Gamescope, and MangoHud. Protontricks, Wayland-compatible Steam Input, GameMode, Gamescope, and MangoHud.
Enabling Steam also activates the 32-bit graphics and PipeWire support required Enabling Steam also activates the 32-bit graphics and PipeWire support required
@@ -6,6 +6,7 @@
"applications.chrome" "applications.chrome"
"applications.discord" "applications.discord"
"applications.gnome-text-editor" "applications.gnome-text-editor"
"applications.handy"
"applications.kde" "applications.kde"
"applications.moonlight" "applications.moonlight"
"applications.slack" "applications.slack"