diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 9d12e96f..d8481919 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -350,6 +350,9 @@ Makefile @thiagokokada
/modules/programs/topgrade.nix @msfjarvis
/tests/modules/programs/topgrade @msfjarvis
+/modules/programs/translate-shell.nix @marsam
+/tests/modules/programs/translate-shell @marsam
+
/modules/programs/vim-vint.nix @tomodachi94
/tests/modules/programs/vim-vint @tomodachi94
diff --git a/modules/modules.nix b/modules/modules.nix
index 69543ab2..ddc32535 100644
--- a/modules/modules.nix
+++ b/modules/modules.nix
@@ -188,6 +188,7 @@ let
./programs/tmate.nix
./programs/tmux.nix
./programs/topgrade.nix
+ ./programs/translate-shell.nix
./programs/urxvt.nix
./programs/vim.nix
./programs/vim-vint.nix
diff --git a/modules/programs/translate-shell.nix b/modules/programs/translate-shell.nix
new file mode 100644
index 00000000..8c179a36
--- /dev/null
+++ b/modules/programs/translate-shell.nix
@@ -0,0 +1,52 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ cfg = config.programs.translate-shell;
+
+ mkKeyValue = key: value:
+ let
+ formatValue = v:
+ if isBool v then
+ (if v then "true" else "false")
+ else if isString v then
+ ''"${v}"''
+ else if isList v then
+ "[ ${concatStringsSep " " (map formatValue v)} ]"
+ else
+ toString v;
+ in ":${key} ${formatValue value}";
+
+ toKeyValue = generators.toKeyValue { inherit mkKeyValue; };
+
+in {
+ meta.maintainers = [ maintainers.marsam ];
+
+ options.programs.translate-shell = {
+ enable = mkEnableOption "translate-shell";
+
+ settings = mkOption {
+ type = with types; attrsOf (oneOf [ bool str (listOf str) ]);
+ default = { };
+ example = {
+ verbose = true;
+ hl = "en";
+ tl = [ "es" "fr" ];
+ };
+ description = ''
+ Options to add to $XDG_CONFIG_HOME/translate-shell/init.trans file.
+ See
+ for options.
+ '';
+ };
+ };
+
+ config = mkIf cfg.enable {
+ home.packages = [ pkgs.translate-shell ];
+
+ xdg.configFile."translate-shell/init.trans" =
+ mkIf (cfg.settings != { }) { text = "{${toKeyValue cfg.settings}}"; };
+ };
+}
diff --git a/tests/default.nix b/tests/default.nix
index c4e009eb..b7a3c432 100644
--- a/tests/default.nix
+++ b/tests/default.nix
@@ -128,6 +128,7 @@ import nmt {
./modules/programs/tmate
./modules/programs/tmux
./modules/programs/topgrade
+ ./modules/programs/translate-shell
./modules/programs/vim-vint
./modules/programs/vscode
./modules/programs/watson
diff --git a/tests/modules/programs/translate-shell/default.nix b/tests/modules/programs/translate-shell/default.nix
new file mode 100644
index 00000000..539206a7
--- /dev/null
+++ b/tests/modules/programs/translate-shell/default.nix
@@ -0,0 +1 @@
+{ translate-shell = ./translate-shell.nix; }
diff --git a/tests/modules/programs/translate-shell/translate-shell.nix b/tests/modules/programs/translate-shell/translate-shell.nix
new file mode 100644
index 00000000..3c1d27bd
--- /dev/null
+++ b/tests/modules/programs/translate-shell/translate-shell.nix
@@ -0,0 +1,27 @@
+{ ... }:
+
+{
+ programs.translate-shell = {
+ enable = true;
+ settings = {
+ verbose = true;
+ engine = "bing";
+ play = true;
+ hl = "en";
+ tl = [ "de" "fr" ];
+ };
+ };
+
+ test.stubs.translate-shell = { };
+
+ nmt.script = ''
+ assertFileContent home-files/.config/translate-shell/init.trans \
+ ${builtins.toFile "translate-shell-expected-settings.trans" ''
+ {:engine "bing"
+ :hl "en"
+ :play true
+ :tl [ "de" "fr" ]
+ :verbose true
+ }''}
+ '';
+}