Subject: bug#73656: 30.0.91; icomplete-vertical has no matches for M-x man RET chdir

From: Eli Zaretskii <[email-masked]>
Date: Sun, 13 Oct 2024 15:09:08 +0300

> From: Van Ly <[email-masked]>
> Cc: [email-masked], [email-masked]
> Date: Wed, 09 Oct 2024 23:43:12 +1100
> 
> 
> Eli Zaretskii <[email-masked]> writes:
> 
> >
> > I think this points out the problem: man.el expects a different
> > format, as documented in the doc string of Man-parse-man-k.  But maybe
> > I'm missing something, so I'll let others chime in.
> >
> > My suggestion is to step with Edebug through Man-parse-man-k and see
> > what's wrong there.
> >
> 
> 
> 
> The netbsd-users say legacy behavior for "man -k output" is obtained by
> 
> 
> 
>  $ man -k -l chdir
>  $ apropos -l chdir
>  $ env APROPOS="-l" emacs -Q
> 
> 
> 
> The Edebug session would cycle to line 16 below (line 953 in man.el)
> foreach of the characters from chdir during icomplete-vertical
> autocomplete to find no matches.
> 
> 
> 
>  1 (defun Man-parse-man-k ()
>  2   "Parse \"man -k\" output and return the list of page names.
>  3 
>  4 The current buffer should contain the output of a command of the
>  5 form \"man -k keyword\", which is traditionally also available with
>  6 apropos(1).
>  7 
>  8 While POSIX man(1p) is a bit vague about what to expect here,
>  9 this function tries to parse some commonly used formats, which
> 10 can be described in the following informal way, with square brackets
> 11 indicating optional parts and whitespace being interpreted
> 12 somewhat loosely.
> 13 
> 14 foo[, bar [, ...]] [other stuff] (sec) - description
> 15 foo(sec)[, bar(sec) [, ...]] [other stuff] - description"
> 16   (goto-char (point-min))
> 17   ;; See man-tests for data about which systems use which format (hopefully we
> 18   ;; will be able to simplify the code if/when some of those formats aren't
> 19   ;; used any more).
> 20   (let (table)
> 21     (while (search-forward-regexp "^\\([^ \t,\n]+\\)\\(.*?\\)\
> 22 \\(?:[ \t]\\(([^ \t,\n]+?)\\)\\)?\\(?:[ \t]+- ?\\(.*\\)\\)?$" nil t)
> 23       (let ((section (match-string 3))
> 24 	    (description (match-string 4))
> 25 	    (bound (match-end 2)))
> 26         (goto-char (match-end 1))
> 27 	(while
> 28             (progn
> 29               ;; The first regexp grouping may already match the section
> 30               ;; tacked on to the name, which is ok since for the formats we
> 31               ;; claim to support the third (non-shy) grouping does not
> 32               ;; match in this case, i.e., section is nil.
> 33               (push (propertize (concat (match-string 1) section)
> 34                                 'help-echo description)
> 35                     table)
> 36               (search-forward-regexp "\\=, *\\([^ \t,]+\\)" bound t)))))
> 37     (nreverse table)))

If you edit this part of Man-completion-table:

          (let ((process-environment (copy-sequence process-environment)))
            (setenv "COLUMNS" "999") ;; don't truncate long names
            ;; manual-program might not even exist.  And since it's
            ;; run differently in Man-getpage-in-background, an error
            ;; here may not necessarily mean that we'll also get an
            ;; error later.
            (when (eq 0
                      (ignore-errors
                        (process-file
                         manual-program nil '(t nil) nil
   >>>>>>>>>>>>>>>>      "-k" (concat (when (or Man-man-k-use-anchor
                                                (string-equal prefix ""))
                                        "^")
                                      (if (string-equal prefix "")
                                          prefix
                                        ;; FIXME: shell-quote-argument
                                        ;; is not entirely
                                        ;; appropriate: we actually
                                        ;; need to quote ERE here.
                                        ;; But we don't have that, and
                                        ;; shell-quote-argument does
                                        ;; the job...
                                        (shell-quote-argument prefix))))))
              (setq table (Man-parse-man-k)))))

to use "-k" "-l" instead of "-k" in the line I emphasized, does that
solve the problem?