+(defvar widget)
+
+(defun widget-string-complete ()
+ "Complete contents of string field.
+Completions are taken from the :completion-alist property of the
+widget. If that isn't a list, it's evalled and expected to yield a list."
+ (interactive)
+ (let* ((prefix (buffer-substring-no-properties (widget-field-start widget)
+ (point)))
+ (completion-ignore-case (widget-get widget :completion-ignore-case))
+ (alist (widget-get widget :completion-alist))
+ (_ (unless (listp alist)
+ (setq alist (eval alist))))
+ (completion (try-completion prefix alist)))
+ (cond ((eq completion t)
+ (when completion-ignore-case
+ ;; Replace field with completion in case its case is different.
+ (delete-region (widget-field-start widget)
+ (widget-field-end widget))
+ (insert-and-inherit (car (assoc-string prefix alist t))))
+ (message "Only match"))
+ ((null completion)
+ (error "No match"))
+ ((not (eq t (compare-strings prefix nil nil completion nil nil
+ completion-ignore-case)))
+ (when completion-ignore-case
+ ;; Replace field with completion in case its case is different.
+ (delete-region (widget-field-start widget)
+ (widget-field-end widget))
+ (insert-and-inherit completion)))
+ (t
+ (message "Making completion list...")
+ (with-output-to-temp-buffer "*Completions*"
+ (display-completion-list
+ (all-completions prefix alist nil)))
+ (message "Making completion list...done")))))
+