From 12c0edb7555613aecfd27610601f137be252b804 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Wed, 28 Oct 2015 11:43:52 +0000 Subject: [PATCH] * lisp/isearch.el: Define all toggles with `isearch-define-mode-toggle' (isearch-define-mode-toggle): New macro. (isearch-toggle-invisible): Renamed to `isearch-define-mode-toggle'. (isearch-toggle-case-fold, isearch-toggle-invisible) (isearch-toggle-regexp, isearch-toggle-lax-whitespace): Define with `isearch-define-mode-toggle'. --- lisp/isearch.el | 105 ++++++++++++++++++++++-------------------------- 1 file changed, 47 insertions(+), 58 deletions(-) diff --git a/lisp/isearch.el b/lisp/isearch.el index a1ce4f19489..1c545de3e20 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -235,7 +235,7 @@ If a function, use that function as an `isearch-regexp-function'. Example functions are `word-search-regexp' \(`\\[isearch-toggle-word]'), `isearch-symbol-regexp' \(`\\[isearch-toggle-symbol]'), and `character-fold-to-regexp' \(`\\[isearch-toggle-character-fold]')." - ;; :type is set below by `isearch-specify-regexp-function'. + ;; :type is set below by `isearch-define-mode-toggle'. :type '(choice (const :tag "Literal search" nil) (const :tag "Regexp search" t) (function :tag "Other")) @@ -520,11 +520,7 @@ This is like `describe-bindings', but displays only Isearch keys." (put 'isearch-edit-string :advertised-binding "\M-se") (define-key map "\M-se" 'isearch-edit-string) - (define-key map "\M-sc" 'isearch-toggle-case-fold) - (define-key map "\M-si" 'isearch-toggle-invisible) - (define-key map "\M-sr" 'isearch-toggle-regexp) - (define-key map "\M-s " 'isearch-toggle-lax-whitespace) - ;; More toggles defined by `isearch-specify-regexp-function'. + ;; More toggles defined by `isearch-define-mode-toggle'. (define-key map [?\M-%] 'isearch-query-replace) (define-key map [?\C-\M-%] 'isearch-query-replace-regexp) @@ -1494,50 +1490,52 @@ Use `isearch-exit' to quit without signaling." (interactive) (isearch-repeat 'backward)) -(defun isearch-toggle-regexp () - "Toggle regexp searching on or off." - ;; The status stack is left unchanged. - (interactive) - (setq isearch-regexp (not isearch-regexp)) - (if isearch-regexp (setq isearch-regexp-function nil)) - (setq isearch-success t isearch-adjusted t) - (isearch-update)) - + ;;; Toggles for `isearch-regexp-function' and `search-default-regexp-mode'. -(defmacro isearch-specify-regexp-function (mode function key) - "Define a search MODE in which `isearch-regexp-function' is set to FUNCTION. -Define a command called `isearch-toggle-MODE' and bind it to -`isearch-mode-map' under `M-s KEY'. -Also set the `isearch-message-prefix' property of FUNCTION." +(defmacro isearch-define-mode-toggle (mode key function &optional docstring &rest body) + "Define a command called `isearch-toggle-MODE' and bind it to `M-s KEY'. +The first line of the docstring is auto-generated, the remainder +may be provided in DOCSTRING. +If FUNCTION is a symbol, this command first toggles the value of +`isearch-regexp-function' between nil and FUNCTION. Also set the +`isearch-message-prefix' property of FUNCTION. +The command then executes BODY and updates the isearch prompt." + (declare (indent defun)) (let ((command-name (intern (format "isearch-toggle-%s" mode)))) `(progn (defun ,command-name () - ,(format "Toggle %s searching on or off." mode) + ,(format "Toggle %s searching on or off.%s" mode + (if docstring (concat "\n" docstring) "")) (interactive) - (setq isearch-regexp-function - (unless (eq isearch-regexp-function #',function) - #',function)) - (when isearch-regexp-function (setq isearch-regexp nil)) + ,@(when function + `((setq isearch-regexp-function + (unless (eq isearch-regexp-function #',function) + #',function)) + (when isearch-regexp-function (setq isearch-regexp nil)))) + ,@body (setq isearch-success t isearch-adjusted t) (isearch-update)) (define-key isearch-mode-map ,(concat "\M-s" key) #',command-name) - (put ',function 'isearch-message-prefix ,(format "%s " mode)) - (cl-callf (lambda (types) (cons 'choice - (cons '(const :tag ,(capitalize (format "%s search" mode)) ,function) - (cdr types)))) - (get 'search-default-regexp-mode 'custom-type))))) - -(isearch-specify-regexp-function word word-search-regexp "w") -(isearch-specify-regexp-function symbol isearch-symbol-regexp "_") -(isearch-specify-regexp-function character-fold character-fold-to-regexp "'") + ,@(when (symbolp function) + `((put ',function 'isearch-message-prefix ,(format "%s " mode)) + (cl-callf (lambda (types) (cons 'choice + (cons '(const :tag ,(capitalize (format "%s search" mode)) ,function) + (cdr types)))) + (get 'search-default-regexp-mode 'custom-type))))))) + +(isearch-define-mode-toggle word "w" word-search-regexp) +(isearch-define-mode-toggle symbol "_" isearch-symbol-regexp) +(isearch-define-mode-toggle character-fold "'" character-fold-to-regexp) (put 'character-fold-to-regexp 'isearch-message-prefix "char-fold ") -(defun isearch-toggle-lax-whitespace () - "Toggle whitespace matching in searching on or off. -In ordinary search, toggles the value of the variable +(isearch-define-mode-toggle regexp "r" nil nil + (setq isearch-regexp (not isearch-regexp)) + (if isearch-regexp (setq isearch-regexp-function nil))) + +(isearch-define-mode-toggle lax-whitespace " " nil + "In ordinary search, toggles the value of the variable `isearch-lax-whitespace'. In regexp search, toggles the value of the variable `isearch-regexp-lax-whitespace'." - (interactive) (if isearch-regexp (setq isearch-regexp-lax-whitespace (not isearch-regexp-lax-whitespace)) (setq isearch-lax-whitespace (not isearch-lax-whitespace))) @@ -1550,14 +1548,10 @@ value of the variable `isearch-regexp-lax-whitespace'." isearch-lax-whitespace) "match spaces loosely" "match spaces literally"))) - (setq isearch-success t isearch-adjusted t) - (sit-for 1) - (isearch-update)) + (sit-for 1)) -(defun isearch-toggle-case-fold () - "Toggle case folding in searching on or off. -Toggles the value of the variable `isearch-case-fold-search'." - (interactive) +(isearch-define-mode-toggle case-fold "c" nil + "Toggles the value of the variable `isearch-case-fold-search'." (setq isearch-case-fold-search (if isearch-case-fold-search nil 'yes)) (let ((message-log-max nil)) @@ -1565,26 +1559,21 @@ Toggles the value of the variable `isearch-case-fold-search'." (isearch-message-prefix nil isearch-nonincremental) isearch-message (if isearch-case-fold-search "in" ""))) - (setq isearch-success t isearch-adjusted t) - (sit-for 1) - (isearch-update)) + (sit-for 1)) -(defun isearch-toggle-invisible () - "Toggle searching in invisible text on or off. +(isearch-define-mode-toggle invisible "i" nil + "This determines whether to search inside invisible text or not. Toggles the variable `isearch-invisible' between values nil and a non-nil value of the option `search-invisible' \(or `open' if `search-invisible' is nil)." - (interactive) (setq isearch-invisible - (if isearch-invisible nil (or search-invisible 'open))) + (if isearch-invisible nil (or search-invisible 'open))) (let ((message-log-max nil)) (message "%s%s [match %svisible text]" - (isearch-message-prefix nil isearch-nonincremental) - isearch-message - (if isearch-invisible "in" ""))) - (setq isearch-success t isearch-adjusted t) - (sit-for 1) - (isearch-update)) + (isearch-message-prefix nil isearch-nonincremental) + isearch-message + (if isearch-invisible "in" ""))) + (sit-for 1)) ;; Word search -- 2.39.5