]> rtime.felk.cvut.cz Git - sojka/company-mode.git/blobdiff - company.el
Bumped version to 0.4.2.
[sojka/company-mode.git] / company.el
index 681d9c26e7eb5855d490581ff7af341a03dd7c42..edd4797a81bf0bc43af3209a3426643b040ec69b 100644 (file)
@@ -3,7 +3,7 @@
 ;; Copyright (C) 2009 Nikolaj Schumacher
 ;;
 ;; Author: Nikolaj Schumacher <bugs * nschum de>
-;; Version: 0.4.1
+;; Version: 0.4.2
 ;; Keywords: abbrev, convenience, matchis
 ;; URL: http://nschum.de/src/emacs/company/
 ;; Compatibility: GNU Emacs 22.x, GNU Emacs 23.x
 ;;     ('meta (format "This value is named %s" arg))))
 ;;
 ;; Sometimes it is a good idea to mix two back-ends together, for example to
-;; enrich gtags with dabbrev text (to emulate local variables):
-;;
-;; (defun gtags-gtags-dabbrev-backend (command &optional arg &rest ignored)
-;;   (case command
-;;     (prefix (company-gtags 'prefix))
-;;     (candidates (append (company-gtags 'candidates arg)
-;;                         (company-dabbrev 'candidates arg)))))
+;; enrich gtags with dabbrev-code results (to emulate local variables):
+;; To do this, add a list with the merged back-ends as an element in
+;; company-backends.
 ;;
 ;; Known Issues:
 ;; When point is at the very end of the buffer, the pseudo-tooltip appears very
 ;;
 ;;; Change Log:
 ;;
+;; 2009-04-25 (0.4.2)
+;;    In C modes . and -> now count towards `company-minimum-prefix-length'.
+;;    Reverted default front-end back to `company-preview-if-just-one-frontend'.
+;;    The pseudo tooltip will no longer be clipped at the right window edge.
 ;;    Added `company-tooltip-minimum'.
 ;;    Windows compatibility fixes.
 ;;
   (set variable value))
 
 (defcustom company-frontends '(company-pseudo-tooltip-unless-just-one-frontend
-                               company-preview-frontend
+                               company-preview-if-just-one-frontend
                                company-echo-metadata-frontend)
   "*The list of active front-ends (visualizations).
 Each front-end is a function that takes one argument.  It is called with
@@ -306,7 +306,10 @@ of the following:
 'prefix: The back-end should return the text to be completed.  It must be
 text immediately before `point'.  Returning nil passes control to the next
 back-end.  The function should return 'stop if it should complete but cannot
-\(e.g. if it is in the middle of a string\).
+\(e.g. if it is in the middle of a string\).  If the returned value is only
+part of the prefix (e.g. the part after \"->\" in C), the back-end may return a
+cons of prefix and prefix length, which is then used in the
+`company-minimum-prefix-length' test.
 
 'candidates: The second argument is the prefix to be completed.  The
 return value should be a list of candidates that start with the prefix.
@@ -356,7 +359,7 @@ does not know about.  It should also be callable interactively and use
                                      company-safe-backends)
                            (symbol :tag "User defined"))))))
 
-(put 'company-backends 'safe-local-variable 'company-safe-backend-p)
+(put 'company-backends 'safe-local-variable 'company-safe-backends-p)
 
 (defcustom company-completion-started-hook nil
   "*Hook run when company starts completing.
@@ -911,17 +914,22 @@ keymap during active completions (`company-active-map'):
         (company-cancel company-prefix)
         nil)))))
 
+(defun company--good-prefix-p (prefix)
+  (and (or (company-explicit-action-p)
+           (>= (or (cdr-safe prefix) (length prefix))
+               company-minimum-prefix-length))
+       (stringp (or (car-safe prefix) prefix))))
+
 (defun company--continue ()
   (when (company-call-backend 'no-cache company-prefix)
     ;; Don't complete existing candidates, fetch new ones.
     (setq company-candidates-cache nil))
   (let* ((new-prefix (company-call-backend 'prefix))
-         (c (when (and (stringp new-prefix)
-                       (or (company-explicit-action-p)
-                           (>= (length new-prefix)
-                               company-minimum-prefix-length))
+         (c (when (and (company--good-prefix-p new-prefix)
+                       (setq new-prefix (or (car-safe new-prefix) new-prefix))
                        (= (- (point) (length new-prefix))
                           (- company-point (length company-prefix))))
+              (setq new-prefix (or (car-safe new-prefix) new-prefix))
               (company-calculate-candidates new-prefix))))
     (or (cond
          ((eq c t)
@@ -952,9 +960,9 @@ keymap during active completions (`company-active-map'):
                   (funcall backend 'prefix))
               (company--multi-backend-adapter backend 'prefix)))
       (when prefix
-        (when (and (stringp prefix)
-                   (>= (length prefix) company-minimum-prefix-length))
-          (setq company-backend backend
+        (when (company--good-prefix-p prefix)
+          (setq prefix (or (car-safe prefix) prefix)
+                company-backend backend
                 c (company-calculate-candidates prefix))
           ;; t means complete/unique.  We don't start, so no hooks.
           (when (consp c)
@@ -1356,7 +1364,7 @@ To show the number next to the candidates in some back-ends, enable
     (erase-buffer)
     (current-buffer)))
 
-(defmacro company-electric (&rest body)
+(defmacro company--electric-do (&rest body)
   (declare (indent 0) (debug t))
   `(when (company-manual-begin)
      (save-window-excursion
@@ -1376,7 +1384,7 @@ To show the number next to the candidates in some back-ends, enable
 (defun company-show-doc-buffer ()
   "Temporarily show a buffer with the complete documentation for the selection."
   (interactive)
-  (company-electric
+  (company--electric-do
     (let ((selected (nth company-selection company-candidates)))
       (display-buffer (or (company-call-backend 'doc-buffer selected)
                           (error "No documentation available")) t))))
@@ -1385,7 +1393,7 @@ To show the number next to the candidates in some back-ends, enable
 (defun company-show-location ()
   "Temporarily display a buffer showing the selected candidate in context."
   (interactive)
-  (company-electric
+  (company--electric-do
     (let* ((selected (nth company-selection company-candidates))
            (location (company-call-backend 'location selected))
            (pos (or (cdr location) (error "No location available")))
@@ -1410,7 +1418,8 @@ To show the number next to the candidates in some back-ends, enable
   (remove-hook 'company-completion-finished-hook company-callback t)
   (remove-hook 'company-completion-cancelled-hook 'company-remove-callback t)
   (remove-hook 'company-completion-finished-hook 'company-remove-callback t)
-  (set-marker company-begin-with-marker nil))
+  (when company-begin-with-marker
+    (set-marker company-begin-with-marker nil)))
 
 (defun company-begin-backend (backend &optional callback)
   "Start a completion at point using BACKEND."
@@ -1550,6 +1559,11 @@ Example:
     (length lst)))
 
 (defun company--replacement-string (lines old column nl &optional align-top)
+
+  (let ((width (length (car lines))))
+    (when (> width (- (window-width) column))
+      (setq column (max 0 (- (window-width) width)))))
+
   (let (new)
     (when align-top
       ;; untouched lines first
@@ -1565,7 +1579,7 @@ Example:
             (mapconcat 'identity (nreverse new) "\n")
             "\n")))
 
-(defun company-create-lines (column selection limit)
+(defun company--create-lines (selection limit)
 
   (let ((len company-candidates-length)
         (numbered 99999)
@@ -1594,7 +1608,7 @@ Example:
 
     (dotimes (i len)
       (setq width (max (length (pop lines-copy)) width)))
-    (setq width (min width (- (window-width) column)))
+    (setq width (min width (window-width)))
 
     (setq lines-copy lines)
 
@@ -1628,11 +1642,15 @@ Example:
 
 ;; show
 
+(defsubst company--window-inner-height ()
+  (let ((edges (window-inside-edges (selected-window))))
+    (- (nth 3 edges) (nth 1 edges))))
+
 (defsubst company--pseudo-tooltip-height ()
   "Calculate the appropriate tooltip height.
 Returns a negative number if the tooltip should be displayed above point."
-  (let* ((lines (1- (count-lines (window-start) (point-at-bol))))
-         (below (- (window-height) 3 lines)))
+  (let* ((lines (count-lines (window-start) (point-at-bol)))
+         (below (- (company--window-inner-height) 1 lines)))
     (if (and (< below (min company-tooltip-minimum company-candidates-length))
              (> lines below))
         (- (max 3 (min company-tooltip-limit lines)))
@@ -1644,34 +1662,33 @@ Returns a negative number if the tooltip should be displayed above point."
 
     (move-to-column 0)
 
-    (let ((height (company--pseudo-tooltip-height))
-          above lines nl beg end old-string str)
+    (let* ((height (company--pseudo-tooltip-height))
+           above)
 
       (when (< height 0)
         (setq row (+ row height -1)
               above t))
 
-      (setq lines (company-create-lines column selection (abs height))
-            nl (< (move-to-window-line row) row)
-            beg (point)
-            end (save-excursion
-                  (move-to-window-line (+ row (abs height)))
-                  (point))
-            old-string
-            (mapcar 'company-untabify (company-buffer-lines beg end)))
-
-      (setq company-pseudo-tooltip-overlay (make-overlay beg end))
-
-      (overlay-put company-pseudo-tooltip-overlay 'company-old old-string)
-      (overlay-put company-pseudo-tooltip-overlay 'company-column column)
-      (overlay-put company-pseudo-tooltip-overlay 'company-nl nl)
-      (overlay-put company-pseudo-tooltip-overlay 'company-above above)
-      (overlay-put company-pseudo-tooltip-overlay 'company-before
-                   (company--replacement-string lines old-string column nl
-                                                above))
-      (overlay-put company-pseudo-tooltip-overlay 'company-height (abs height))
-
-      (overlay-put company-pseudo-tooltip-overlay 'window (selected-window)))))
+      (let* ((nl (< (move-to-window-line row) row))
+             (beg (point))
+             (end (save-excursion
+                    (move-to-window-line (+ row (abs height)))
+                    (point)))
+             (ov (make-overlay beg end))
+             (args (list (mapcar 'company-untabify
+                                 (company-buffer-lines beg end))
+                         column nl above)))
+
+        (setq company-pseudo-tooltip-overlay ov)
+        (overlay-put ov 'company-replacement-args args)
+        (overlay-put ov 'company-before
+                     (apply 'company--replacement-string
+                            (company--create-lines selection (abs height))
+                            args))
+
+        (overlay-put ov 'company-column column)
+        (overlay-put ov 'company-height (abs height))
+        (overlay-put ov 'window (selected-window))))))
 
 (defun company-pseudo-tooltip-show-at-point (pos)
   (let ((col-row (company--col-row pos)))
@@ -1680,15 +1697,13 @@ Returns a negative number if the tooltip should be displayed above point."
                                    company-selection))))
 
 (defun company-pseudo-tooltip-edit (lines selection)
-  (let* ((old-string (overlay-get company-pseudo-tooltip-overlay 'company-old))
-         (column (overlay-get company-pseudo-tooltip-overlay 'company-column))
-         (nl (overlay-get company-pseudo-tooltip-overlay 'company-nl))
-         (height (overlay-get company-pseudo-tooltip-overlay 'company-height))
-         (above (overlay-get company-pseudo-tooltip-overlay 'company-above))
-         (lines (company-create-lines column selection (abs height))))
+  (let ((column (overlay-get company-pseudo-tooltip-overlay 'company-column))
+        (height (overlay-get company-pseudo-tooltip-overlay 'company-height)))
     (overlay-put company-pseudo-tooltip-overlay 'company-before
-                 (company--replacement-string lines old-string column nl
-                                              above))))
+                 (apply 'company--replacement-string
+                        (company--create-lines selection height)
+                        (overlay-get company-pseudo-tooltip-overlay
+                                     'company-replacement-args)))))
 
 (defun company-pseudo-tooltip-hide ()
   (when company-pseudo-tooltip-overlay