diff --git a/modules/programs/readline.nix b/modules/programs/readline.nix
index 2658061f..fecb4572 100644
--- a/modules/programs/readline.nix
+++ b/modules/programs/readline.nix
@@ -21,7 +21,14 @@ let
           abort ("values ${toPretty v} is of unsupported type");
     in "set ${n} ${mkValueStr v}";
 
-  mkBindingStr = k: v: ''"${k}": ${v}'';
+  mkBindingStr = k: v:
+    let
+      isKeynameNotKeyseq = k:
+        builtins.elem (builtins.head (lib.splitString "-" (toLower k))) [
+          "control"
+          "meta"
+        ];
+    in if isKeynameNotKeyseq k then "${k}: ${v}" else ''"${k}": ${v}'';
 
 in {
   options.programs.readline = {
diff --git a/tests/modules/programs/readline/using-all-options.nix b/tests/modules/programs/readline/using-all-options.nix
index ab851020..85c9fc14 100644
--- a/tests/modules/programs/readline/using-all-options.nix
+++ b/tests/modules/programs/readline/using-all-options.nix
@@ -7,7 +7,10 @@ with lib;
     programs.readline = {
       enable = true;
 
-      bindings = { "\\C-h" = "backward-kill-word"; };
+      bindings = {
+        "\\C-h" = "backward-kill-word";
+        "Control-p" = ''"whups"'';
+      };
 
       variables = {
         bell-style = "audible";
diff --git a/tests/modules/programs/readline/using-all-options.txt b/tests/modules/programs/readline/using-all-options.txt
index 6b4aef51..e8f10932 100644
--- a/tests/modules/programs/readline/using-all-options.txt
+++ b/tests/modules/programs/readline/using-all-options.txt
@@ -4,6 +4,7 @@ $include /etc/inputrc
 set bell-style audible
 set completion-map-case on
 set completion-prefix-display-length 2
+Control-p: "whups"
 "\C-h": backward-kill-word
 $if mode=emacs
 "\e[1~": beginning-of-line