diff options
| author | Juri Linkov | 2022-06-12 19:45:15 +0300 |
|---|---|---|
| committer | Juri Linkov | 2022-06-12 19:45:15 +0300 |
| commit | e42d4d2ddf4f193c2e3b9391fd6b4cb4ea3ba4b3 (patch) | |
| tree | 6aeb2c0912b0e3e065de0ef96602df8d650ede05 | |
| parent | 1dd92bb7b8817038577626a13d7464a09e4d8a27 (diff) | |
| download | emacs-e42d4d2ddf4f193c2e3b9391fd6b4cb4ea3ba4b3.tar.gz emacs-e42d4d2ddf4f193c2e3b9391fd6b4cb4ea3ba4b3.zip | |
* 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).
| -rw-r--r-- | etc/NEWS | 6 | ||||
| -rw-r--r-- | lisp/isearch.el | 68 |
2 files changed, 62 insertions, 12 deletions
| @@ -1575,6 +1575,12 @@ If non-nil (which is the default), hitting 'RET' or 'mouse-1' on | |||
| 1575 | the directory components at the directory displayed at the start of | 1575 | the directory components at the directory displayed at the start of |
| 1576 | the buffer will take you to that directory. | 1576 | the buffer will take you to that directory. |
| 1577 | 1577 | ||
| 1578 | --- | ||
| 1579 | *** Search and replace in Dired/Wdired supports more regexps. | ||
| 1580 | For example, the regexp ".*" will match only characters that are part | ||
| 1581 | of the file name. Also "^.*$" can be used to match at the beginning | ||
| 1582 | of the file name and at the end of the file name. | ||
| 1583 | |||
| 1578 | ** Exif | 1584 | ** Exif |
| 1579 | 1585 | ||
| 1580 | --- | 1586 | --- |
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 | |||
| 4456 | 4456 | ||
| 4457 | 4457 | ||
| 4458 | (defun isearch-search-fun-in-text-property (property &optional search-fun) | 4458 | (defun isearch-search-fun-in-text-property (property &optional search-fun) |
| 4459 | "Return the function that searches inside fields. | 4459 | "Return the function that searches inside text properties. |
| 4460 | The arg PROPERTY defines the name of the text property that | 4460 | The arg PROPERTY defines the name of the text property, and the search |
| 4461 | delimits fields in the current buffer. Then the search will be | 4461 | will be narrowed to match only inside such text properties in the current |
| 4462 | narrowed to match only on such text properties. The optional arg | 4462 | buffer. The optional arg SEARCH-FUN can provide the default search |
| 4463 | SEARCH-FUN can provide the default search function which is | 4463 | function which is by default is the same as returned by |
| 4464 | by default is the same as returned by `isearch-search-fun-default'." | 4464 | `isearch-search-fun-default'." |
| 4465 | (lambda (string &optional bound noerror count) | 4465 | (lambda (string &optional bound noerror count) |
| 4466 | (let* ((old (point)) | 4466 | (let* ((old (point)) |
| 4467 | ;; Check if point is already on the property. | 4467 | ;; Check if point is already on the property. |
| @@ -4469,7 +4469,16 @@ by default is the same as returned by `isearch-search-fun-default'." | |||
| 4469 | (if isearch-forward old (max (1- old) (point-min))) | 4469 | (if isearch-forward old (max (1- old) (point-min))) |
| 4470 | property) | 4470 | property) |
| 4471 | old)) | 4471 | old)) |
| 4472 | end found) | 4472 | end found (i 0) |
| 4473 | (subregexp | ||
| 4474 | (and isearch-regexp | ||
| 4475 | (save-match-data | ||
| 4476 | (catch 'subregexp | ||
| 4477 | (while (string-match "\\^\\|\\$" string i) | ||
| 4478 | (setq i (match-end 0)) | ||
| 4479 | (when (subregexp-context-p string (match-beginning 0)) | ||
| 4480 | ;; The ^/$ is not inside a char-range or escaped. | ||
| 4481 | (throw 'subregexp t)))))))) | ||
| 4473 | ;; Otherwise, try to search for the next property. | 4482 | ;; Otherwise, try to search for the next property. |
| 4474 | (unless beg | 4483 | (unless beg |
| 4475 | (setq beg (if isearch-forward | 4484 | (setq beg (if isearch-forward |
| @@ -4482,12 +4491,47 @@ by default is the same as returned by `isearch-search-fun-default'." | |||
| 4482 | (setq end (if isearch-forward | 4491 | (setq end (if isearch-forward |
| 4483 | (next-single-property-change beg property) | 4492 | (next-single-property-change beg property) |
| 4484 | (previous-single-property-change beg property))) | 4493 | (previous-single-property-change beg property))) |
| 4485 | (setq found (funcall (or search-fun (isearch-search-fun-default)) | 4494 | ;; Handle ^/$ specially by matching in a temporary buffer. |
| 4486 | string (if bound (if isearch-forward | 4495 | (if subregexp |
| 4487 | (min bound end) | 4496 | (let* ((prop-beg |
| 4488 | (max bound end)) | 4497 | (if (or (if isearch-forward (bobp) (eobp)) |
| 4489 | end) | 4498 | (null (get-text-property |
| 4499 | (+ (point) (if isearch-forward -1 0)) | ||
| 4500 | property))) | ||
| 4501 | ;; Already at the beginning of the field. | ||
| 4502 | beg | ||
| 4503 | ;; Get the real beginning of the field when | ||
| 4504 | ;; the search was started in the middle. | ||
| 4505 | (if isearch-forward | ||
| 4506 | (previous-single-property-change beg property) | ||
| 4507 | (next-single-property-change beg property)))) | ||
| 4508 | (substring (buffer-substring prop-beg end)) | ||
| 4509 | (offset (if isearch-forward prop-beg end)) | ||
| 4510 | match-data) | ||
| 4511 | (with-temp-buffer | ||
| 4512 | (insert substring) | ||
| 4513 | (goto-char (- beg offset -1)) | ||
| 4514 | ;; Apply ^/$ regexp on the whole extracted substring. | ||
| 4515 | (setq found (funcall | ||
| 4516 | (or search-fun (isearch-search-fun-default)) | ||
| 4517 | string (and bound (max (point-min) | ||
| 4518 | (min (point-max) | ||
| 4519 | (- bound offset -1)))) | ||
| 4490 | noerror count)) | 4520 | noerror count)) |
| 4521 | ;; Adjust match data as if it's matched in original buffer. | ||
| 4522 | (when found | ||
| 4523 | (setq found (+ found offset -1) | ||
| 4524 | match-data (mapcar (lambda (m) (+ m offset -1)) | ||
| 4525 | (match-data))))) | ||
| 4526 | (when match-data (set-match-data match-data))) | ||
| 4527 | (setq found (funcall | ||
| 4528 | (or search-fun (isearch-search-fun-default)) | ||
| 4529 | string (if bound (if isearch-forward | ||
| 4530 | (min bound end) | ||
| 4531 | (max bound end)) | ||
| 4532 | end) | ||
| 4533 | noerror count))) | ||
| 4534 | ;; Get the next text property. | ||
| 4491 | (unless found | 4535 | (unless found |
| 4492 | (setq beg (if isearch-forward | 4536 | (setq beg (if isearch-forward |
| 4493 | (next-single-property-change end property) | 4537 | (next-single-property-change end property) |