diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index e8fb479bc85..a24b92cdae8 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -4982,11 +4982,6 @@ usual. Returns (ALL PAT PREFIX SUFFIX)." (prefix (substring beforepoint 0 (car bounds))) (suffix (substring afterpoint (cdr bounds))) (pat2 (substring pat (car bounds) (+ point (cdr bounds)))) - (completion-regexp-list - (cons (mapconcat (lambda (c) (regexp-quote (char-to-string c))) - pat2 - ".*") - completion-regexp-list)) (all (all-completions prefix table pred)) (all (if (zerop (length pat2)) all diff --git a/src/minibuf.c b/src/minibuf.c index c716ac0d811..745a71a63fc 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -2364,6 +2364,22 @@ STR the i-th character of PAT matched. */) if (patlen == 0 || strlen == 0 || size > FLEX_MAX_MATRIX_SIZE) return Qnil; + /* Also bail if PAT is not a subsequence of STR so bail "cheaply" + before the O(N*M) DP algorithm. Walking both strings + byte-by-byte for this purpose (and only for case-sensitive common + case) should be valid even for multibyte strings. */ + if (!completion_ignore_case) + { + const unsigned char *p = SDATA (pat); + const unsigned char *s = SDATA (str); + int pi = 0; + for (int si = 0; si < strlen && pi < patlen; si++) + if (s[si] == p[pi]) + pi++; + if (pi < patlen) + return Qnil; + } + /* Initialize M and D with positive infinity... */ for (int j = 0; j < size; j++) M[j] = D[j] = pos_inf;