Subject: bug#36372: 27.0.50; replace-regexp-in-string skips START first chars in return value [PATCH]

From: Clément Pit-Claudel <[email-masked]>
Date: Wed, 26 Jun 2019 11:59:35 -0400

On 2019-06-26 11:20, Mattias Engdegård wrote:
> Clément, apologies for dragging you into the discussion, but when you woke up this morning, you probably didn't know that you were possibly the only man in history to use the last argument to replace-regexp-in-string.

Well, my morning just got a lot more interesting :)

> Now I would be curious to know:
> 
> (1) Does this code, in company-coq--loc-fully-qualified-name, actually work the way you intended? (Looks like it.)

Yes, I think it does.  It's a bit inscrutable, so here's an annotated copy:

(defun company-coq--loc-fully-qualified-name (fqn)
  ;; assume fqn is Coq.Init.Nat.max
  (let* ((spec (company-coq-longest-matching-path-spec fqn))
         ;; … spec is ("Coq.Init" . "/build/coq/theories/Init/")
         (logical (if spec (concat (car spec) ".") ""))
         ;; … logical is "Coq.Init."
         (mod-name (replace-regexp-in-string "\\..*\\'" "" fqn nil nil nil (length logical))))
         ;; … mod-name is "Nat"
    (company-coq-library-path logical mod-name spec)))
    ;; … return /build/coq/theories/Init/Nat.v

The reason for this odd dance is that a Coq identifier is essentially a directory path (Coq.Init.) + a file name (here Nat.) + an identifier name (max).  But in some cases there can be modules in the path too, like maybe Coq.Init.Nat.XYZ.max, and in those cases the file is still only 'Nat.' 

This code would probably be clearer if I just used a substring to trim out the beginning of the string ^^

> (2) Did you learn how the START parameter affects the return value by reading the doc string, the manual, the source code, or by testing?

Almost certainly the docstring, confirmed by testing.  I haven't looked at this section of the manual.  

> (3) Are you aware of other code using the START parameter to replace-regexp-in-string?

Nothing off the top of my head, but I probably wouldn't have thought of the instance in company-coq either.  A quick grep through my local sources doesn't turn up anything else, but a quick visual check isn't a very reliable method (did you use a plain grep to find the instance in company-coq, or do you have a more sophisticated trick?).

Hope this helps,
Clément.