]> code.delx.au - gnu-emacs-elpa/commitdiff
Use overriding active map.
authorNikolaj Schumacher <git@nschum.de>
Mon, 16 Mar 2009 01:34:06 +0000 (02:34 +0100)
committerNikolaj Schumacher <git@nschum.de>
Fri, 20 Mar 2009 11:50:05 +0000 (12:50 +0100)
company.el

index 627574b662023a23161a38b5593453626d8de5ef..f9cae142b0e4ff4f6395c48116a71af2d58db19d 100644 (file)
 
 ;;; mode ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
-(defvar company-current-map (make-sparse-keymap))
-
 (defvar company-mode-map (make-sparse-keymap))
 
 (defvar company-active-map
   (let ((keymap (make-sparse-keymap)))
-    (set-keymap-parent keymap company-mode-map)
     (define-key keymap (kbd "M-n") 'company-select-next)
     (define-key keymap (kbd "M-p") 'company-select-previous)
     (define-key keymap "\C-m" 'company-complete-selection)
 ;;;###autoload
 (define-minor-mode company-mode
   ""
-  nil " comp" nil
+  nil " comp" company-mode-map
   (if company-mode
       (progn
-        (add-to-list 'minor-mode-overriding-map-alist
-                     (cons 'company-mode company-current-map))
         (add-hook 'pre-command-hook 'company-pre-command nil t)
         (add-hook 'post-command-hook 'company-post-command nil t)
         (company-timer-set 'company-idle-delay
     (company-cancel)
     (kill-local-variable 'company-point)))
 
+;;; keymaps ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar company-overriding-keymap-bound nil)
+(make-variable-buffer-local 'company-overriding-keymap-bound)
+
+(defvar company-old-keymap nil)
+(make-variable-buffer-local 'company-old-keymap)
+
+(defvar company-my-keymap nil)
+(make-variable-buffer-local 'company-my-keymap)
+
+(defsubst company-enable-overriding-keymap (keymap)
+  (setq company-my-keymap keymap)
+  (when company-overriding-keymap-bound
+    (company-uninstall-map)))
+
+(defun company-install-map ()
+  (unless (or company-overriding-keymap-bound
+              (null company-my-keymap))
+    (setq company-old-keymap overriding-terminal-local-map
+          overriding-terminal-local-map company-my-keymap
+          company-overriding-keymap-bound t)))
+
+(defun company-uninstall-map ()
+  (when (and company-overriding-keymap-bound
+             (eq overriding-terminal-local-map company-my-keymap))
+    (setq overriding-terminal-local-map company-old-keymap
+          company-overriding-keymap-bound nil)))
+
+;; Hack:
+;; Emacs calculates the active keymaps before reading the event.  That means we
+;; cannot change the keymap from a timer.  So we send a bogus command.
+(defun company-ignore ()
+  (interactive))
+
+(global-set-key '[31415926] 'company-ignore)
+
+(defun company-input-noop ()
+  (push 31415926 unread-command-events))
+
 ;;; backends ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 (defun company-grab (regexp &optional expression)
        (not (equal (point) company-point))
        (let ((company-idle-delay t))
          (company-begin)
-         (company-post-command))))
+         (when company-candidates
+           (company-input-noop)
+           (company-post-command)))))
 
 (defun company-manual-begin ()
   (and company-mode
   (if company-candidates
       (progn
         (setq company-point (point))
-        (set-keymap-parent company-current-map company-active-map)
+        (company-enable-overriding-keymap company-active-map)
         (company-call-frontends 'update))
     (company-cancel)))
 
         company-selection-changed nil
         company-point nil)
   (company-call-frontends 'hide)
-  (set-keymap-parent company-current-map company-mode-map))
+  (company-enable-overriding-keymap nil))
 
 (defun company-abort ()
   (company-cancel)
           (company-call-frontends 'pre-command))
       (error (message "Company: An error occurred in pre-command")
              (message "%s" (error-message-string err))
-             (company-cancel)))))
+             (company-cancel))))
+  (company-uninstall-map))
 
 (defun company-post-command ()
   (unless (eq this-command 'company-show-doc-buffer)
             (company-call-frontends 'post-command)))
       (error (message "Company: An error occurred in post-command")
              (message "%s" (error-message-string err))
-             (company-cancel)))))
+             (company-cancel))))
+  (company-install-map))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;