From: Juri Linkov Date: Sun, 12 Jun 2022 16:45:15 +0000 (+0300) Subject: * lisp/isearch.el (isearch-search-fun-in-text-property): Handle ^/$ specially. X-Git-Tag: emacs-29.0.90~1910^2~53 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=e42d4d2ddf4f193c2e3b9391fd6b4cb4ea3ba4b3;p=emacs.git * lisp/isearch.el (isearch-search-fun-in-text-property): Handle ^/$ specially. When the regexp contains ^ or $ then use a temporary buffer to find matches at the beginning/end of the region with the given text property (bug#14013). --- diff --git a/etc/NEWS b/etc/NEWS index 424d1250c33..6f00a51a708 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1575,6 +1575,12 @@ If non-nil (which is the default), hitting 'RET' or 'mouse-1' on the directory components at the directory displayed at the start of the buffer will take you to that directory. +--- +*** Search and replace in Dired/Wdired supports more regexps. +For example, the regexp ".*" will match only characters that are part +of the file name. Also "^.*$" can be used to match at the beginning +of the file name and at the end of the file name. + ** Exif --- diff --git a/lisp/isearch.el b/lisp/isearch.el index 5fbfb724a3c..fb52bfe30cb 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -4456,12 +4456,12 @@ LAX-WHITESPACE: The value of `isearch-lax-whitespace' and (defun isearch-search-fun-in-text-property (property &optional search-fun) - "Return the function that searches inside fields. -The arg PROPERTY defines the name of the text property that -delimits fields in the current buffer. Then the search will be -narrowed to match only on such text properties. The optional arg -SEARCH-FUN can provide the default search function which is -by default is the same as returned by `isearch-search-fun-default'." + "Return the function that searches inside text properties. +The arg PROPERTY defines the name of the text property, and the search +will be narrowed to match only inside such text properties in the current +buffer. The optional arg SEARCH-FUN can provide the default search +function which is by default is the same as returned by +`isearch-search-fun-default'." (lambda (string &optional bound noerror count) (let* ((old (point)) ;; Check if point is already on the property. @@ -4469,7 +4469,16 @@ by default is the same as returned by `isearch-search-fun-default'." (if isearch-forward old (max (1- old) (point-min))) property) old)) - end found) + end found (i 0) + (subregexp + (and isearch-regexp + (save-match-data + (catch 'subregexp + (while (string-match "\\^\\|\\$" string i) + (setq i (match-end 0)) + (when (subregexp-context-p string (match-beginning 0)) + ;; The ^/$ is not inside a char-range or escaped. + (throw 'subregexp t)))))))) ;; Otherwise, try to search for the next property. (unless beg (setq beg (if isearch-forward @@ -4482,12 +4491,47 @@ by default is the same as returned by `isearch-search-fun-default'." (setq end (if isearch-forward (next-single-property-change beg property) (previous-single-property-change beg property))) - (setq found (funcall (or search-fun (isearch-search-fun-default)) - string (if bound (if isearch-forward - (min bound end) - (max bound end)) - end) + ;; Handle ^/$ specially by matching in a temporary buffer. + (if subregexp + (let* ((prop-beg + (if (or (if isearch-forward (bobp) (eobp)) + (null (get-text-property + (+ (point) (if isearch-forward -1 0)) + property))) + ;; Already at the beginning of the field. + beg + ;; Get the real beginning of the field when + ;; the search was started in the middle. + (if isearch-forward + (previous-single-property-change beg property) + (next-single-property-change beg property)))) + (substring (buffer-substring prop-beg end)) + (offset (if isearch-forward prop-beg end)) + match-data) + (with-temp-buffer + (insert substring) + (goto-char (- beg offset -1)) + ;; Apply ^/$ regexp on the whole extracted substring. + (setq found (funcall + (or search-fun (isearch-search-fun-default)) + string (and bound (max (point-min) + (min (point-max) + (- bound offset -1)))) noerror count)) + ;; Adjust match data as if it's matched in original buffer. + (when found + (setq found (+ found offset -1) + match-data (mapcar (lambda (m) (+ m offset -1)) + (match-data))))) + (when match-data (set-match-data match-data))) + (setq found (funcall + (or search-fun (isearch-search-fun-default)) + string (if bound (if isearch-forward + (min bound end) + (max bound end)) + end) + noerror count))) + ;; Get the next text property. (unless found (setq beg (if isearch-forward (next-single-property-change end property)