Skip to content


Subversion checkout URL

You can clone with
Download ZIP


Duplicate in candidates and a 'view property #54

wants to merge 13 commits into from

4 participants


I'm working on a source for auto-complete for C++ (with the help of the libclang).

In my pull request there is 2 'improvements' to the default auto-complete package:

  • A 'view property for "popup.el" This string property allow a popup to display an alternative text for a popup item.
  • Allowing duplicates in sources with (allow-dups) For example in my source for C++ I have something like: (defconst ac-source-irony '((candidates . (irony-ac-candidates ac-point)) (prefix . irony-get-completion-point) (requires . 0) (candidate-face . ac-irony-candidate-face) (selection-face . ac-irony-selection-face) (action . irony-ac-action) (allow-dups) ; <= HERE (cache)) "Auto-complete source for `irony-mode'.")

The goal is to display overloaded functions and being able to select the good function immediatly (an action expand the arguments of the function).

Here are 2 screenshots of the result:

I think C++ is one example where the same completion strings can mean different things and I think it's interesting to have a direct access to all of the strings (less keystrokes used IMHO).

note: the 'view property was inspired by a previous pull request (but I tried to integrate it better). I'm not sure this property is the best solution, maybe the change should be made in auto-complete.el and not in popup.el.

(I'm not really fluent in english, I hope it's not too bad.)


Big pull request. I will work on merging.


Thanks ! I think there is to many commits in my pull request, with only a small part "useful" at the end. I suggest you to only get the idea and maybe implement it in a cleaner way (I don't understand all of your code, my elisp skills is quite limited, I think you will be able to integrate things better than me).

The idea is to be able to display a string different from what it's really completed. For example if have 2 functions:

  • void test(int)
  • void test(char)

I want to complete the string "test" but I would like to have the 2 choices:

test(int) :void
test(char) :void

The two are meaningful because the action is not the same at the end. One will trigger a yasnippet expansion for the parameter int and the other for the char parameter.


Wow, this looks really useful, but I take it that it's not merged yet.

Sarcasm, how would the calling autocomplete source use this? (i.e. how to specify the method signature after the method name, and the type in the column to the right)


Here is a minimal working code (I think), you can try in your *scratch* buffer.

(defun make-item (sym signature result-type)
  (popup-make-item sym :view signature :summary result-type))

(defun generate-candidates ()
   (make-item "foo" "foo(int)"      "int")    ; int foo(int)
   (make-item "foo" "foo(int, int)" "int")    ; int foo(int, int)
   (make-item "bar" "bar(char)"     "void")   ; void bar(char)
   (make-item "bar" "bar()"         "void"))) ; void bar()

(defconst the-ac-source
  '((candidates . (generate-candidates))

(defun the-ac-complete ()
  (auto-complete '(the-ac-source)))

(local-set-key [(control return)] 'the-ac-complete)


I hope this help, it would be great to have this functionality the main branch of auto-complete.


@m2ym are you still working on merging this?

@Sarcasm Sarcasm referenced this pull request in Sarcasm/irony-mode

Don't use auto-complete fork #79

@m2ym m2ym closed this

Sorry for closing this without merging. I will improve the internal design of AC in next version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Aug 8, 2011
  1. @Sarcasm
Commits on Aug 9, 2011
  1. @Sarcasm
  2. @Sarcasm
Commits on Aug 10, 2011
  1. @Sarcasm
  2. @Sarcasm
Commits on Aug 18, 2011
  1. @Sarcasm
  2. @Sarcasm
Commits on Aug 23, 2011
  1. @Sarcasm

    Remove the custom 'delete-dups' and use a buffer local variable for a…

    Sarcasm authored
    …llowing duplicates or not.
  2. @Sarcasm


    Sarcasm authored
Commits on Sep 4, 2011
  1. @Sarcasm

    Now sources can set 'allow-dups to allow duplicates (the buffer local…

    Sarcasm authored
    … variable ac-allow-duplicates is removed).
  2. @Sarcasm

    Replace assoc-default with assq (like 'cache the 'allow-dups flag doe…

    Sarcasm authored
    …sn't need to have a value).
Commits on Sep 12, 2011
  1. @Sarcasm

    Remove a comment that describe "allow-dups" in the code, it would be …

    Sarcasm authored
    …better placed in the documentation.
Commits on Feb 4, 2013
  1. @Sarcasm
This page is out of date. Refresh to see the latest.
Showing with 35 additions and 26 deletions.
  1. +7 −1 auto-complete.el
  2. +28 −25 popup.el
8 auto-complete.el
@@ -292,6 +292,9 @@ a prefix doen't contain any upper case letters."
(defvar auto-complete-mode-hook nil
"Hook for `auto-complete-mode'.")
+(defvar ac-sarcasm-fork-version "0.1"
+ "Make this fork of auto-complete detectable.")
;;;; Internal variables
@@ -991,10 +994,13 @@ You can not use it in source definition like (prefix . `NAME')."
with case-fold-search = completion-ignore-case
with prefix-len = (length ac-prefix)
for source in ac-current-sources
+ if (assq 'allow-dups source) sum 1 into allow-dups
append (ac-candidates-1 source) into candidates
finally return
- (delete-dups candidates)
+ (if (zerop allow-dups)
+ (delete-dups candidates))
(if (and ac-use-comphist ac-comphist)
(if ac-show-menu
(let* ((pair (ac-comphist-sort ac-comphist candidates prefix-len ac-comphist-threshold))
53 popup.el
@@ -21,7 +21,7 @@
;;; Commentary:
;;; Code:
@@ -124,13 +124,13 @@ SQUEEZE nil means leave whitespaces other than line breaks untouched."
(progn ,@body)
(set-buffer-modified-p modified)))))
(defun popup-preferred-width (list)
"Return preferred width of popup to show `LIST' beautifully."
(loop with tab-width = 4
for item in list
for summary = (popup-item-summary item)
- maximize (string-width (popup-x-to-string item)) into width
+ maximize (string-width (popup-x-to-string (or (popup-item-view item) item))) into width
if (stringp summary)
maximize (+ (string-width summary) 2) into summary-width
finally return (* (ceiling (/ (+ (or width 0) (or summary-width 0)) 10.0)) 10)))
@@ -147,20 +147,20 @@ SQUEEZE nil means leave whitespaces other than line breaks untouched."
(setq window (selected-window)))
(unless (popup-window-full-width-p window)
(let ((t-p-w-w (buffer-local-value 'truncate-partial-width-windows
- (window-buffer window))))
+ (window-buffer window))))
(if (integerp t-p-w-w)
- (< (window-width window) t-p-w-w)
- t-p-w-w))))
+ (< (window-width window) t-p-w-w)
+ t-p-w-w))))
-(defun popup-current-physical-column ()
+(defun popup-current-physical-column (&optional window)
(or (when (and popup-use-optimized-column-computation
- (eq (window-hscroll) 0))
+ (eq (window-hscroll window) 0))
(let ((current-column (current-column)))
- (if (or (popup-truncated-partial-width-window-p)
+ (if (or (popup-truncated-partial-width-window-p window)
- (< current-column (window-width)))
+ (< current-column (window-width window)))
- (car (posn-col-row (posn-at-point)))))
+ (car (posn-col-row (posn-at-point nil window)))))
(defun popup-last-line-of-buffer-p ()
(save-excursion (end-of-line) (/= (forward-line) 0)))
@@ -239,7 +239,8 @@ SQUEEZE nil means leave whitespaces other than line breaks untouched."
- summary)
+ summary
+ view)
"Utility function to make popup item.
See also `popup-item-propertize'."
(popup-item-propertize name
@@ -249,6 +250,7 @@ See also `popup-item-propertize'."
'document document
'symbol symbol
'summary summary
+ 'view view
'sublist sublist))
(defsubst popup-item-value (item) (popup-item-property item 'value))
@@ -257,6 +259,7 @@ See also `popup-item-propertize'."
(defsubst popup-item-selection-face (item) (popup-item-property item 'selection-face))
(defsubst popup-item-document (item) (popup-item-property item 'document))
(defsubst popup-item-summary (item) (popup-item-property item 'summary))
+(defsubst popup-item-view (item) (popup-item-property item 'view))
(defsubst popup-item-symbol (item) (popup-item-property item 'symbol))
(defsubst popup-item-sublist (item) (popup-item-property item 'sublist))
@@ -299,7 +302,7 @@ See also `popup-item-propertize'."
(popup-set-filtered-list popup list)
(setf (popup-pattern popup) nil)
(setf (popup-original-list popup) list))
(defun popup-set-filtered-list (popup list)
(setf (popup-list popup) list
(popup-offset popup) (if (> (popup-direction popup) 0)
@@ -357,7 +360,7 @@ See also `popup-item-propertize'."
(defun popup-create-line-string (popup string margin-left margin-right symbol summary)
(let* ((popup-width (popup-width popup))
(summary-width (string-width summary))
- (string (car (popup-substring-by-width string
+ (string (car (popup-substring-by-width (or (popup-item-view string) string)
(- popup-width
(if (> summary-width 0)
(+ summary-width 2)
@@ -437,7 +440,7 @@ See also `popup-item-propertize'."
(goto-char (point-max))
(insert (make-string newlines ?\n))))
(if overflow
(if foldable
@@ -452,11 +455,11 @@ See also `popup-item-propertize'."
(decf column margin-left))
(when (and (null parent)
(< column 0))
- ;; Cancel margin left
+ ;; Cancel margin left
(setq column 0)
(decf popup-width margin-left)
(setq margin-left-cancel t))
(dotimes (i height)
(let (overlay begin w (dangle t) (prefix "") (postfix ""))
(when around
@@ -464,7 +467,7 @@ See also `popup-item-propertize'."
(vertical-motion (cons column direction))
(vertical-motion direction)
(move-to-column (+ (current-column) column))))
- (setq around t
+ (setq around t
current-column (popup-current-physical-column))
(when (> current-column column)
@@ -494,8 +497,8 @@ See also `popup-item-propertize'."
(overlay-put overlay 'postfix postfix)
(overlay-put overlay 'width width)
(aset overlays
- (if (> direction 0) i (- height i 1))
- overlay)))
+ (if (> direction 0) i (- height i 1))
+ overlay)))
(loop for p from (- 10000 (* depth 1000))
for overlay in (nreverse (append overlays nil))
do (overlay-put overlay 'priority p))
@@ -579,11 +582,11 @@ See also `popup-item-propertize'."
(concat " " (or (popup-item-symbol item) " "))
for summary = (or (popup-item-summary item) "")
;; Show line and set item to the line
(popup-set-line-item popup o item face margin-left margin-right scroll-bar-char sym summary)
;; Remember current height
(setf (popup-current-height popup) (- o offset))
@@ -687,7 +690,7 @@ See also `popup-item-propertize'."
(defvar popup-isearch-keymap
(let ((map (make-sparse-keymap)))
- ;(define-key map "\r" 'popup-isearch-done)
+ ;; (define-key map "\r" 'popup-isearch-done)
(define-key map "\C-g" 'popup-isearch-cancel)
(define-key map "\C-h" 'popup-isearch-delete)
(define-key map (kbd "DEL") 'popup-isearch-delete)
@@ -812,11 +815,11 @@ See also `popup-item-propertize'."
(and (eq margin t) (setq margin 1))
(or margin-left (setq margin-left margin))
(or margin-right (setq margin-right margin))
(let ((it (popup-fill-string string width popup-tip-max-width)))
(setq width (car it)
lines (cdr it)))
(setq tip (popup-create point width height
:min-height min-height
:around around
Something went wrong with that request. Please try again.