⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 isearch.el

📁 早期freebsd实现
💻 EL
字号:
;; Incremental search;; Copyright (C) 1985, 1986 Free Software Foundation, Inc.;; This file is part of GNU Emacs.;; GNU Emacs is free software; you can redistribute it and/or modify;; it under the terms of the GNU General Public License as published by;; the Free Software Foundation; either version 1, or (at your option);; any later version.;; GNU Emacs is distributed in the hope that it will be useful,;; but WITHOUT ANY WARRANTY; without even the implied warranty of;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the;; GNU General Public License for more details.;; You should have received a copy of the GNU General Public License;; along with GNU Emacs; see the file COPYING.  If not, write to;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.; in loaddefs.el;(defvar search-last-string "";  "Last string search for by a search command.;This does not include direct calls to the primitive search functions,;and does not include searches that are aborted.");(defvar search-last-regexp "";  "Last string searched for by a regexp search command.;This does not include direct calls to the primitive search functions,;and does not include searches that are aborted.");;(defconst search-repeat-char ?\C-s;  "Character to repeat incremental search forwards.");(defconst search-reverse-char ?\C-r;  "Character to repeat incremental search backwards.");(defconst search-exit-char ?\e;  "Character to exit incremental search.");(defconst search-delete-char ?\177;  "Character to delete from incremental search string.");(defconst search-quote-char ?\C-q;  "Character to quote special characters for incremental search.");(defconst search-yank-word-char ?\C-w;  "Character to pull next word from buffer into search string.");(defconst search-yank-line-char ?\C-y;  "Character to pull rest of line from buffer into search string.");(defconst search-exit-option t;  "Non-nil means random control characters terminate incremental search.");;(defvar search-slow-window-lines 1;  "*Number of lines in slow search display windows.");(defconst search-slow-speed 1200;  "*Highest terminal speed at which to use \"slow\" style incremental search.;This is the style where a one-line window is created to show the line;that the search has reached.");; This function does all the work of incremental search.;; The functions attached to ^R and ^S are trivial,;; merely calling this one, but they are always loaded by default;; whereas this file can optionally be autoloadable.;; This is the only entry point in this file.(defun isearch (forward &optional regexp)  (let ((search-string "")	(search-message "")	(cmds nil)	(success t)	(wrapped nil)	(barrier (point))	adjusted	(invalid-regexp nil)	(slow-terminal-mode (and (<= (baud-rate) search-slow-speed)				 (> (window-height)				    (* 4 search-slow-window-lines))))	(other-end nil)    ;Start of last match if fwd, end if backwd.	(small-window nil)		;if t, using a small window	(found-point nil)		;to restore point from a small window	;; This is the window-start value found by the search.	(found-start nil)	(opoint (point))	(inhibit-quit t))  ;Prevent ^G from quitting immediately.    (isearch-push-state)    (save-window-excursion     (catch 'search-done       (while t	 (or (>= unread-command-char 0)	     (progn	       (or (input-pending-p)		   (isearch-message))	       (if (and slow-terminal-mode			(not (or small-window (pos-visible-in-window-p))))		   (progn		     (setq small-window t)		     (setq found-point (point))		     (move-to-window-line 0)		     (let ((window-min-height 1))		       (split-window nil (if (< search-slow-window-lines 0)					     (1+ (- search-slow-window-lines))					   (- (window-height)					      (1+ search-slow-window-lines)))))		     (if (< search-slow-window-lines 0)			 (progn (vertical-motion (- 1 search-slow-window-lines))				(set-window-start (next-window) (point))				(set-window-hscroll (next-window)						    (window-hscroll))				(set-window-hscroll (selected-window) 0))		       (other-window 1))		     (goto-char found-point)))))	 (let ((char (if quit-flag			 ?\C-g		       (read-char))))	   (setq quit-flag nil adjusted nil)	   ;; Meta character means exit search.	   (cond ((and (>= char 128)		       search-exit-option)		  (setq unread-command-char char)		  (throw 'search-done t))		 ((eq char search-exit-char)		  ;; Esc means exit search normally.		  ;; Except, if first thing typed, it means do nonincremental		  (if (= 0 (length search-string))		      (nonincremental-search forward regexp))		  (throw 'search-done t))		 ((= char ?\C-g)		  ;; ^G means the user tried to quit.		  (ding)		  (discard-input)		  (if success		      ;; If search is successful, move back to starting point		      ;; and really do quit.		      (progn (goto-char opoint)			     (signal 'quit nil))		    ;; If search is failing, rub out until it is once more		    ;;  successful.		    (while (not success) (isearch-pop))))		 ((or (eq char search-repeat-char)		      (eq char search-reverse-char))		  (if (eq forward (eq char search-repeat-char))		      ;; C-s in forward or C-r in reverse.		      (if (equal search-string "")			  ;; If search string is empty, use last one.			  (setq search-string				(if regexp				    search-last-regexp search-last-string)				search-message				(mapconcat 'text-char-description					   search-string ""))			;; If already have what to search for, repeat it.			(or success			    (progn (goto-char (if forward (point-min) (point-max)))				   (setq wrapped t))))		    ;; C-s in reverse or C-r in forward, change direction.		    (setq forward (not forward)))		  (setq barrier (point)) ; For subsequent \| if regexp.		  (setq success t)		  (or (equal search-string "")		      (isearch-search))		  (isearch-push-state))		 ((= char search-delete-char)		  ;; Rubout means discard last input item and move point		  ;; back.  If buffer is empty, just beep.		  (if (null (cdr cmds))		      (ding)		    (isearch-pop)))		 (t		  (cond ((or (eq char search-yank-word-char)			     (eq char search-yank-line-char))			 ;; ^W means gobble next word from buffer.			 ;; ^Y means gobble rest of line from buffer.			 (let ((word (save-excursion				       (and (not forward) other-end					    (goto-char other-end))				       (buffer-substring					(point)					(save-excursion					  (if (eq char search-yank-line-char)					      (end-of-line)					    (forward-word 1))					  (point))))))			   (if regexp			       (setq word (regexp-quote word)))			   (setq search-string (concat search-string word)				 search-message				   (concat search-message					   (mapconcat 'text-char-description						      word "")))))			 ;; Any other control char =>			 ;;  unread it and exit the search normally.			 ((and search-exit-option			       (/= char search-quote-char)			       (or (= char ?\177)				   (and (< char ? ) (/= char ?\t) (/= char ?\r))))			  (setq unread-command-char char)			  (throw 'search-done t))			 (t			  ;; Any other character => add it to the			  ;;  search string and search.			  (cond ((= char search-quote-char)				 (setq char (read-quoted-char					     (isearch-message t))))				((= char ?\r)				 ;; unix braindeath				 (setq char ?\n)))			  (setq search-string (concat search-string						      (char-to-string char))				search-message (concat search-message						       (text-char-description char)))))		  (if (and (not success)			   ;; unsuccessful regexp search may become			   ;;  successful by addition of characters which			   ;;  make search-string valid			   (not regexp))		      nil		    ;; If a regexp search may have been made more		    ;; liberal, retreat the search start.		    ;; Go back to place last successful search started		    ;; or to the last ^S/^R (barrier), whichever is nearer.		    (and regexp success cmds			 (cond ((memq char '(?* ??))				(setq adjusted t)				(let ((cs (nth (if forward						   5 ; other-end						 2) ; saved (point)					       (car (cdr cmds)))))				  ;; (car cmds) is after last search;				  ;; (car (cdr cmds)) is from before it.				  (setq cs (or cs barrier))				  (goto-char				   (if forward				       (max cs barrier)				     (min cs barrier)))))			       ((eq char ?\|)				(setq adjusted t)				(goto-char barrier))))		    ;; In reverse regexp search, adding a character at		    ;; the end may cause zero or many more chars to be		    ;; matched, in the string following point.		    ;; Allow all those possibiities without moving point as		    ;; long as the match does not extend past search origin.		    (if (and regexp (not forward) (not adjusted)			     (condition-case ()				 (looking-at search-string)			       (error nil))			     (<= (match-end 0) (min opoint barrier)))			(setq success t invalid-regexp nil			      other-end (match-end 0))		      ;; Not regexp, not reverse, or no match at point.		      (if (and other-end (not adjusted))			  (goto-char (if forward other-end				       (min opoint barrier (1+ other-end)))))		      (isearch-search)))		  (isearch-push-state))))))     (setq found-start (window-start (selected-window)))     (setq found-point (point)))    (if (> (length search-string) 0)	(if regexp	    (setq search-last-regexp search-string)	    (setq search-last-string search-string)))    ;; If there was movement, mark the starting position.    ;; Maybe should test difference between and set mark iff > threshold.    (if (/= (point) opoint)	(push-mark opoint)      (message ""))    (if small-window	(goto-char found-point)      ;; Exiting the save-window-excursion clobbers this; restore it.      (set-window-start (selected-window) found-start t))))(defun isearch-message (&optional c-q-hack ellipsis)  ;; 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.  (and invalid-regexp ellipsis       (condition-case ()	   (progn (re-search-forward search-string (point) t)		  (setq invalid-regexp nil))	 (error nil)))  ;; If currently failing, display no ellipsis.  (or success (setq ellipsis nil))  (let ((m (concat (if success "" "failing ")		   (if wrapped "wrapped ")		   (if regexp "regexp " "")		   "I-search"		   (if forward ": " " backward: ")		   search-message		   (if c-q-hack "^Q" "")		   (if invalid-regexp		       (concat " [" invalid-regexp "]")		     ""))))    (aset m 0 (upcase (aref m 0)))    (let ((cursor-in-echo-area ellipsis))      (if c-q-hack m (message "%s" m)))))(defun isearch-pop ()  (setq cmds (cdr cmds))  (let ((cmd (car cmds)))    (setq search-string (car cmd)	  search-message (car (cdr cmd))	  success (nth 3 cmd)	  forward (nth 4 cmd)	  other-end (nth 5 cmd)	  invalid-regexp (nth 6 cmd)	  wrapped (nth 7 cmd)	  barrier (nth 8 cmd))    (goto-char (car (cdr (cdr cmd))))))(defun isearch-push-state ()  (setq cmds (cons (list search-string search-message (point)			 success forward other-end invalid-regexp			 wrapped barrier)		   cmds)))(defun isearch-search ()  (isearch-message nil t)  (condition-case lossage      (let ((inhibit-quit nil))	(if regexp (setq invalid-regexp nil))	(setq success	      (funcall	       (if regexp		   (if forward 're-search-forward 're-search-backward)		 (if forward 'search-forward 'search-backward))	       search-string nil t))	(if success	    (setq other-end		  (if forward (match-beginning 0) (match-end 0)))))    (quit (setq unread-command-char ?\C-g)	  (setq success nil))    (invalid-regexp (setq invalid-regexp (car (cdr lossage)))		    (if (string-match "\\`Premature \\|\\`Unmatched \\|\\`Invalid "				      invalid-regexp)			(setq invalid-regexp "incomplete input"))))  (if success      nil    ;; Ding if failed this time after succeeding last time.    (and (nth 3 (car cmds))	 (ding))    (goto-char (nth 2 (car cmds)))));; This is called from incremental-search;; if the first input character is the exit character.;; The interactive-arg-reader uses free variables `forward' and `regexp';; which are bound by `incremental-search'.;; We store the search string in `search-string';; which has been bound already by `incremental-search';; so that, when we exit, it is copied into `search-last-string'.(defun nonincremental-search (forward regexp)  (let (message char function string inhibit-quit)    (let ((cursor-in-echo-area t))      ;; Prompt assuming not word search,      (setq message (if regexp 			(if forward "Regexp search: "			  "Regexp search backward: ")		      (if forward "Search: " "Search backward: ")))      (message "%s" message)      ;; Read 1 char and switch to word search if it is ^W.      (setq char (read-char)))    (if (eq char search-yank-word-char)	(setq message (if forward "Word search: " "Word search backward: "))      ;; Otherwise let that 1 char be part of the search string.      (setq unread-command-char char))    (setq function	  (if (eq char search-yank-word-char)	      (if forward 'word-search-forward 'word-search-backward)	    (if regexp		(if forward 're-search-forward 're-search-backward)	      (if forward 'search-forward 'search-backward))))    ;; Read the search string with corrected prompt.    (setq string (read-string message))    ;; Empty means use default.    (if (= 0 (length string))	(setq string search-last-string)      ;; Set last search string now so it is set even if we fail.      (setq search-last-string string))    ;; Since we used the minibuffer, we should be available for redo.    (setq command-history (cons (list function string) command-history))    ;; Go ahead and search.    (funcall function string)))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -