X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/fd71e94970ea84d3e4ed8fc5756373e57c1d9378..2238127283d703f38765f9b3f6a64f799d18e9e5:/lisp/isearch.el diff --git a/lisp/isearch.el b/lisp/isearch.el index 7071497cbf..1942641fae 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -1,12 +1,11 @@ ;;; isearch.el --- incremental search minor mode -;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2001, -;; 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 -;; Free Software Foundation, Inc. +;; Copyright (C) 1992-1997, 1999-2011 Free Software Foundation, Inc. ;; Author: Daniel LaLiberte ;; Maintainer: FSF ;; Keywords: matching +;; Package: emacs ;; This file is part of GNU Emacs. @@ -156,6 +155,9 @@ command history." (defvar isearch-mode-hook nil "Function(s) to call after starting up an incremental search.") +(defvar isearch-update-post-hook nil + "Function(s) to call after isearch has found matches in the buffer.") + (defvar isearch-mode-end-hook nil "Function(s) to call after terminating an incremental search. When these functions are called, `isearch-mode-end-hook-quit' @@ -235,7 +237,7 @@ Default value, nil, means edit the string instead." "Face for highlighting Isearch matches." :group 'isearch :group 'basic-faces) -(defvar isearch 'isearch) +(defvar isearch-face 'isearch) (defface isearch-fail '((((class color) (min-colors 88) (background light)) @@ -271,30 +273,37 @@ and `lazy-highlight-interval')." :group 'isearch :group 'matching) +(define-obsolete-variable-alias 'isearch-lazy-highlight-cleanup + 'lazy-highlight-cleanup + "22.1") + (defcustom lazy-highlight-cleanup t "Controls whether to remove extra highlighting after a search. If this is nil, extra highlighting can be \"manually\" removed with \\[lazy-highlight-cleanup]." :type 'boolean :group 'lazy-highlight) -(define-obsolete-variable-alias 'isearch-lazy-highlight-cleanup - 'lazy-highlight-cleanup + +(define-obsolete-variable-alias 'isearch-lazy-highlight-initial-delay + 'lazy-highlight-initial-delay "22.1") (defcustom lazy-highlight-initial-delay 0.25 "Seconds to wait before beginning to lazily highlight all matches." :type 'number :group 'lazy-highlight) -(define-obsolete-variable-alias 'isearch-lazy-highlight-initial-delay - 'lazy-highlight-initial-delay + +(define-obsolete-variable-alias 'isearch-lazy-highlight-interval + 'lazy-highlight-interval "22.1") (defcustom lazy-highlight-interval 0 ; 0.0625 "Seconds between lazily highlighting successive matches." :type 'number :group 'lazy-highlight) -(define-obsolete-variable-alias 'isearch-lazy-highlight-interval - 'lazy-highlight-interval + +(define-obsolete-variable-alias 'isearch-lazy-highlight-max-at-a-time + 'lazy-highlight-max-at-a-time "22.1") (defcustom lazy-highlight-max-at-a-time 20 @@ -305,9 +314,6 @@ A value of nil means highlight all matches." :type '(choice (const :tag "All" nil) (integer :tag "Some")) :group 'lazy-highlight) -(define-obsolete-variable-alias 'isearch-lazy-highlight-max-at-a-time - 'lazy-highlight-max-at-a-time - "22.1") (defface lazy-highlight '((((class color) (min-colors 88) (background light)) @@ -323,10 +329,10 @@ A value of nil means highlight all matches." :group 'lazy-highlight :group 'basic-faces) (define-obsolete-face-alias 'isearch-lazy-highlight-face 'lazy-highlight "22.1") -(defvar lazy-highlight-face 'lazy-highlight) (define-obsolete-variable-alias 'isearch-lazy-highlight-face 'lazy-highlight-face "22.1") +(defvar lazy-highlight-face 'lazy-highlight) ;; Define isearch help map. @@ -458,13 +464,16 @@ This is like `describe-bindings', but displays only Isearch keys." (define-key map "\C-w" 'isearch-yank-word-or-char) (define-key map "\M-\C-w" 'isearch-del-char) (define-key map "\M-\C-y" 'isearch-yank-char) - (define-key map "\C-y" 'isearch-yank-line) + (define-key map "\C-y" 'isearch-yank-kill) + (define-key map "\M-s\C-e" 'isearch-yank-line) - (define-key map "\C-h" isearch-help-map) + (define-key map (char-to-string help-char) isearch-help-map) + (define-key map [help] isearch-help-map) + (define-key map [f1] isearch-help-map) (define-key map "\M-n" 'isearch-ring-advance) (define-key map "\M-p" 'isearch-ring-retreat) - (define-key map "\M-y" 'isearch-yank-kill) + (define-key map "\M-y" 'isearch-yank-pop) (define-key map "\M-\t" 'isearch-complete) @@ -540,7 +549,8 @@ Each set is a vector of the form: (defvar isearch-error nil) ; Error message for failed search. (defvar isearch-other-end nil) ; Start (end) of match if forward (backward). (defvar isearch-wrapped nil) ; Searching restarted from the top (bottom). -(defvar isearch-barrier 0) +(defvar isearch-barrier 0 + "Recorded minimum/maximal point for the current search.") (defvar isearch-just-started nil) (defvar isearch-start-hscroll 0) ; hscroll when starting the search. @@ -628,6 +638,8 @@ Type \\[isearch-yank-char] to yank char from buffer onto end of search\ Type \\[isearch-yank-line] to yank rest of line onto end of search string\ and search for it. Type \\[isearch-yank-kill] to yank the last string of killed text. +Type \\[isearch-yank-pop] to replace string just yanked into search prompt + with string killed before it. Type \\[isearch-quote-char] to quote control character to search for it. \\[isearch-abort] while searching or when search has failed cancels input\ back to what has @@ -868,7 +880,8 @@ It is called by the function `isearch-forward' and other related functions." (isearch-lazy-highlight-new-loop)) ;; We must prevent the point moving to the end of composition when a ;; part of the composition has just been searched. - (setq disable-point-adjustment t)) + (setq disable-point-adjustment t) + (run-hooks 'isearch-update-post-hook)) (defun isearch-done (&optional nopush edit) "Exit Isearch mode. @@ -1048,6 +1061,23 @@ nonincremental search instead via `isearch-edit-string'." (isearch-done) (isearch-clean-overlays)) +(defvar minibuffer-history-symbol) ;; from external package gmhist.el + +(defun isearch-fail-pos () + "Position of first mismatch in search string, or its length if none." + (let ((cmds isearch-cmds)) + (if (and isearch-success (not isearch-error)) + (length isearch-message) + (while (or (not (isearch-success-state (car cmds))) + (isearch-error-state (car cmds))) + (pop cmds)) + (let ((succ-msg (and cmds (isearch-message-state (car cmds))))) + (if (and (stringp succ-msg) + (< (length succ-msg) (length isearch-message)) + (equal succ-msg + (substring isearch-message 0 (length succ-msg)))) + (length succ-msg) + 0))))) (defun isearch-edit-string () "Edit the search string in the minibuffer. @@ -1067,7 +1097,7 @@ If first char entered is \\[isearch-yank-word-or-char], then do word search inst ;; this could be simplified greatly. ;; Editing doesn't back up the search point. Should it? (interactive) - (condition-case err + (condition-case nil (progn (let ((isearch-nonincremental isearch-nonincremental) @@ -1112,7 +1142,7 @@ If first char entered is \\[isearch-yank-word-or-char], then do word search inst ;; Actually terminate isearching until editing is done. ;; This is so that the user can do anything without failure, ;; like switch buffers and start another isearch, and return. - (condition-case err + (condition-case nil (isearch-done t t) (exit nil)) ; was recursive editing @@ -1128,7 +1158,7 @@ If first char entered is \\[isearch-yank-word-or-char], then do word search inst (setq isearch-new-string (read-from-minibuffer (isearch-message-prefix nil nil isearch-nonincremental) - isearch-string + (cons isearch-string (1+ (isearch-fail-pos))) minibuffer-local-isearch-map nil (if isearch-regexp (cons 'regexp-search-ring @@ -1233,9 +1263,9 @@ Use `isearch-exit' to quit without signaling." (interactive) ;; (ding) signal instead below, if quitting (discard-input) - (if isearch-success - ;; If search is successful, move back to starting point - ;; and really do quit. + (if (and isearch-success (not isearch-error)) + ;; If search is successful and has no incomplete regexp, + ;; move back to starting point and really do quit. (progn (setq isearch-success nil) (isearch-cancel)) @@ -1476,20 +1506,28 @@ If search string is empty, just beep." (eq 'not-yanks search-upper-case)) (setq string (downcase string))) (if isearch-regexp (setq string (regexp-quote string))) - (setq isearch-string (concat isearch-string string) - isearch-message - (concat isearch-message - (mapconcat 'isearch-text-char-description - string "")) - ;; Don't move cursor in reverse search. - isearch-yank-flag t) - (isearch-search-and-update)) + ;; Don't move cursor in reverse search. + (setq isearch-yank-flag t) + (isearch-process-search-string + string (mapconcat 'isearch-text-char-description string ""))) (defun isearch-yank-kill () "Pull string from kill ring into search string." (interactive) (isearch-yank-string (current-kill 0))) +(defun isearch-yank-pop () + "Replace just-yanked search string with previously killed string." + (interactive) + (if (not (memq last-command '(isearch-yank-kill isearch-yank-pop))) + ;; Fall back on `isearch-yank-kill' for the benefits of people + ;; who are used to the old behavior of `M-y' in isearch mode. In + ;; future, this fallback may be changed if we ever change + ;; `yank-pop' to do something like the kill-ring-browser. + (isearch-yank-kill) + (isearch-pop-state) + (isearch-yank-string (current-kill 1)))) + (defun isearch-yank-x-selection () "Pull current X selection into search string." (interactive) @@ -1538,14 +1576,18 @@ or it might return the position of the end of the line." (interactive "p") (isearch-yank-internal (lambda () (forward-char arg) (point)))) +(declare-function subword-forward "subword" (&optional arg)) (defun isearch-yank-word-or-char () - "Pull next character or word from buffer into search string." + "Pull next character, subword or word from buffer into search string. +Subword is used when `subword-mode' is activated. " (interactive) (isearch-yank-internal (lambda () (if (or (= (char-syntax (or (char-after) 0)) ?w) (= (char-syntax (or (char-after (1+ (point))) 0)) ?w)) - (forward-word 1) + (if (and (boundp 'subword-mode) subword-mode) + (subword-forward 1) + (forward-word 1)) (forward-char 1)) (point)))) (defun isearch-yank-word () @@ -1708,9 +1750,10 @@ Scroll-bar or mode-line events are processed appropriately." ;; attempts this, we scroll the text back again. ;; ;; We implement this feature with a property called `isearch-scroll'. -;; If a command's symbol has the value t for this property it is a -;; scrolling command. The feature needs to be enabled by setting the -;; customizable variable `isearch-allow-scroll' to a non-nil value. +;; If a command's symbol has the value t for this property or for the +;; `scroll-command' property, it is a scrolling command. The feature +;; needs to be enabled by setting the customizable variable +;; `isearch-allow-scroll' to a non-nil value. ;; ;; The universal argument commands (e.g. C-u) in simple.el are marked ;; as scrolling commands, and isearch.el has been amended to allow @@ -1727,12 +1770,11 @@ Scroll-bar or mode-line events are processed appropriately." (if (fboundp 'w32-handle-scroll-bar-event) (put 'w32-handle-scroll-bar-event 'isearch-scroll t)) -;; Commands which scroll the window: +;; Commands which scroll the window (some scroll commands +;; already have the `scroll-command' property on them): (put 'recenter 'isearch-scroll t) (put 'recenter-top-bottom 'isearch-scroll t) (put 'reposition-window 'isearch-scroll t) -(put 'scroll-up 'isearch-scroll t) -(put 'scroll-down 'isearch-scroll t) ;; Commands which act on the other window (put 'list-buffers 'isearch-scroll t) @@ -1757,7 +1799,7 @@ Scroll-bar or mode-line events are processed appropriately." "Whether scrolling is allowed during incremental search. If non-nil, scrolling commands can be used in Isearch mode. However, the current match will never scroll offscreen. -If nil, scolling commands will first cancel Isearch mode." +If nil, scrolling commands will first cancel Isearch mode." :type 'boolean :group 'isearch) @@ -1821,7 +1863,8 @@ Otherwise return nil." (let* ((overriding-terminal-local-map nil) (binding (key-binding key-seq))) (and binding (symbolp binding) (commandp binding) - (eq (get binding 'isearch-scroll) t) + (or (eq (get binding 'isearch-scroll) t) + (eq (get binding 'scroll-command) t)) binding))) (defalias 'isearch-other-control-char 'isearch-other-meta-char) @@ -1982,12 +2025,6 @@ Isearch mode." (setq char (unibyte-char-to-multibyte char))) (isearch-process-search-char char)))) -(defun isearch-return-char () - "Convert return into newline for incremental search." - (interactive) - (isearch-process-search-char ?\n)) -(make-obsolete 'isearch-return-char 'isearch-printing-char "19.7") - (defun isearch-printing-char () "Add this ordinary printing character to the search string and search." (interactive) @@ -2146,7 +2183,7 @@ If there is no completion possible, say so and continue searching." (isearch-message-suffix c-q-hack ellipsis))) (if c-q-hack m (let ((message-log-max nil)) (message "%s" m))))) -(defun isearch-message-prefix (&optional c-q-hack ellipsis nonincremental) +(defun isearch-message-prefix (&optional _c-q-hack ellipsis nonincremental) ;; If about to search, and previous search regexp was invalid, ;; check that it still is. If it is valid now, ;; let the message we display while searching say that it is valid. @@ -2179,7 +2216,7 @@ If there is no completion possible, say so and continue searching." (propertize (concat (upcase (substring m 0 1)) (substring m 1)) 'face 'minibuffer-prompt))) -(defun isearch-message-suffix (&optional c-q-hack ellipsis) +(defun isearch-message-suffix (&optional c-q-hack _ellipsis) (concat (if c-q-hack "^Q" "") (if isearch-error (concat " [" isearch-error "]") @@ -2190,10 +2227,13 @@ If there is no completion possible, say so and continue searching." ;; Searching (defvar isearch-search-fun-function nil - "Override `isearch-search-fun'. -This function should return the search function for Isearch to use. -It will call this function with three arguments -as if it were `search-forward'.") + "Overrides the default `isearch-search-fun' behaviour. +This variable's value should be a function, which will be called +with no arguments, and should return a function that takes three +arguments: STRING, BOUND, and NOERROR. + +This returned function will be used by `isearch-search-string' to +search for the first occurrence of STRING or its translation.") (defun isearch-search-fun () "Return the function to use for the search. @@ -2414,14 +2454,8 @@ update the match data, and return point." ;; If the following character is currently invisible, ;; skip all characters with that same `invisible' property value. ;; Do that over and over. - (while (and (< (point) end) - (let ((prop - (get-char-property (point) 'invisible))) - (if (eq buffer-invisibility-spec t) - prop - (or (memq prop buffer-invisibility-spec) - (assq prop buffer-invisibility-spec))))) - (if (get-text-property (point) 'invisible) + (while (and (< (point) end) (invisible-p (point))) + (if (invisible-p (get-text-property (point) 'invisible)) (progn (goto-char (next-single-property-change (point) 'invisible nil end)) @@ -2436,10 +2470,7 @@ update the match data, and return point." (while overlays (setq o (car overlays) invis-prop (overlay-get o 'invisible)) - (if (if (eq buffer-invisibility-spec t) - invis-prop - (or (memq invis-prop buffer-invisibility-spec) - (assq invis-prop buffer-invisibility-spec))) + (if (invisible-p invis-prop) (if (overlay-get o 'isearch-open-invisible) (setq ov-list (cons o ov-list)) ;; We found one overlay that cannot be @@ -2529,7 +2560,7 @@ since they have special meaning in a regexp." (setq isearch-overlay (make-overlay beg end)) ;; 1001 is higher than lazy's 1000 and ediff's 100+ (overlay-put isearch-overlay 'priority 1001) - (overlay-put isearch-overlay 'face isearch)))) + (overlay-put isearch-overlay 'face isearch-face)))) (defun isearch-dehighlight () (when isearch-overlay @@ -2575,6 +2606,7 @@ since they have special meaning in a regexp." (defvar isearch-lazy-highlight-regexp nil) (defvar isearch-lazy-highlight-space-regexp nil) (defvar isearch-lazy-highlight-forward nil) +(defvar isearch-lazy-highlight-error nil) (defun lazy-highlight-cleanup (&optional force) "Stop lazy highlighting and remove extra highlighting from current buffer. @@ -2616,9 +2648,13 @@ by other Emacs features." (not (= (window-end) ; Window may have been split/joined. isearch-lazy-highlight-window-end)) (not (eq isearch-forward - isearch-lazy-highlight-forward)))) + isearch-lazy-highlight-forward)) + ;; In case we are recovering from an error. + (not (equal isearch-error + isearch-lazy-highlight-error)))) ;; something important did indeed change (lazy-highlight-cleanup t) ;kill old loop & remove overlays + (setq isearch-lazy-highlight-error isearch-error) (when (not isearch-error) (setq isearch-lazy-highlight-start-limit beg isearch-lazy-highlight-end-limit end) @@ -2665,6 +2701,8 @@ Attempt to do the search exactly the way the pending Isearch would." ;; Clear RETRY unless the search predicate says ;; to skip this search hit. (if (or (not success) + (= (point) bound) ; like (bobp) (eobp) in `isearch-search'. + (= (match-beginning 0) (match-end 0)) (funcall isearch-filter-predicate (match-beginning 0) (match-end 0))) (setq retry nil))) @@ -2754,5 +2792,4 @@ CASE-FOLD non-nil means the search was case-insensitive." (isearch-search) (isearch-update)) -;; arch-tag: 74850515-f7d8-43a6-8a2c-ca90a4c1e675 ;;; isearch.el ends here