Function: completion--sifn-requote
completion--sifn-requote is a byte-compiled function defined in
minibuffer.el.gz.
Signature
(completion--sifn-requote UPOS QSTR)
Source Code
;; Defined in /usr/src/emacs/lisp/minibuffer.el.gz
(file-error nil))) ;PCM often calls with invalid directories.
(defun completion--sifn-requote (upos qstr)
;; We're looking for `qpos' such that:
;; (equal (substring (substitute-in-file-name qstr) 0 upos)
;; (substitute-in-file-name (substring qstr 0 qpos)))
;; Big problem here: we have to reverse engineer substitute-in-file-name to
;; find the position corresponding to UPOS in QSTR, but
;; substitute-in-file-name can do anything, depending on file-name-handlers.
;; substitute-in-file-name does the following kind of things:
;; - expand env-var references.
;; - turn backslashes into slashes.
;; - truncate some prefix of the input.
;; - rewrite some prefix.
;; Some of these operations are written in external libraries and we'd rather
;; not hard code any assumptions here about what they actually do. IOW, we
;; want to treat substitute-in-file-name as a black box, as much as possible.
;; Kind of like in rfn-eshadow-update-overlay, only worse.
;; Example of things we need to handle:
;; - Tramp (substitute-in-file-name "/foo:~/bar//baz") => "/scpc:foo:/baz".
;; - Cygwin (substitute-in-file-name "C:\bin") => "/usr/bin"
;; (substitute-in-file-name "C:\") => "/"
;; (substitute-in-file-name "C:\bi") => "/bi"
(let* ((ustr (substitute-in-file-name qstr))
(uprefix (substring ustr 0 upos))
qprefix)
;; Main assumption: nothing after qpos should affect the text before upos,
;; so we can work our way backward from the end of qstr, one character
;; at a time.
;; Second assumptions: If qpos is far from the end this can be a bit slow,
;; so we speed it up by doing a first loop that skips a word at a time.
;; This word-sized loop is careful not to cut in the middle of env-vars.
(while (let ((boundary (string-match "\\(\\$+{?\\)?\\w+\\W*\\'" qstr)))
(and boundary
(progn
(setq qprefix (substring qstr 0 boundary))
(string-prefix-p uprefix
(substitute-in-file-name qprefix)))))
(setq qstr qprefix))
(let ((qpos (length qstr)))
(while (and (> qpos 0)
(string-prefix-p uprefix
(substitute-in-file-name
(substring qstr 0 (1- qpos)))))
(setq qpos (1- qpos)))
(cons qpos #'minibuffer-maybe-quote-filename))))