 
 ;; -- General, for all secondary buffers.
 
-(defun rdebug-secondary-buffer-populate-map (map &optional menu)
-  (define-key map " " 'gud-step)
-  (define-key map "+" 'gud-step-plus)
-  (define-key map "<" 'gud-up)
-  (define-key map ">" 'gud-down)
+;; Note, we re-populate the menus of the different minor and major
+;; modes. The reason is that Emacs caches the key bindings, which
+;; means that wrong ones are shown when buffers are changed.
+
+;; Remember, all menu items are added in the reverse order!
+
+;; TODO: This is a mix of commands that apply to dedicated buffers,
+;; the source buffers and the debugger shell buffer. Things like
+;; "delete breakpoint" can be in source and the breakpoints window,
+;; but not in the others.
+
+(defun rdebug-populate-debugger-menu (map)
+  "Populate the Rdebug 'Debugger' menu."
+  (let ((menu (make-sparse-keymap)))
+    (define-key map [menu-bar debugger] (cons "Debugger" menu))
+    (define-key menu [step] '(menu-item "Step into" gud-step))
+    (define-key menu [next] '(menu-item "Step over" gud-next))
+    (define-key menu [go] '(menu-item "Run" gud-cont))
+    (define-key menu [start] '(menu-item "Start the debugger" rdebug))
+
+    ;; --------------------
+    ;; The "Window Layout" submeny.
+    (let ((submenu (make-sparse-keymap)))
+      (define-key menu [layout] (cons "Window Layout" submenu)))
+
+    (define-key map [menu-bar debugger layout original]
+      '(menu-item "Original Layout" rdebug-display-original-window-configuration))
+
+    (define-key map [menu-bar debugger layout initial]
+      '(menu-item "Initial Debugger Layout" rdebug-restore-windows))
+
+    ;; --------------------
+    ;; The "Breakpoints" submeny.
+    (let ((submenu (make-sparse-keymap)))
+      (define-key menu [breakpoints] (cons "Breakpoints" submenu)))
+
+    (define-key map [menu-bar debugger breakpoints toggle]
+      '(menu-item "Toggle breakpoint" rdebug-toggle-breakpoint
+                  :enable (eq major-mode 'rdebug-breakpoints-mode)))
+
+    (define-key map [menu-bar debugger breakpoints goto]
+      '(menu-item "Goto breakpoint" rdebug-goto-breakpoint
+                  :enable (eq major-mode 'rdebug-breakpoints-mode)))
+    ;; The following are replaced with buffer-specific commands.
+    (define-key map [menu-bar debugger breakpoints delete]
+      '(menu-item "Delete breakpoint" gud-remove))
+
+    (define-key map [menu-bar debugger breakpoints set]
+      '(menu-item "Set breakpoint" gud-break
+                  :enable (not rdebug-secondary-buffer)))
+
+    ;; --------------------
+    ;; The "Variables" submeny.
+    (let ((submenu (make-sparse-keymap)))
+      (define-key menu [variables] (cons "Variables" submenu)))
+    (define-key map [menu-bar debugger variables edit]
+      '(menu-item "Edit" rdebug-variables-edit
+                  :enable (eq major-mode 'rdebug-variables-mode)))
+
+    ;; --------------------
+    ;; The "Watch" submeny.
+    (let ((submenu (make-sparse-keymap)))
+      (define-key menu [watch] (cons "Watch" submenu)))
+    (define-key map [menu-bar debugger watch delete]
+      '(menu-item "Delete" rdebug-display-delete
+                  :enable (eq major-mode 'rdebug-display-mode)))
+    (define-key map [menu-bar debugger watch goto]
+      '(menu-item "Edit" rdebug-display-edit
+                  :enable (eq major-mode 'rdebug-display-mode)))
+    (define-key map [menu-bar debugger watch add]
+      '(menu-item "Add" rdebug-display-add))
+
+    ;; --------------------
+    ;; The "View" submeny.
+    (let ((submenu (make-sparse-keymap)))
+      (define-key menu [view] (cons "View" submenu)))
+
+    (define-key map [menu-bar debugger view output]
+      '(menu-item "Output" rdebug-display-output-buffer))
+
+    (define-key map [menu-bar debugger view display]
+      '(menu-item "Watch" rdebug-display-display-buffer))
+
+    (define-key map [menu-bar debugger view breakpoints]
+      '(menu-item "Stack trace" rdebug-display-stack-buffer))
+
+    (define-key map [menu-bar debugger view shell]
+      '(menu-item "Debugger Shell" rdebug-display-cmd-buffer))
+
+    (define-key map [menu-bar debugger view variables]
+      '(menu-item "Variables" rdebug-display-variables-buffer))
+
+    (define-key map [menu-bar debugger view breakpoints]
+      '(menu-item "Breakpoints" rdebug-display-breakpoints-buffer))
+    menu))
+
+
+;; -- Ruby debugger support for other modes.
+
+(defvar rdebug-debugger-support-minor-mode-map
+  (let ((map (make-sparse-keymap)))
+    (rdebug-populate-common-keys map)
+    (rdebug-populate-debugger-menu map)
+    map))
+
+
+(define-minor-mode rdebug-debugger-support-minor-mode
+  "Minor mode active in source buffers that use Rdebug."
+  :group rdebug
+  :global nil
+  :init-value nil
+  :keymap rdebug-debugger-support-minor-mode-map
+  ())
+
+
+(defun rdebug-turn-on-debugger-support ()
+  "Activate debugger support in source buffer.
+
+This adds a menu and binds keys to debugger commands.
+
+Typically, this is added to the major mode hook, for example:
+
+  (add-hook 'ruby-mode-hook 'rdebug-turn-on-debugger-support)"
+  (rdebug-debugger-support-minor-mode 1))
+
+
+;; -- Secondary buffer support.
+
+;; TODO: rename no-menu to something like not-top-level.
+;;
+;; OR: pass two maps, one top level (for menu and common) and one
+;; submap for keys.
+(defun rdebug-populate-secondary-buffer-map (map &optional no-menu)
+  ;; Keys to view other buffers.
   (define-key map "?" 'rdebug-display-secondary-window-help-buffer)
   (define-key map "B" 'rdebug-display-breakpoints-buffer)
   (define-key map "C" 'rdebug-display-cmd-buffer)

(defvar rdebug-output-mode-map
  (let ((map (make-sparse-keymap)))
    (suppress-keymap map)
    (rdebug-secondary-buffer-populate-map map)
    map))

(defun rdebug-output-mode ()

    (define-key map [mouse-2] 'rdebug-variables-edit-mouse)
    (define-key map [mouse-3] 'rdebug-variables-edit-mouse)
    (define-key map "q" 'kill-this-buffer)
    (rdebug-populate-secondary-buffer-map map)
     map))

(defun rdebug-variables-mode ()
