Subject: bug#17284: Host name completion in shell mode take 45 seconds

From: Drew Adams <[email-masked]>
Date: Sat, 4 Apr 2015 07:46:40 -0700 (PDT)

> (defun string-before-p (string)
>    "Return t if string before `point' equals STRING."
>    (let ((start (- (point) (length string))))
>      (and (>= start (point-min))
> 	 (string-equal
> 	  (buffer-substring-no-properties start (point))
> 	  string))))

`buffer-substring-no-properties' is defined in C.  I can't tell
whether this is more efficient because of that or less efficient
because it creates a potentially giant string before starting to
compare.  I was trying to compare starting from the far end,
thinking that that might lead to earlier failure detection.

But I'll take your word for it that this is probably better.

(I guess if we were really worried about the long-string case we
could do what Isearch does, for the comparison.)

I didn't mention this before, because my implementation of
`chars-before' uses `char-before'.  But with such a function,
if it is defined without using `char-before' then the latter
function could be eliminated: (chars-before "a") instead of
(char-before ?a).

> And for simpler cases giving `char-before' a second argument
> to specify the position of the character before `point' might help too.

Yes.  (And that could apply as well to `chars-before', aka
`string-before-p' - optionally specify the start or end position.)

> But many occurrences of `looking-back' in the code base are inherently
> tied to regexps specified via defcustoms or passed as arguments and it
> doesn't seem easy to get rid of them.  Hence we should probably add a
> TODO item to fix all occurrences of `looking-back' either via the LIMIT
> argument, by string or character comparison.  An appetizing formulation
> of such an item would be very welcome.

Yes.  And I think you just formulated it, appetizingly enough. ;-)