On Mon, Nov 3, 2025 at 4:06 AM Arash Esbati <[email protected]> wrote:
>
> Hongyi Zhao <[email protected]> writes:
> > [...]
> > 4. Is there a more elegant way to configure
> > `completion-at-point-functions` itself to grant file completion higher
> > priority in these specific command-argument contexts?
>
> This is my setup for the cape package:
>
> (use-package cape
> :defer t
> :init
> (add-hook 'completion-at-point-functions #'cape-file 95)
>
> :custom
> (cape-file-prefix '("file:" "./" "../" "~/"))
>
> :bind (:map corfu-map
> ("C-c p f" . cape-file)))
>
> Not sure if it is an elegant way, but it works for me.
Based on my tests, when typing ./ and ../, cape-file always displays
the same list of filenames in the current directory, but my following
implementation doesn't have this issue:
```
(defun my/file-path-annotation-function (cand)
"An annotation function for file paths.
Returns ' Dir' for directories and ' File' for files."
(if (string-suffix-p "/" cand)
" Dir"
" File"))
(defun my/smart-cape-file ()
"A smart file completion backend that ONLY activates for path-like prefixes.
In all other cases, it returns nil, allowing the completion chain to proceed.
它只在路径上下文中激活,并注入一个标注函数来提供丰富的'File/Dir'界面。"
(interactive)
(let* ((end (point))
(start (save-excursion (re-search-backward "[ \t\n\\({]" nil t)))
(start (if start (1+ start) (line-beginning-position)))
;; 我们计算出用户输入的前缀
(prefix (buffer-substring-no-properties start end)))
;; 只有当这个前缀看起来像一个路径时 (以 ./ ../ ~/ / 开头),
;; 我们才返回一个 CAPF 指令。否则,我们返回 nil,保持沉默。
(when (string-match-p "\\`\\(\\.\\.?/\\|~\\|/\\)" prefix)
(list start end #'completion-file-name-table
:annotation-function #'my/file-path-annotation-function))))
```
> Best, Arash
Regards,
Zhao