:type 'boolean
:group 'isearch)
+(defcustom isearch-resume-enabled t
+ "*If non-nil, `isearch-resume' commands are added to the command history."
+ :type 'boolean
+ :group 'isearch)
+
(defvar isearch-mode-hook nil
"Function(s) to call after starting up an incremental search.")
(define-key map " " 'isearch-whitespace-chars)
(define-key map [?\S-\ ] 'isearch-whitespace-chars)
- (define-key map "\C-w" 'isearch-yank-word)
+ (define-key map "\C-w" 'isearch-yank-word-or-char)
(define-key map "\C-y" 'isearch-yank-line)
;; Define keys for regexp chars * ? |.
(define-key map [delete-frame] nil)
(define-key map [iconify-frame] nil)
(define-key map [make-frame-visible] nil)
+ (define-key map [mouse-movement] nil)
;; For searching multilingual text.
(define-key map "\C-\\" 'isearch-toggle-input-method)
(define-key map "\C-^" 'isearch-toggle-specified-input-method)
(defvar isearch-wrapped nil) ; Searching restarted from the top (bottom).
(defvar isearch-barrier 0)
(defvar isearch-just-started nil)
+(defvar isearch-start-hscroll 0) ; hscroll when starting the search.
; case-fold-search while searching.
; either nil, t, or 'yes. 'yes means the same as t except that mixed
; case in the search string is ignored.
(defvar isearch-case-fold-search nil)
+(defvar isearch-last-case-fold-search nil)
+
;; Used to save default value while isearch is active
(defvar isearch-original-minibuffer-message-timeout nil)
Type LFD (C-j) to match end of line.
Type \\[isearch-repeat-forward] to search again forward,\
\\[isearch-repeat-backward] to search again backward.
-Type \\[isearch-yank-word] to yank word from buffer onto end of search\
+Type \\[isearch-yank-word-or-char] to yank word from buffer onto end of search\
string and search for it.
Type \\[isearch-yank-line] to yank rest of line onto end of search string\
and search for it.
isearch-regexp regexp
isearch-word word-p
isearch-op-fun op-fun
+ isearch-last-case-fold-search isearch-case-fold-search
isearch-case-fold-search case-fold-search
isearch-string ""
isearch-message ""
isearch-within-brackets nil
isearch-slow-terminal-mode (and (<= baud-rate search-slow-speed)
(> (window-height)
- (* 4 search-slow-window-lines)))
+ (* 4
+ (abs search-slow-window-lines))))
isearch-other-end nil
isearch-small-window nil
isearch-just-started t
+ isearch-start-hscroll (window-hscroll)
isearch-opoint (point)
search-ring-yank-pointer nil
;; Maybe make minibuffer frame visible and/or raise it.
(let ((frame (window-frame (minibuffer-window))))
- (if (not (memq (frame-live-p frame) '(nil t)))
- (progn
- (make-frame-visible frame)
- (if minibuffer-auto-raise
- (raise-frame frame)))))
+ (unless (memq (frame-live-p frame) '(nil t))
+ (unless (frame-visible-p frame)
+ (make-frame-visible frame))
+ (if minibuffer-auto-raise
+ (raise-frame frame))))
(setq isearch-mode " Isearch") ;; forward? regexp?
(force-mode-line-update)
(defun isearch-update ()
;; Called after each command to update the display.
- (if (null unread-command-events)
+ (if (and (null unread-command-events)
+ (null executing-kbd-macro))
(progn
(if (not (input-pending-p))
(isearch-message))
(window-hscroll))
(set-window-hscroll (selected-window) 0))
(other-window 1))
- (goto-char found-point)))
- (if isearch-other-end
+ (goto-char found-point))
+ ;; Keep same hscrolling as at the start of the search when possible
+ (let ((current-scroll (window-hscroll)))
+ (set-window-hscroll (selected-window) isearch-start-hscroll)
+ (unless (pos-visible-in-window-p)
+ (set-window-hscroll (selected-window) current-scroll))))
+ (if isearch-other-end
(if (< isearch-other-end (point)) ; isearch-forward?
(isearch-highlight isearch-other-end (point))
(isearch-highlight (point) isearch-other-end))
(setq disable-point-adjustment t))
(defun isearch-done (&optional nopush edit)
- (let ((command `(isearch-resume ,isearch-string ,isearch-regexp
- ,isearch-word ,isearch-forward
- ,isearch-message
- ,isearch-case-fold-search)))
- (unless (equal (car command-history) command)
- (setq command-history (cons command command-history))))
+ (if isearch-resume-enabled
+ (let ((command `(isearch-resume ,isearch-string ,isearch-regexp
+ ,isearch-word ,isearch-forward
+ ,isearch-message
+ ',isearch-case-fold-search)))
+ (unless (equal (car command-history) command)
+ (setq command-history (cons command command-history)))))
(remove-hook 'mouse-leave-buffer-hook 'isearch-done)
(remove-hook 'kbd-macro-termination-hook 'isearch-done)
\\[isearch-ring-retreat-edit] to replace the search string with the previous item in the search ring.
\\[isearch-complete-edit] to complete the search string using the search ring.
\\<isearch-mode-map>
-If first char entered is \\[isearch-yank-word], then do word search instead."
+If first char entered is \\[isearch-yank-word-or-char], then do word search instead."
;; This code is very hairy for several reasons, explained in the code.
;; Mainly, isearch-mode must be terminated while editing and then restarted.
;; Word search does not apply (yet) to regexp searches,
;; no check is made here.
(message (isearch-message-prefix nil nil t))
- (if (eq 'isearch-yank-word
- (lookup-key isearch-mode-map (vector e)))
+ (if (memq (lookup-key isearch-mode-map (vector e))
+ '(isearch-yank-word
+ isearch-yank-word-or-char))
(setq isearch-word t;; so message-prefix is right
isearch-new-word t)
(cancel-kbd-macro-events)
(setq isearch-string (or (car (if isearch-regexp
regexp-search-ring
search-ring))
- ""))
+ "")
+
+ isearch-message
+ (mapconcat 'isearch-text-char-description
+ isearch-string ""))
;; This used to set the last search string,
;; but I think it is not right to do that here.
;; Only the string actually used should be saved.
"")
isearch-message
(mapconcat 'isearch-text-char-description
- isearch-string ""))
+ isearch-string "")
+ isearch-case-fold-search isearch-last-case-fold-search)
;; If already have what to search for, repeat it.
(or isearch-success
(progn
(isearch-update))
(defun isearch-delete-char ()
- "Discard last input item and move point back.
+ "Discard last input item and move point back.
If no previous match was done, just beep."
(interactive)
(if (null (cdr isearch-cmds))
(funcall binding click))))))
-(defun isearch-yank-word ()
- "Pull next word from buffer into search string."
- (interactive)
+(defun isearch-yank-internal (jumpform)
+ "Pull the text from point to the point reached by JUMPFORM.
+JUMPFORM is a lambda expression that takes no arguments and returns a
+buffer position, possibly having moved point to that position. For
+example, it might move point forward by a word and return point, or it
+might return the position of the end of the line."
(isearch-yank-string
(save-excursion
(and (not isearch-forward) isearch-other-end
(goto-char isearch-other-end))
- (buffer-substring-no-properties
- (point) (progn (forward-word 1) (point))))))
+ (buffer-substring-no-properties (point) (funcall jumpform)))))
+
+(defun isearch-yank-char ()
+ "Pull next letter from buffer into search string."
+ (interactive)
+ (isearch-yank-internal (lambda () (forward-char 1) (point))))
+
+(defun isearch-yank-word-or-char ()
+ "Pull next character or word from buffer into search string."
+ (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)
+ (forward-char 1)) (point))))
+
+(defun isearch-yank-word ()
+ "Pull next word from buffer into search string."
+ (interactive)
+ (isearch-yank-internal (lambda () (forward-word 1) (point))))
(defun isearch-yank-line ()
"Pull rest of line from buffer into search string."
(interactive)
- (isearch-yank-string
- (save-excursion
- (and (not isearch-forward) isearch-other-end
- (goto-char isearch-other-end))
- (buffer-substring-no-properties (point) (line-end-position)))))
+ (isearch-yank-internal (lambda () (line-end-position))))
(defun isearch-search-and-update ()
(defun isearch-whitespace-chars ()
"Match all whitespace chars, if in regexp mode.
-If you want to search for just a space, type \\[quoted-insert] SPC."
+If you want to search for just a space, type \\<isearch-mode-map>\\[isearch-quote-char] SPC."
(interactive)
(if isearch-regexp
(if (and search-whitespace-regexp (not isearch-within-brackets)
(concat " [" current-input-method-title "]: ")
": ")
)))
- (concat (upcase (substring m 0 1)) (substring m 1))))
-
+ (propertize (concat (upcase (substring m 0 1)) (substring m 1))
+ 'face 'minibuffer-prompt)))
(defun isearch-message-suffix (&optional c-q-hack ellipsis)
(concat (if c-q-hack "^Q" "")
;;; - the variable `isearch-invalid-regexp' is expected to be true
;;; iff `isearch-string' is an invalid regexp.
-(require 'timer)
-
(defgroup isearch-lazy-highlight nil
"Lazy highlighting feature for incremental search."
:prefix "isearch-lazy-highlight-"
'((((type tty pc) (class color))
(:background "magenta4" :foreground "cyan1"))
(((class color) (background light))
- (:background "magenta4" :foreground "lightskyblue1"))
+ ;; The background must not be too dark, for that means
+ ;; the character is hard to see when the cursor is there.
+ (:background "magenta2" :foreground "lightskyblue1"))
(((class color) (background dark))
(:background "palevioletred2" :foreground "brown4"))
(t (:inverse-video t)))
This happens when `isearch-update' is invoked (which can cause the
search string to change or the window to scroll)."
(when (and isearch-lazy-highlight
+ (null executing-kbd-macro)
(sit-for 0) ;make sure (window-start) is credible
(or (not (equal isearch-string
isearch-lazy-highlight-last-string))