diff options
| author | Tom Tromey | 2013-06-03 12:25:05 -0600 |
|---|---|---|
| committer | Tom Tromey | 2013-06-03 12:25:05 -0600 |
| commit | 68359abba96d7ec4db8aab3d3dd9cf1105c3bab5 (patch) | |
| tree | 862703e7e1a1888170136a8296a5750d6b2ae2eb /lisp/replace.el | |
| parent | cbcba8ce7f980b01c18c0fd561ef6687b1361507 (diff) | |
| parent | e2d8a6f0a229b4ebe26484b892ec4f14888f58b6 (diff) | |
| download | emacs-68359abba96d7ec4db8aab3d3dd9cf1105c3bab5.tar.gz emacs-68359abba96d7ec4db8aab3d3dd9cf1105c3bab5.zip | |
merge from trunk; clean up some issues
Diffstat (limited to 'lisp/replace.el')
| -rw-r--r-- | lisp/replace.el | 374 |
1 files changed, 236 insertions, 138 deletions
diff --git a/lisp/replace.el b/lisp/replace.el index 17eea19edd8..af05bd11fb2 100644 --- a/lisp/replace.el +++ b/lisp/replace.el | |||
| @@ -250,6 +250,10 @@ letters. \(Transferring the case pattern means that if the old text | |||
| 250 | matched is all caps, or capitalized, then its replacement is upcased | 250 | matched is all caps, or capitalized, then its replacement is upcased |
| 251 | or capitalized.) | 251 | or capitalized.) |
| 252 | 252 | ||
| 253 | Ignore read-only matches if `query-replace-skip-read-only' is non-nil, | ||
| 254 | ignore hidden matches if `search-invisible' is nil, and ignore more | ||
| 255 | matches using a non-nil `isearch-filter-predicates'. | ||
| 256 | |||
| 253 | If `replace-lax-whitespace' is non-nil, a space or spaces in the string | 257 | If `replace-lax-whitespace' is non-nil, a space or spaces in the string |
| 254 | to be replaced will match a sequence of whitespace chars defined by the | 258 | to be replaced will match a sequence of whitespace chars defined by the |
| 255 | regexp in `search-whitespace-regexp'. | 259 | regexp in `search-whitespace-regexp'. |
| @@ -300,6 +304,10 @@ pattern of the old text to the new text, if `case-replace' and | |||
| 300 | all caps, or capitalized, then its replacement is upcased or | 304 | all caps, or capitalized, then its replacement is upcased or |
| 301 | capitalized.) | 305 | capitalized.) |
| 302 | 306 | ||
| 307 | Ignore read-only matches if `query-replace-skip-read-only' is non-nil, | ||
| 308 | ignore hidden matches if `search-invisible' is nil, and ignore more | ||
| 309 | matches using a non-nil `isearch-filter-predicates'. | ||
| 310 | |||
| 303 | If `replace-regexp-lax-whitespace' is non-nil, a space or spaces in the regexp | 311 | If `replace-regexp-lax-whitespace' is non-nil, a space or spaces in the regexp |
| 304 | to be replaced will match a sequence of whitespace chars defined by the | 312 | to be replaced will match a sequence of whitespace chars defined by the |
| 305 | regexp in `search-whitespace-regexp'. | 313 | regexp in `search-whitespace-regexp'. |
| @@ -380,6 +388,10 @@ that reads REGEXP. | |||
| 380 | Preserves case in each replacement if `case-replace' and `case-fold-search' | 388 | Preserves case in each replacement if `case-replace' and `case-fold-search' |
| 381 | are non-nil and REGEXP has no uppercase letters. | 389 | are non-nil and REGEXP has no uppercase letters. |
| 382 | 390 | ||
| 391 | Ignore read-only matches if `query-replace-skip-read-only' is non-nil, | ||
| 392 | ignore hidden matches if `search-invisible' is nil, and ignore more | ||
| 393 | matches using a non-nil `isearch-filter-predicates'. | ||
| 394 | |||
| 383 | If `replace-regexp-lax-whitespace' is non-nil, a space or spaces in the regexp | 395 | If `replace-regexp-lax-whitespace' is non-nil, a space or spaces in the regexp |
| 384 | to be replaced will match a sequence of whitespace chars defined by the | 396 | to be replaced will match a sequence of whitespace chars defined by the |
| 385 | regexp in `search-whitespace-regexp'. | 397 | regexp in `search-whitespace-regexp'. |
| @@ -470,6 +482,10 @@ are non-nil and FROM-STRING has no uppercase letters. | |||
| 470 | \(Preserving case means that if the string matched is all caps, or capitalized, | 482 | \(Preserving case means that if the string matched is all caps, or capitalized, |
| 471 | then its replacement is upcased or capitalized.) | 483 | then its replacement is upcased or capitalized.) |
| 472 | 484 | ||
| 485 | Ignore read-only matches if `query-replace-skip-read-only' is non-nil, | ||
| 486 | ignore hidden matches if `search-invisible' is nil, and ignore more | ||
| 487 | matches using a non-nil `isearch-filter-predicates'. | ||
| 488 | |||
| 473 | If `replace-lax-whitespace' is non-nil, a space or spaces in the string | 489 | If `replace-lax-whitespace' is non-nil, a space or spaces in the string |
| 474 | to be replaced will match a sequence of whitespace chars defined by the | 490 | to be replaced will match a sequence of whitespace chars defined by the |
| 475 | regexp in `search-whitespace-regexp'. | 491 | regexp in `search-whitespace-regexp'. |
| @@ -512,6 +528,10 @@ and TO-STRING is also null.)" | |||
| 512 | Preserve case in each match if `case-replace' and `case-fold-search' | 528 | Preserve case in each match if `case-replace' and `case-fold-search' |
| 513 | are non-nil and REGEXP has no uppercase letters. | 529 | are non-nil and REGEXP has no uppercase letters. |
| 514 | 530 | ||
| 531 | Ignore read-only matches if `query-replace-skip-read-only' is non-nil, | ||
| 532 | ignore hidden matches if `search-invisible' is nil, and ignore more | ||
| 533 | matches using a non-nil `isearch-filter-predicates'. | ||
| 534 | |||
| 515 | If `replace-regexp-lax-whitespace' is non-nil, a space or spaces in the regexp | 535 | If `replace-regexp-lax-whitespace' is non-nil, a space or spaces in the regexp |
| 516 | to be replaced will match a sequence of whitespace chars defined by the | 536 | to be replaced will match a sequence of whitespace chars defined by the |
| 517 | regexp in `search-whitespace-regexp'. | 537 | regexp in `search-whitespace-regexp'. |
| @@ -1125,6 +1145,14 @@ If the value is nil, don't highlight the buffer names specially." | |||
| 1125 | :type 'face | 1145 | :type 'face |
| 1126 | :group 'matching) | 1146 | :group 'matching) |
| 1127 | 1147 | ||
| 1148 | (defcustom list-matching-lines-prefix-face 'shadow | ||
| 1149 | "Face used by \\[list-matching-lines] to show the prefix column. | ||
| 1150 | If the face doesn't differ from the default face, | ||
| 1151 | don't highlight the prefix with line numbers specially." | ||
| 1152 | :type 'face | ||
| 1153 | :group 'matching | ||
| 1154 | :version "24.4") | ||
| 1155 | |||
| 1128 | (defcustom occur-excluded-properties | 1156 | (defcustom occur-excluded-properties |
| 1129 | '(read-only invisible intangible field mouse-face help-echo local-map keymap | 1157 | '(read-only invisible intangible field mouse-face help-echo local-map keymap |
| 1130 | yank-handler follow-link) | 1158 | yank-handler follow-link) |
| @@ -1334,7 +1362,9 @@ See also `multi-occur'." | |||
| 1334 | (isearch-no-upper-case-p regexp t) | 1362 | (isearch-no-upper-case-p regexp t) |
| 1335 | case-fold-search) | 1363 | case-fold-search) |
| 1336 | list-matching-lines-buffer-name-face | 1364 | list-matching-lines-buffer-name-face |
| 1337 | nil list-matching-lines-face | 1365 | (if (face-differs-from-default-p list-matching-lines-prefix-face) |
| 1366 | list-matching-lines-prefix-face) | ||
| 1367 | list-matching-lines-face | ||
| 1338 | (not (eq occur-excluded-properties t)))))) | 1368 | (not (eq occur-excluded-properties t)))))) |
| 1339 | (let* ((bufcount (length active-bufs)) | 1369 | (let* ((bufcount (length active-bufs)) |
| 1340 | (diff (- (length bufs) bufcount))) | 1370 | (diff (- (length bufs) bufcount))) |
| @@ -1359,16 +1389,18 @@ See also `multi-occur'." | |||
| 1359 | (defun occur-engine (regexp buffers out-buf nlines case-fold | 1389 | (defun occur-engine (regexp buffers out-buf nlines case-fold |
| 1360 | title-face prefix-face match-face keep-props) | 1390 | title-face prefix-face match-face keep-props) |
| 1361 | (with-current-buffer out-buf | 1391 | (with-current-buffer out-buf |
| 1362 | (let ((globalcount 0) | 1392 | (let ((global-lines 0) ;; total count of matching lines |
| 1393 | (global-matches 0) ;; total count of matches | ||
| 1363 | (coding nil) | 1394 | (coding nil) |
| 1364 | (case-fold-search case-fold)) | 1395 | (case-fold-search case-fold)) |
| 1365 | ;; Map over all the buffers | 1396 | ;; Map over all the buffers |
| 1366 | (dolist (buf buffers) | 1397 | (dolist (buf buffers) |
| 1367 | (when (buffer-live-p buf) | 1398 | (when (buffer-live-p buf) |
| 1368 | (let ((matches 0) ;; count of matched lines | 1399 | (let ((lines 0) ;; count of matching lines |
| 1369 | (lines 1) ;; line count | 1400 | (matches 0) ;; count of matches |
| 1370 | (prev-after-lines nil) ;; context lines of prev match | 1401 | (curr-line 1) ;; line count |
| 1371 | (prev-lines nil) ;; line number of prev match endpt | 1402 | (prev-line nil) ;; line number of prev match endpt |
| 1403 | (prev-after-lines nil) ;; context lines of prev match | ||
| 1372 | (matchbeg 0) | 1404 | (matchbeg 0) |
| 1373 | (origpt nil) | 1405 | (origpt nil) |
| 1374 | (begpt nil) | 1406 | (begpt nil) |
| @@ -1389,7 +1421,7 @@ See also `multi-occur'." | |||
| 1389 | (while (not (eobp)) | 1421 | (while (not (eobp)) |
| 1390 | (setq origpt (point)) | 1422 | (setq origpt (point)) |
| 1391 | (when (setq endpt (re-search-forward regexp nil t)) | 1423 | (when (setq endpt (re-search-forward regexp nil t)) |
| 1392 | (setq matches (1+ matches)) ;; increment match count | 1424 | (setq lines (1+ lines)) ;; increment matching lines count |
| 1393 | (setq matchbeg (match-beginning 0)) | 1425 | (setq matchbeg (match-beginning 0)) |
| 1394 | ;; Get beginning of first match line and end of the last. | 1426 | ;; Get beginning of first match line and end of the last. |
| 1395 | (save-excursion | 1427 | (save-excursion |
| @@ -1398,7 +1430,7 @@ See also `multi-occur'." | |||
| 1398 | (goto-char endpt) | 1430 | (goto-char endpt) |
| 1399 | (setq endpt (line-end-position))) | 1431 | (setq endpt (line-end-position))) |
| 1400 | ;; Sum line numbers up to the first match line. | 1432 | ;; Sum line numbers up to the first match line. |
| 1401 | (setq lines (+ lines (count-lines origpt begpt))) | 1433 | (setq curr-line (+ curr-line (count-lines origpt begpt))) |
| 1402 | (setq marker (make-marker)) | 1434 | (setq marker (make-marker)) |
| 1403 | (set-marker marker matchbeg) | 1435 | (set-marker marker matchbeg) |
| 1404 | (setq curstring (occur-engine-line begpt endpt keep-props)) | 1436 | (setq curstring (occur-engine-line begpt endpt keep-props)) |
| @@ -1407,6 +1439,7 @@ See also `multi-occur'." | |||
| 1407 | (start 0)) | 1439 | (start 0)) |
| 1408 | (while (and (< start len) | 1440 | (while (and (< start len) |
| 1409 | (string-match regexp curstring start)) | 1441 | (string-match regexp curstring start)) |
| 1442 | (setq matches (1+ matches)) | ||
| 1410 | (add-text-properties | 1443 | (add-text-properties |
| 1411 | (match-beginning 0) (match-end 0) | 1444 | (match-beginning 0) (match-end 0) |
| 1412 | (append | 1445 | (append |
| @@ -1420,10 +1453,10 @@ See also `multi-occur'." | |||
| 1420 | ;; Generate the string to insert for this match | 1453 | ;; Generate the string to insert for this match |
| 1421 | (let* ((match-prefix | 1454 | (let* ((match-prefix |
| 1422 | ;; Using 7 digits aligns tabs properly. | 1455 | ;; Using 7 digits aligns tabs properly. |
| 1423 | (apply #'propertize (format "%7d:" lines) | 1456 | (apply #'propertize (format "%7d:" curr-line) |
| 1424 | (append | 1457 | (append |
| 1425 | (when prefix-face | 1458 | (when prefix-face |
| 1426 | `(font-lock-face prefix-face)) | 1459 | `(font-lock-face ,prefix-face)) |
| 1427 | `(occur-prefix t mouse-face (highlight) | 1460 | `(occur-prefix t mouse-face (highlight) |
| 1428 | ;; Allow insertion of text at | 1461 | ;; Allow insertion of text at |
| 1429 | ;; the end of the prefix (for | 1462 | ;; the end of the prefix (for |
| @@ -1447,7 +1480,9 @@ See also `multi-occur'." | |||
| 1447 | ;; of multi-line matches. | 1480 | ;; of multi-line matches. |
| 1448 | (replace-regexp-in-string | 1481 | (replace-regexp-in-string |
| 1449 | "\n" | 1482 | "\n" |
| 1450 | "\n :" | 1483 | (if prefix-face |
| 1484 | (propertize "\n :" 'font-lock-face prefix-face) | ||
| 1485 | "\n :") | ||
| 1451 | match-str) | 1486 | match-str) |
| 1452 | ;; Add marker at eol, but no mouse props. | 1487 | ;; Add marker at eol, but no mouse props. |
| 1453 | (propertize "\n" 'occur-target marker))) | 1488 | (propertize "\n" 'occur-target marker))) |
| @@ -1458,7 +1493,8 @@ See also `multi-occur'." | |||
| 1458 | ;; The complex multi-line display style. | 1493 | ;; The complex multi-line display style. |
| 1459 | (setq ret (occur-context-lines | 1494 | (setq ret (occur-context-lines |
| 1460 | out-line nlines keep-props begpt endpt | 1495 | out-line nlines keep-props begpt endpt |
| 1461 | lines prev-lines prev-after-lines)) | 1496 | curr-line prev-line prev-after-lines |
| 1497 | prefix-face)) | ||
| 1462 | ;; Set first elem of the returned list to `data', | 1498 | ;; Set first elem of the returned list to `data', |
| 1463 | ;; and the second elem to `prev-after-lines'. | 1499 | ;; and the second elem to `prev-after-lines'. |
| 1464 | (setq prev-after-lines (nth 1 ret)) | 1500 | (setq prev-after-lines (nth 1 ret)) |
| @@ -1470,28 +1506,34 @@ See also `multi-occur'." | |||
| 1470 | (if endpt | 1506 | (if endpt |
| 1471 | (progn | 1507 | (progn |
| 1472 | ;; Sum line numbers between first and last match lines. | 1508 | ;; Sum line numbers between first and last match lines. |
| 1473 | (setq lines (+ lines (count-lines begpt endpt) | 1509 | (setq curr-line (+ curr-line (count-lines begpt endpt) |
| 1474 | ;; Add 1 for empty last match line since | 1510 | ;; Add 1 for empty last match line since |
| 1475 | ;; count-lines returns 1 line less. | 1511 | ;; count-lines returns 1 line less. |
| 1476 | (if (and (bolp) (eolp)) 1 0))) | 1512 | (if (and (bolp) (eolp)) 1 0))) |
| 1477 | ;; On to the next match... | 1513 | ;; On to the next match... |
| 1478 | (forward-line 1)) | 1514 | (forward-line 1)) |
| 1479 | (goto-char (point-max))) | 1515 | (goto-char (point-max))) |
| 1480 | (setq prev-lines (1- lines))) | 1516 | (setq prev-line (1- curr-line))) |
| 1481 | ;; Flush remaining context after-lines. | 1517 | ;; Flush remaining context after-lines. |
| 1482 | (when prev-after-lines | 1518 | (when prev-after-lines |
| 1483 | (with-current-buffer out-buf | 1519 | (with-current-buffer out-buf |
| 1484 | (insert (apply #'concat (occur-engine-add-prefix | 1520 | (insert (apply #'concat (occur-engine-add-prefix |
| 1485 | prev-after-lines))))))) | 1521 | prev-after-lines prefix-face))))))) |
| 1486 | (when (not (zerop matches)) ;; is the count zero? | 1522 | (when (not (zerop lines)) ;; is the count zero? |
| 1487 | (setq globalcount (+ globalcount matches)) | 1523 | (setq global-lines (+ global-lines lines) |
| 1524 | global-matches (+ global-matches matches)) | ||
| 1488 | (with-current-buffer out-buf | 1525 | (with-current-buffer out-buf |
| 1489 | (goto-char headerpt) | 1526 | (goto-char headerpt) |
| 1490 | (let ((beg (point)) | 1527 | (let ((beg (point)) |
| 1491 | end) | 1528 | end) |
| 1492 | (insert (propertize | 1529 | (insert (propertize |
| 1493 | (format "%d match%s%s in buffer: %s\n" | 1530 | (format "%d match%s%s%s in buffer: %s\n" |
| 1494 | matches (if (= matches 1) "" "es") | 1531 | matches (if (= matches 1) "" "es") |
| 1532 | ;; Don't display the same number of lines | ||
| 1533 | ;; and matches in case of 1 match per line. | ||
| 1534 | (if (= lines matches) | ||
| 1535 | "" (format " in %d line%s" | ||
| 1536 | lines (if (= lines 1) "" "s"))) | ||
| 1495 | ;; Don't display regexp for multi-buffer. | 1537 | ;; Don't display regexp for multi-buffer. |
| 1496 | (if (> (length buffers) 1) | 1538 | (if (> (length buffers) 1) |
| 1497 | "" (format " for \"%s\"" | 1539 | "" (format " for \"%s\"" |
| @@ -1506,12 +1548,17 @@ See also `multi-occur'." | |||
| 1506 | `(occur-title ,buf)))) | 1548 | `(occur-title ,buf)))) |
| 1507 | (goto-char (point-min))))))) | 1549 | (goto-char (point-min))))))) |
| 1508 | ;; Display total match count and regexp for multi-buffer. | 1550 | ;; Display total match count and regexp for multi-buffer. |
| 1509 | (when (and (not (zerop globalcount)) (> (length buffers) 1)) | 1551 | (when (and (not (zerop global-lines)) (> (length buffers) 1)) |
| 1510 | (goto-char (point-min)) | 1552 | (goto-char (point-min)) |
| 1511 | (let ((beg (point)) | 1553 | (let ((beg (point)) |
| 1512 | end) | 1554 | end) |
| 1513 | (insert (format "%d match%s total for \"%s\":\n" | 1555 | (insert (format "%d match%s%s total for \"%s\":\n" |
| 1514 | globalcount (if (= globalcount 1) "" "es") | 1556 | global-matches (if (= global-matches 1) "" "es") |
| 1557 | ;; Don't display the same number of lines | ||
| 1558 | ;; and matches in case of 1 match per line. | ||
| 1559 | (if (= global-lines global-matches) | ||
| 1560 | "" (format " in %d line%s" | ||
| 1561 | global-lines (if (= global-lines 1) "" "s"))) | ||
| 1515 | (query-replace-descr regexp))) | 1562 | (query-replace-descr regexp))) |
| 1516 | (setq end (point)) | 1563 | (setq end (point)) |
| 1517 | (add-text-properties beg end (when title-face | 1564 | (add-text-properties beg end (when title-face |
| @@ -1523,7 +1570,7 @@ See also `multi-occur'." | |||
| 1523 | ;; buffer. | 1570 | ;; buffer. |
| 1524 | (set-buffer-file-coding-system coding)) | 1571 | (set-buffer-file-coding-system coding)) |
| 1525 | ;; Return the number of matches | 1572 | ;; Return the number of matches |
| 1526 | globalcount))) | 1573 | global-matches))) |
| 1527 | 1574 | ||
| 1528 | (defun occur-engine-line (beg end &optional keep-props) | 1575 | (defun occur-engine-line (beg end &optional keep-props) |
| 1529 | (if (and keep-props (if (boundp 'jit-lock-mode) jit-lock-mode) | 1576 | (if (and keep-props (if (boundp 'jit-lock-mode) jit-lock-mode) |
| @@ -1537,10 +1584,13 @@ See also `multi-occur'." | |||
| 1537 | str) | 1584 | str) |
| 1538 | (buffer-substring-no-properties beg end))) | 1585 | (buffer-substring-no-properties beg end))) |
| 1539 | 1586 | ||
| 1540 | (defun occur-engine-add-prefix (lines) | 1587 | (defun occur-engine-add-prefix (lines &optional prefix-face) |
| 1541 | (mapcar | 1588 | (mapcar |
| 1542 | #'(lambda (line) | 1589 | #'(lambda (line) |
| 1543 | (concat " :" line "\n")) | 1590 | (concat (if prefix-face |
| 1591 | (propertize " :" 'font-lock-face prefix-face) | ||
| 1592 | " :") | ||
| 1593 | line "\n")) | ||
| 1544 | lines)) | 1594 | lines)) |
| 1545 | 1595 | ||
| 1546 | (defun occur-accumulate-lines (count &optional keep-props pt) | 1596 | (defun occur-accumulate-lines (count &optional keep-props pt) |
| @@ -1563,13 +1613,14 @@ See also `multi-occur'." | |||
| 1563 | ;; Generate context display for occur. | 1613 | ;; Generate context display for occur. |
| 1564 | ;; OUT-LINE is the line where the match is. | 1614 | ;; OUT-LINE is the line where the match is. |
| 1565 | ;; NLINES and KEEP-PROPS are args to occur-engine. | 1615 | ;; NLINES and KEEP-PROPS are args to occur-engine. |
| 1566 | ;; LINES is line count of the current match, | 1616 | ;; CURR-LINE is line count of the current match, |
| 1567 | ;; PREV-LINES is line count of the previous match, | 1617 | ;; PREV-LINE is line count of the previous match, |
| 1568 | ;; PREV-AFTER-LINES is a list of after-context lines of the previous match. | 1618 | ;; PREV-AFTER-LINES is a list of after-context lines of the previous match. |
| 1569 | ;; Generate a list of lines, add prefixes to all but OUT-LINE, | 1619 | ;; Generate a list of lines, add prefixes to all but OUT-LINE, |
| 1570 | ;; then concatenate them all together. | 1620 | ;; then concatenate them all together. |
| 1571 | (defun occur-context-lines (out-line nlines keep-props begpt endpt | 1621 | (defun occur-context-lines (out-line nlines keep-props begpt endpt |
| 1572 | lines prev-lines prev-after-lines) | 1622 | curr-line prev-line prev-after-lines |
| 1623 | &optional prefix-face) | ||
| 1573 | ;; Find after- and before-context lines of the current match. | 1624 | ;; Find after- and before-context lines of the current match. |
| 1574 | (let ((before-lines | 1625 | (let ((before-lines |
| 1575 | (nreverse (cdr (occur-accumulate-lines | 1626 | (nreverse (cdr (occur-accumulate-lines |
| @@ -1584,22 +1635,22 @@ See also `multi-occur'." | |||
| 1584 | 1635 | ||
| 1585 | (when prev-after-lines | 1636 | (when prev-after-lines |
| 1586 | ;; Don't overlap prev after-lines with current before-lines. | 1637 | ;; Don't overlap prev after-lines with current before-lines. |
| 1587 | (if (>= (+ prev-lines (length prev-after-lines)) | 1638 | (if (>= (+ prev-line (length prev-after-lines)) |
| 1588 | (- lines (length before-lines))) | 1639 | (- curr-line (length before-lines))) |
| 1589 | (setq prev-after-lines | 1640 | (setq prev-after-lines |
| 1590 | (butlast prev-after-lines | 1641 | (butlast prev-after-lines |
| 1591 | (- (length prev-after-lines) | 1642 | (- (length prev-after-lines) |
| 1592 | (- lines prev-lines (length before-lines) 1)))) | 1643 | (- curr-line prev-line (length before-lines) 1)))) |
| 1593 | ;; Separate non-overlapping context lines with a dashed line. | 1644 | ;; Separate non-overlapping context lines with a dashed line. |
| 1594 | (setq separator "-------\n"))) | 1645 | (setq separator "-------\n"))) |
| 1595 | 1646 | ||
| 1596 | (when prev-lines | 1647 | (when prev-line |
| 1597 | ;; Don't overlap current before-lines with previous match line. | 1648 | ;; Don't overlap current before-lines with previous match line. |
| 1598 | (if (<= (- lines (length before-lines)) | 1649 | (if (<= (- curr-line (length before-lines)) |
| 1599 | prev-lines) | 1650 | prev-line) |
| 1600 | (setq before-lines | 1651 | (setq before-lines |
| 1601 | (nthcdr (- (length before-lines) | 1652 | (nthcdr (- (length before-lines) |
| 1602 | (- lines prev-lines 1)) | 1653 | (- curr-line prev-line 1)) |
| 1603 | before-lines)) | 1654 | before-lines)) |
| 1604 | ;; Separate non-overlapping before-context lines. | 1655 | ;; Separate non-overlapping before-context lines. |
| 1605 | (unless (> nlines 0) | 1656 | (unless (> nlines 0) |
| @@ -1609,10 +1660,13 @@ See also `multi-occur'." | |||
| 1609 | ;; Return a list where the first element is the output line. | 1660 | ;; Return a list where the first element is the output line. |
| 1610 | (apply #'concat | 1661 | (apply #'concat |
| 1611 | (append | 1662 | (append |
| 1612 | (and prev-after-lines | 1663 | (if prev-after-lines |
| 1613 | (occur-engine-add-prefix prev-after-lines)) | 1664 | (occur-engine-add-prefix prev-after-lines prefix-face)) |
| 1614 | (and separator (list separator)) | 1665 | (if separator |
| 1615 | (occur-engine-add-prefix before-lines) | 1666 | (list (if prefix-face |
| 1667 | (propertize separator 'font-lock-face prefix-face) | ||
| 1668 | separator))) | ||
| 1669 | (occur-engine-add-prefix before-lines prefix-face) | ||
| 1616 | (list out-line))) | 1670 | (list out-line))) |
| 1617 | ;; And the second element is the list of context after-lines. | 1671 | ;; And the second element is the list of context after-lines. |
| 1618 | (if (> nlines 0) after-lines)))) | 1672 | (if (> nlines 0) after-lines)))) |
| @@ -1818,6 +1872,68 @@ It is used by `query-replace-regexp', `replace-regexp', | |||
| 1818 | It is called with three arguments, as if it were | 1872 | It is called with three arguments, as if it were |
| 1819 | `re-search-forward'.") | 1873 | `re-search-forward'.") |
| 1820 | 1874 | ||
| 1875 | (defun replace-search (search-string limit regexp-flag delimited-flag | ||
| 1876 | case-fold-search) | ||
| 1877 | "Search for the next occurence of SEARCH-STRING to replace." | ||
| 1878 | ;; Let-bind global isearch-* variables to values used | ||
| 1879 | ;; to search the next replacement. These let-bindings | ||
| 1880 | ;; should be effective both at the time of calling | ||
| 1881 | ;; `isearch-search-fun-default' and also at the | ||
| 1882 | ;; time of funcalling `search-function'. | ||
| 1883 | ;; These isearch-* bindings can't be placed higher | ||
| 1884 | ;; outside of this function because then another I-search | ||
| 1885 | ;; used after `recursive-edit' might override them. | ||
| 1886 | (let* ((isearch-regexp regexp-flag) | ||
| 1887 | (isearch-word delimited-flag) | ||
| 1888 | (isearch-lax-whitespace | ||
| 1889 | replace-lax-whitespace) | ||
| 1890 | (isearch-regexp-lax-whitespace | ||
| 1891 | replace-regexp-lax-whitespace) | ||
| 1892 | (isearch-case-fold-search case-fold-search) | ||
| 1893 | (isearch-adjusted nil) | ||
| 1894 | (isearch-nonincremental t) ; don't use lax word mode | ||
| 1895 | (isearch-forward t) | ||
| 1896 | (search-function | ||
| 1897 | (or (if regexp-flag | ||
| 1898 | replace-re-search-function | ||
| 1899 | replace-search-function) | ||
| 1900 | (isearch-search-fun-default)))) | ||
| 1901 | (funcall search-function search-string limit t))) | ||
| 1902 | |||
| 1903 | (defvar replace-overlay nil) | ||
| 1904 | |||
| 1905 | (defun replace-highlight (match-beg match-end range-beg range-end | ||
| 1906 | search-string regexp-flag delimited-flag | ||
| 1907 | case-fold-search) | ||
| 1908 | (if query-replace-highlight | ||
| 1909 | (if replace-overlay | ||
| 1910 | (move-overlay replace-overlay match-beg match-end (current-buffer)) | ||
| 1911 | (setq replace-overlay (make-overlay match-beg match-end)) | ||
| 1912 | (overlay-put replace-overlay 'priority 1001) ;higher than lazy overlays | ||
| 1913 | (overlay-put replace-overlay 'face 'query-replace))) | ||
| 1914 | (if query-replace-lazy-highlight | ||
| 1915 | (let ((isearch-string search-string) | ||
| 1916 | (isearch-regexp regexp-flag) | ||
| 1917 | (isearch-word delimited-flag) | ||
| 1918 | (isearch-lax-whitespace | ||
| 1919 | replace-lax-whitespace) | ||
| 1920 | (isearch-regexp-lax-whitespace | ||
| 1921 | replace-regexp-lax-whitespace) | ||
| 1922 | (isearch-case-fold-search case-fold-search) | ||
| 1923 | (isearch-forward t) | ||
| 1924 | (isearch-other-end match-beg) | ||
| 1925 | (isearch-error nil)) | ||
| 1926 | (isearch-lazy-highlight-new-loop range-beg range-end)))) | ||
| 1927 | |||
| 1928 | (defun replace-dehighlight () | ||
| 1929 | (when replace-overlay | ||
| 1930 | (delete-overlay replace-overlay)) | ||
| 1931 | (when query-replace-lazy-highlight | ||
| 1932 | (lazy-highlight-cleanup lazy-highlight-cleanup) | ||
| 1933 | (setq isearch-lazy-highlight-last-string nil)) | ||
| 1934 | ;; Close overlays opened by `isearch-range-invisible' in `perform-replace'. | ||
| 1935 | (isearch-clean-overlays)) | ||
| 1936 | |||
| 1821 | (defun perform-replace (from-string replacements | 1937 | (defun perform-replace (from-string replacements |
| 1822 | query-flag regexp-flag delimited-flag | 1938 | query-flag regexp-flag delimited-flag |
| 1823 | &optional repeat-count map start end) | 1939 | &optional repeat-count map start end) |
| @@ -1852,6 +1968,9 @@ make, or the user didn't cancel the call." | |||
| 1852 | (keep-going t) | 1968 | (keep-going t) |
| 1853 | (stack nil) | 1969 | (stack nil) |
| 1854 | (replace-count 0) | 1970 | (replace-count 0) |
| 1971 | (skip-read-only-count 0) | ||
| 1972 | (skip-filtered-count 0) | ||
| 1973 | (skip-invisible-count 0) | ||
| 1855 | (nonempty-match nil) | 1974 | (nonempty-match nil) |
| 1856 | (multi-buffer nil) | 1975 | (multi-buffer nil) |
| 1857 | (recenter-last-op nil) ; Start cycling order with initial position. | 1976 | (recenter-last-op nil) ; Start cycling order with initial position. |
| @@ -1905,62 +2024,40 @@ make, or the user didn't cancel the call." | |||
| 1905 | ;; Loop finding occurrences that perhaps should be replaced. | 2024 | ;; Loop finding occurrences that perhaps should be replaced. |
| 1906 | (while (and keep-going | 2025 | (while (and keep-going |
| 1907 | (not (or (eobp) (and limit (>= (point) limit)))) | 2026 | (not (or (eobp) (and limit (>= (point) limit)))) |
| 1908 | ;; Let-bind global isearch-* variables to values used | 2027 | ;; Use the next match if it is already known; |
| 1909 | ;; to search the next replacement. These let-bindings | 2028 | ;; otherwise, search for a match after moving forward |
| 1910 | ;; should be effective both at the time of calling | 2029 | ;; one char if progress is required. |
| 1911 | ;; `isearch-search-fun-default' and also at the | 2030 | (setq real-match-data |
| 1912 | ;; time of funcalling `search-function'. | 2031 | (cond ((consp match-again) |
| 1913 | ;; These isearch-* bindings can't be placed higher | 2032 | (goto-char (nth 1 match-again)) |
| 1914 | ;; outside of this loop because then another I-search | 2033 | (replace-match-data |
| 1915 | ;; used after `recursive-edit' might override them. | 2034 | t real-match-data match-again)) |
| 1916 | (let* ((isearch-regexp regexp-flag) | 2035 | ;; MATCH-AGAIN non-nil means accept an |
| 1917 | (isearch-word delimited-flag) | 2036 | ;; adjacent match. |
| 1918 | (isearch-lax-whitespace | 2037 | (match-again |
| 1919 | replace-lax-whitespace) | 2038 | (and |
| 1920 | (isearch-regexp-lax-whitespace | 2039 | (replace-search search-string limit |
| 1921 | replace-regexp-lax-whitespace) | 2040 | regexp-flag delimited-flag |
| 1922 | (isearch-case-fold-search case-fold-search) | 2041 | case-fold-search) |
| 1923 | (isearch-adjusted nil) | 2042 | ;; For speed, use only integers and |
| 1924 | (isearch-nonincremental t) ; don't use lax word mode | 2043 | ;; reuse the list used last time. |
| 1925 | (isearch-forward t) | 2044 | (replace-match-data t real-match-data))) |
| 1926 | (search-function | 2045 | ((and (< (1+ (point)) (point-max)) |
| 1927 | (or (if regexp-flag | 2046 | (or (null limit) |
| 1928 | replace-re-search-function | 2047 | (< (1+ (point)) limit))) |
| 1929 | replace-search-function) | 2048 | ;; If not accepting adjacent matches, |
| 1930 | (isearch-search-fun-default)))) | 2049 | ;; move one char to the right before |
| 1931 | ;; Use the next match if it is already known; | 2050 | ;; searching again. Undo the motion |
| 1932 | ;; otherwise, search for a match after moving forward | 2051 | ;; if the search fails. |
| 1933 | ;; one char if progress is required. | 2052 | (let ((opoint (point))) |
| 1934 | (setq real-match-data | 2053 | (forward-char 1) |
| 1935 | (cond ((consp match-again) | 2054 | (if (replace-search search-string limit |
| 1936 | (goto-char (nth 1 match-again)) | 2055 | regexp-flag delimited-flag |
| 1937 | (replace-match-data | 2056 | case-fold-search) |
| 1938 | t real-match-data match-again)) | 2057 | (replace-match-data |
| 1939 | ;; MATCH-AGAIN non-nil means accept an | 2058 | t real-match-data) |
| 1940 | ;; adjacent match. | 2059 | (goto-char opoint) |
| 1941 | (match-again | 2060 | nil)))))) |
| 1942 | (and | ||
| 1943 | (funcall search-function search-string | ||
| 1944 | limit t) | ||
| 1945 | ;; For speed, use only integers and | ||
| 1946 | ;; reuse the list used last time. | ||
| 1947 | (replace-match-data t real-match-data))) | ||
| 1948 | ((and (< (1+ (point)) (point-max)) | ||
| 1949 | (or (null limit) | ||
| 1950 | (< (1+ (point)) limit))) | ||
| 1951 | ;; If not accepting adjacent matches, | ||
| 1952 | ;; move one char to the right before | ||
| 1953 | ;; searching again. Undo the motion | ||
| 1954 | ;; if the search fails. | ||
| 1955 | (let ((opoint (point))) | ||
| 1956 | (forward-char 1) | ||
| 1957 | (if (funcall | ||
| 1958 | search-function search-string | ||
| 1959 | limit t) | ||
| 1960 | (replace-match-data | ||
| 1961 | t real-match-data) | ||
| 1962 | (goto-char opoint) | ||
| 1963 | nil))))))) | ||
| 1964 | 2061 | ||
| 1965 | ;; Record whether the match is nonempty, to avoid an infinite loop | 2062 | ;; Record whether the match is nonempty, to avoid an infinite loop |
| 1966 | ;; repeatedly matching the same empty string. | 2063 | ;; repeatedly matching the same empty string. |
| @@ -1982,12 +2079,27 @@ make, or the user didn't cancel the call." | |||
| 1982 | (and (/= (nth 0 match) (nth 1 match)) | 2079 | (and (/= (nth 0 match) (nth 1 match)) |
| 1983 | match)))))) | 2080 | match)))))) |
| 1984 | 2081 | ||
| 1985 | ;; Optionally ignore matches that have a read-only property. | 2082 | (cond |
| 1986 | (unless (and query-replace-skip-read-only | 2083 | ;; Optionally ignore matches that have a read-only property. |
| 1987 | (text-property-not-all | 2084 | ((not (or (not query-replace-skip-read-only) |
| 1988 | (nth 0 real-match-data) (nth 1 real-match-data) | 2085 | (not (text-property-not-all |
| 1989 | 'read-only nil)) | 2086 | (nth 0 real-match-data) (nth 1 real-match-data) |
| 1990 | 2087 | 'read-only nil)))) | |
| 2088 | (setq skip-read-only-count (1+ skip-read-only-count))) | ||
| 2089 | ;; Optionally filter out matches. | ||
| 2090 | ((not (run-hook-with-args-until-failure | ||
| 2091 | 'isearch-filter-predicates | ||
| 2092 | (nth 0 real-match-data) (nth 1 real-match-data))) | ||
| 2093 | (setq skip-filtered-count (1+ skip-filtered-count))) | ||
| 2094 | ;; Optionally ignore invisible matches. | ||
| 2095 | ((not (or (eq search-invisible t) | ||
| 2096 | ;; Don't open overlays for automatic replacements. | ||
| 2097 | (and (not query-flag) search-invisible) | ||
| 2098 | ;; Open hidden overlays for interactive replacements. | ||
| 2099 | (not (isearch-range-invisible | ||
| 2100 | (nth 0 real-match-data) (nth 1 real-match-data))))) | ||
| 2101 | (setq skip-invisible-count (1+ skip-invisible-count))) | ||
| 2102 | (t | ||
| 1991 | ;; Calculate the replacement string, if necessary. | 2103 | ;; Calculate the replacement string, if necessary. |
| 1992 | (when replacements | 2104 | (when replacements |
| 1993 | (set-match-data real-match-data) | 2105 | (set-match-data real-match-data) |
| @@ -2192,45 +2304,31 @@ make, or the user didn't cancel the call." | |||
| 2192 | (match-end 0) | 2304 | (match-end 0) |
| 2193 | (current-buffer)) | 2305 | (current-buffer)) |
| 2194 | (match-data t))) | 2306 | (match-data t))) |
| 2195 | stack))))) | 2307 | stack)))))) |
| 2196 | 2308 | ||
| 2197 | (replace-dehighlight)) | 2309 | (replace-dehighlight)) |
| 2198 | (or unread-command-events | 2310 | (or unread-command-events |
| 2199 | (message "Replaced %d occurrence%s" | 2311 | (message "Replaced %d occurrence%s%s" |
| 2200 | replace-count | 2312 | replace-count |
| 2201 | (if (= replace-count 1) "" "s"))) | 2313 | (if (= replace-count 1) "" "s") |
| 2314 | (if (> (+ skip-read-only-count | ||
| 2315 | skip-filtered-count | ||
| 2316 | skip-invisible-count) 0) | ||
| 2317 | (format " (skipped %s)" | ||
| 2318 | (mapconcat | ||
| 2319 | 'identity | ||
| 2320 | (delq nil (list | ||
| 2321 | (if (> skip-read-only-count 0) | ||
| 2322 | (format "%s read-only" | ||
| 2323 | skip-read-only-count)) | ||
| 2324 | (if (> skip-invisible-count 0) | ||
| 2325 | (format "%s invisible" | ||
| 2326 | skip-invisible-count)) | ||
| 2327 | (if (> skip-filtered-count 0) | ||
| 2328 | (format "%s filtered out" | ||
| 2329 | skip-filtered-count)))) | ||
| 2330 | ", ")) | ||
| 2331 | ""))) | ||
| 2202 | (or (and keep-going stack) multi-buffer))) | 2332 | (or (and keep-going stack) multi-buffer))) |
| 2203 | 2333 | ||
| 2204 | (defvar replace-overlay nil) | ||
| 2205 | |||
| 2206 | (defun replace-highlight (match-beg match-end range-beg range-end | ||
| 2207 | search-string regexp-flag delimited-flag | ||
| 2208 | case-fold-search) | ||
| 2209 | (if query-replace-highlight | ||
| 2210 | (if replace-overlay | ||
| 2211 | (move-overlay replace-overlay match-beg match-end (current-buffer)) | ||
| 2212 | (setq replace-overlay (make-overlay match-beg match-end)) | ||
| 2213 | (overlay-put replace-overlay 'priority 1001) ;higher than lazy overlays | ||
| 2214 | (overlay-put replace-overlay 'face 'query-replace))) | ||
| 2215 | (if query-replace-lazy-highlight | ||
| 2216 | (let ((isearch-string search-string) | ||
| 2217 | (isearch-regexp regexp-flag) | ||
| 2218 | (isearch-word delimited-flag) | ||
| 2219 | (isearch-lax-whitespace | ||
| 2220 | replace-lax-whitespace) | ||
| 2221 | (isearch-regexp-lax-whitespace | ||
| 2222 | replace-regexp-lax-whitespace) | ||
| 2223 | (isearch-case-fold-search case-fold-search) | ||
| 2224 | (isearch-forward t) | ||
| 2225 | (isearch-other-end match-beg) | ||
| 2226 | (isearch-error nil)) | ||
| 2227 | (isearch-lazy-highlight-new-loop range-beg range-end)))) | ||
| 2228 | |||
| 2229 | (defun replace-dehighlight () | ||
| 2230 | (when replace-overlay | ||
| 2231 | (delete-overlay replace-overlay)) | ||
| 2232 | (when query-replace-lazy-highlight | ||
| 2233 | (lazy-highlight-cleanup lazy-highlight-cleanup) | ||
| 2234 | (setq isearch-lazy-highlight-last-string nil))) | ||
| 2235 | |||
| 2236 | ;;; replace.el ends here | 2334 | ;;; replace.el ends here |