Due to various/extensive remappings I insert symbols with Control+key, for example Ctrl+9 inserts a left parenthesis (. This works fine with the remappings and the insert/insert-commands, however, modes such as smartparens do not catch this. In my example hitting Ctrl+9 with spartparens should insert a pair of parentheses () instead of a single one (which works using Shift+9). I suspect that the problem is due to using insert/insert-char instead of self-insert-command so the mode does not see/register the event. I wonder if anyone has any idea for a fix?

This my setup code for reference, essentially a loop over a macro that sets up a global keybinding for C-[unshifted char] to [corresponding shifted char]:

; Bind Ctrl as shift for symbols.
(defun my-bind-symbols-to-crtl ()
  (let ( (chars (split-string
                 "~1234567890-=;']\\,./" ""))
         (shifted-chars (split-string
                         "`!@#$%^&*()_+:\"}|<>?" ""))
         (char "") (shifted-char "") )
    (while chars
      (setq char (pop chars))
      (setq shifted-char (pop shifted-chars))
      (when (> (length char) 0)
        (global-set-key (kbd (concat "C-" char)) (eval(macroexpand `(insert-key-macro ,shifted-char)))) ) )))

(defmacro insert-key-macro (in)
  `(lambda () (interactive) (insert ,in)))
(global-set-key (kbd "H-[") (lambda () (interactive) (insert "{")))
(define-key input-decode-map (kbd "C-[") (kbd "H-["))
  • Welcome. Can you provide some code showing how you implement this? Commented Mar 10, 2015 at 9:48
  • 1
    One alternative would be to use function-key-map to translate C-9 to S-9 and then let nature take its course. Commented Mar 10, 2015 at 10:29
  • 1
    (define-key input-decode-map (kbd (concat "C-" char)) (kbd shifted-char))))
    – user6729
    Commented Mar 10, 2015 at 10:41
  • 1
    Just so you know, smartparens does it's work with a function in post-self-insert-hooks, You could just (run-hooks 'post-self-insert-hooks) after inserting. But I think @Lindydancer's solution is the better one. Commented Mar 10, 2015 at 13:19

1 Answer 1


Keys defined by global-set-key are shadowed by any local binding. In your case using key-translation-map seems more appropriate. Also, when defining keys, you can use a string (interpreted as a keyboard macro) instead of a command. This would greatly simplify your code:

(defun my-bind-symbols-to-crtl ()
   (lambda (char shifted-char)
     (define-key key-translation-map (kbd (concat "C-" char))
    "~1234567890-=;']\\,./" "" t)
    "`!@#$%^&*()_+:\"}|<>?" "" t)))


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.