[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: display-completion-list should not strip text properties

From: Stefan Monnier
Subject: Re: display-completion-list should not strip text properties
Date: Mon, 22 Jan 2007 13:56:51 -0500
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.92 (gnu/linux)

> Also, I haven't yet done so for my own Lisp version, but I think that the
> measures 35 and 45 for the column width, which are currently hard-coded,
> could usefully be made into either parameters to the function or global
> variables. Different uses of a completion display might call for different
> column widths, and I see no reason to hard-code this choice.

For what it's worth I use the code below (part of some other lib, so it
wouldn't surprise me if it doesn't work as-is).
It chooses the number of columns based on how many can fit.


(defun complete-insert-strings (strings)
  "Insert a list of STRINGS into the current buffer.
Uses columns to keep the listing readable but compact.
It also eliminates runs of equal strings."
  (when (consp strings)
    (let* ((length (apply 'max
                          (mapcar (lambda (s)
                                    (if (consp s)
                                        (+ (length (car s)) (length (cadr s)))
                                      (length s)))
           (window (get-buffer-window (current-buffer)))
           (wwidth (if window (1- (window-width window)) 79))
           (columns (min
                     ;; At least 2 columns; at least 2 spaces between columns.
                     (max 2 (/ wwidth (+ 2 length)))
                     ;; Don't allocate more columns than we can fill.
                     ;; Windows can't show less than 3 lines anyway.
                     (max 1 (/ (length strings) 2))))
           (colwidth (/ wwidth columns))
           (laststring nil))
      ;; Use tab-width rather than indent-to.
      (setq tab-width colwidth)
      ;; The insertion should be "sensible" no matter what choices were made
      ;; for the parameters above.
      (dolist (str strings)
        (unless (equal laststring str)
          (setq laststring str)
          (unless (bolp) (insert " \t"))
          (when (< wwidth (+ (max colwidth
                                  (if (consp str)
                                      (+ (length (car str)) (length (cadr str)))
                                    (length str)))
            (delete-char -2) (insert "\n"))
          (if (not (consp str))
              (put-text-property (point) (progn (insert str) (point))
                                 'mouse-face 'highlight)
            (put-text-property (point) (progn (insert (car str)) (point))
                               'mouse-face 'highlight)
            (set-text-properties (point) (progn (insert (cadr str)) (point))

(defvar completion-common-substring)

(defun display-completion-list (completions &optional common-substring)
  "Display the list of completions, COMPLETIONS, using `standard-output'.
Each element may be just a symbol or string
or may be a list of two strings to be printed as if concatenated.
`standard-output' must be a buffer.
The actual completion alternatives, as inserted, are given `mouse-face'
properties of `highlight'.
At the end, this runs the normal hook `completion-setup-hook'.
It can find the completion buffer in `standard-output'."
  (if (not (bufferp standard-output))
      ;; This *never* (ever) happens, so there's no point trying to be clever.
        (let ((standard-output (current-buffer))
              (completion-setup-hook nil))
          (display-completion-list completions))
        (princ (buffer-string)))

    (completion-setup-function)         ;in simple.el
    (with-current-buffer standard-output
      (goto-char (point-max))
      (if (null completions)
          (insert "There are no possible completions of what you have typed.")
        (insert "Possible completions are:\n")
        (complete-insert-strings completions))))
  (let ((completion-common-substring common-substring))
    (run-hooks 'completion-setup-hook))

reply via email to

[Prev in Thread] Current Thread [Next in Thread]