   (load "osc52.el")
   (osc52-set-cut-function))
 
+; Activate standard copy-paste
+(cua-mode t)
+
+(defvar user-keys-mode-map (make-sparse-keymap) "user-keys-mode keymap.")
+
+(defun user-keys--empty-command ()
+  "do-nothing action to remove a default keybinding"
+  (interactive))
+
+(defvar user-keys-prefix "M-q" "Custom keybindings prefix in `kbd' format")
+
+(defun user-keys-reset ()
+  "Empty the mode keymap to remove all custom keybindings."
+  (setcdr user-keys-mode-map nil))
+
+(defun user-keys-disable (key-string)
+  (define-key user-keys-mode-map (kbd key-string) 'user-keys--empty-command))
+
+(defun user-keys-add (key-string command)
+  (define-key user-keys-mode-map (kbd key-string) command))
+
+(defun user-keys-make-command-wrap (lookup)
+  (lambda (&rest args)
+    "Wraped command"
+    (interactive (advice-eval-interactive-spec
+		  (let ((cmd (funcall lookup)))
+		    (when cmd (cadr (interactive-form command))))))
+    (let ((cmd (funcall lookup)))
+      (when cmd (apply cmd args)))))
+
+(defun user-keys-alias (global-key-string alias-key-string)
+  (let ((global-key (kbd global-key-string)))
+    (define-key
+      user-keys-mode-map
+      (kbd alias-key-string)
+      (user-keys-make-command-wrap
+       (lambda () (lookup-key (current-global-map) global-key))))))
+
+(defun user-keys-subkey (subkey-string command)
+  (define-key user-keys-mode-map (vconcat (kbd user-keys-prefix) (kbd subkey-string)) command))
+
+(defun user-keys-find-overwritten (key-string)
+  (let* ((key (kbd key-string))
+	 (local-map (current-local-map))
+	 (cmd (and local-map (lookup-key local-map key))))
+    (or cmd (lookup-key (current-global-map) key))))
+
+(defun user-keys-overwritten-prefix-command ()
+  (user-keys-make-command-wrap (lambda () (user-keys-find-overwritten user-keys-prefix))))
+
+(define-minor-mode user-keys-mode
+  "A minor mode that makes user-defined keys a priority over mode-specific or global keybindings."
+  :global t
+  :lighter "")
+
+;(define-globalized-minor-mode user-keys-mode user-keys-global-mode user-keys-mode)
+
+(add-to-list 'emulation-mode-map-alists `((user-keys-mode . ,user-keys-mode-map)))
+
+(user-keys-mode t)
+
+(defun user-keys-init-map ()
+  (user-keys-reset)
+  
+  (setcdr user-keys-mode-map nil)
+
+  ;; As Cua takes C-v, provide an alternative for scrolling. For now I
+  ;; use C-p/C-n as those are bound to line movements by default and
+  ;; so far keyboards always comes with arrow keys.
+  (user-keys-alias "<prior>" "C-p")
+  (user-keys-alias "<next>" "C-n")
+
+  ;; C-space may not be available in some window managers, so use
+  ;; Alt-Space for marking as well.
+  (user-keys-alias "C-SPC" "M-SPC")
+
+  (user-keys-add "C-x 3" 'my-2-window-split)
+
+  ;; Bindings to call the action overriden with user-keys-prefix
+  (user-keys-subkey "q" (user-keys-overwritten-prefix-command))
+
+  (user-keys-subkey "c" 'compile)
+  (user-keys-subkey "e" 'eshell)
+  (user-keys-subkey "g" 'grep)
+  (user-keys-subkey "r" 'rgrep)
+
+  ;; C-x k <enter> is too long for buffer kill, so make "prefix k" as
+  ;; shortcut.
+  ;;
+  ;; (user-keys-subkey "k" (lambda () (interactive) (kill-buffer nil)))
+
+  (user-keys-subkey "t" (lambda () (interactive) (my-run-terminal "term")))
+
+  (mapc (lambda (subkey-string)
+	  (let ((shell-buffer-name (concat "shell_" subkey-string)))
+	    (user-keys-subkey
+	     subkey-string
+	     (lambda () (interactive) (my-run-shell shell-buffer-name)))))
+	'("1" "2" "3" "4" "5" "6"))
+
+  ;; It is way too easy to type this accidentally
+  (user-keys-disable "<insert>")
+  (user-keys-disable "<insertchar>")
+
+  ;; TODO use what is <insert> is bound to currently
+  (user-keys-subkey
+   "<insert>"
+   (user-keys-make-command-wrap (lambda () (user-keys-find-overwritten "<insert>"))))
+
+
+  ;; Remove the binding for keyboard-escape-quit. It is way too easy
+  ;; to trigger it via autorepeat of the escape key.
+  (user-keys-disable (kbd "ESC ESC ESC"))
+
+  (user-keys-subkey
+   "i"
+   (user-keys-make-command-wrap (lambda () (and (fboundp 'ispell-region) 'ispell-region))))
+
+  (user-keys-subkey "f" 'my-toggle-fullscreen)
+
+  )
+
+(user-keys-init-map)
+
 ; Dynamic abbrev should copy the word it finds verbatim
 (setq dabbrev-case-replace nil)
 
-(global-set-key "\C-z" 'undo)
-
-; Extra copy-paste
-(global-set-key (kbd "C-S-v") 'yank)
-(global-set-key (kbd "C-S-c") 'kill-ring-save)
-
-;; C-space may not be available in some window managers, so 
-;; use Alt-Space for marking as well. 
-(global-set-key (kbd "M-SPC") 'set-mark-command)
-
 (when (fboundp 'ido-mode)
   (ido-mode 'buffers))
 
 ; Ignore accidental hiting of insert
-(global-unset-key [insert])
-(global-unset-key [insertchar])
+;(global-unset-key (kbd "<insert>"))
+;(global-unset-key (kbd "<insertchar>"))
 
 ; Remove the binding for keyboard-escape-quit. It is way too easy to trigger
 ; it via autorepeat of the escape key.
-(global-unset-key "\e\e\e")
-
-(global-unset-key "\C-x3")
-(global-set-key "\C-x3" 'my-2-window-split)
-
-; Custom bindings through a prefix key
-(let* ((my-prefix1 ?\M-q)
-       (old-prefix-action (lookup-key (current-global-map) (vector my-prefix1))) 
-       (f (lambda (key action)
-	    (global-set-key (vector my-prefix1 key) action)
-	    )))
-  (when old-prefix-action
-    (global-unset-key (vector my-prefix1))
-    (funcall f ?q old-prefix-action))
-    
-  (funcall f ?c 'compile)
-  (funcall f ?e 'eshell)
-  (funcall f ?g 'grep)
-  (funcall f ?r 'rgrep)
-
-  ;; C-x k <enter> is too long for buffer kill, so make f3 k as shortcut.
-  (funcall f ?k (lambda () (interactive) (kill-buffer nil)))
-
-  (funcall f ?t (lambda () (interactive) (my-run-terminal "term")))
-  (funcall f ?1 (lambda () (interactive) (my-run-shell "shell_1")))
-  (funcall f ?2 (lambda () (interactive) (my-run-shell "shell_2")))
-  (funcall f ?3 (lambda () (interactive) (my-run-shell "shell_3")))
-  (funcall f ?4 (lambda () (interactive) (my-run-shell "shell_4")))
-  (funcall f ?5 (lambda () (interactive) (my-run-shell "shell_5")))
-  (funcall f ?6 (lambda () (interactive) (my-run-shell "shell_6")))
-  (funcall f 'insert 'overwrite-mode)
-  (when (fboundp 'ispell-region)
-    (funcall f ?i 'ispell-region))
-  (funcall f ?f 'my-toggle-fullscreen)
-)
+(global-unset-key (kbd "ESC ESC ESC"))
+
 
 ; Bindings for the debugger
 (let ((dbg-prefix 'f5))

     (c-echo-syntactic-information-p . t)
     (fill-column . 78)))

  (c-add-style 
   "runit-java" 
   '("personal"
     (c-offsets-alist 
      . ((case-label . 0)
	 (statement-case-intro . +)
	 (statement-case-open . 0)))))

  (c-add-style 
   "c-tabs8"
   '("personal"
     (c-basic-offset . 8)
     (indent-tabs-mode . t)
     (c-offsets-alist 
      . ((case-label . 0)
	 (label . 0)
	 (statement-case-intro . +)
	 (statement-case-open . +)))))

  (c-add-style 
   "c-indent2"
   '("personal"
     (c-basic-offset . 2)))

(defun my-golang-hook ()
  (setq tab-width 4)
  (setq indent-tabs-mode 1))

(add-hook 'go-mode-hook 'my-golang-hook)

;; Key binding
