emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Exposing Isearch toggleable options


From: Artur Malabarba
Subject: Exposing Isearch toggleable options
Date: Thu, 29 Oct 2015 00:20:41 +0000

I just pushed a branch called scratch/isearch-show-toggles, which implements a way of exposing some of isearch options to the user.

Basically, as soon as isearch starts, you should see something like this.

Toggles [M-s]:  [w] Word OFF  [_] Symbol OFF  ['] Character-Fold ON   [r] Regexp OFF
I-search: search string here

If your window is wide enough, you'll also see toggles for Lax-Whitespace, Case-Fold, and Invisibe (it auto-ajusts the number of toggles displayed so as to not take more than one line).

I'm not yet sure if this is worth merging to master, so I'd very much appreciate opinions.

Here's the (two-commit) patch for those who prefer:

From 1ddd546be001116024dbbb0afe74d137ff8c679f Mon Sep 17 00:00:00 2001
From: Artur Malabarba <address@hidden>
Date: Thu, 29 Oct 2015 00:28:14 +0000
Subject: [PATCH 1/2] * lisp/isearch.el (isearch-define-mode-toggle): Add
 keyword args

(isearch--toggles): New variable.
---
 lisp/isearch.el | 46 ++++++++++++++++++++++++++++++----------------
 1 file changed, 30 insertions(+), 16 deletions(-)

diff --git a/lisp/isearch.el b/lisp/isearch.el
index e9eec01..6ec5c7f 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -1488,20 +1488,31 @@ isearch-repeat-backward
 
 
 ;;; Toggles for `isearch-regexp-function' and `search-default-regexp-mode'.
-(defmacro isearch-define-mode-toggle (mode key function &optional docstring &rest body)
+(defvar isearch--toggles nil
+  "List of toggles defined with `isearch-define-mode-toggle'.
+Each element is a list of (NAME KEY PRED-FORM).")
+
+(cl-defmacro isearch-define-mode-toggle (mode key &rest body &key function
+                                              doc pred-form &allow-other-keys)
   "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.
+may be provided in DOC.
 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."
+The command then executes BODY and updates the isearch prompt.
+
+PRED-FORM, when evaluated should return non-nil if the mode is
+active.  It is mandatory only if FUNCTION is not provided."
   (declare (indent defun))
-  (let ((command-name (intern (format "isearch-toggle-%s" mode))))
+  (let ((command-name (intern (format "isearch-toggle-%s" mode)))
+        (pred-form (or pred-form `(eq isearch-regexp-function #',function))))
+    (while (keywordp (car body))
+      (setq body (cdr (cdr body))))
     `(progn
        (defun ,command-name ()
          ,(format "Toggle %s searching on or off.%s" mode
-                  (if docstring (concat "\n" docstring) ""))
+                  (if doc (concat "\n" doc) ""))
          (interactive)
          ,@(when function
              `((setq isearch-regexp-function
@@ -1512,6 +1523,7 @@ isearch-define-mode-toggle
          (setq isearch-success t isearch-adjusted t)
          (isearch-update))
        (define-key isearch-mode-map ,(concat "\M-s" key) #',command-name)
+       (setf (alist-get ',mode isearch--toggles) '(,key (lambda () ,pred-form)))
        ,@(when (symbolp function)
            `((put ',function 'isearch-message-prefix ,(format "%s " mode))
              (cl-callf (lambda (types) (cons 'choice
@@ -1519,12 +1531,12 @@ isearch-define-mode-toggle
                                               (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)
+(isearch-define-mode-toggle word "w"           :function word-search-regexp)
+(isearch-define-mode-toggle symbol "_"         :function isearch-symbol-regexp)
+(isearch-define-mode-toggle character-fold "'" :function character-fold-to-regexp)
 (put 'character-fold-to-regexp 'isearch-message-prefix "char-fold ")
 
-(isearch-define-mode-toggle regexp "r" nil nil
+(isearch-define-mode-toggle regexp "r" :pred-form isearch-regexp
   (setq isearch-regexp (not isearch-regexp))
   (if isearch-regexp (setq isearch-regexp-function nil)))
 
@@ -1537,8 +1549,9 @@ isearch--momentary-message
              string))
   (sit-for 1))
 
-(isearch-define-mode-toggle lax-whitespace " " nil
-  "In ordinary search, toggles the value of the variable
+(isearch-define-mode-toggle lax-whitespace " "
+  :pred-form (if isearch-regexp isearch-regexp-lax-whitespace isearch-lax-whitespace)
+  :doc "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'."
   (isearch--momentary-message
@@ -1548,20 +1561,21 @@ isearch--momentary-message
        "match spaces loosely"
      "match spaces literally")))
 
-(isearch-define-mode-toggle case-fold "c" nil
-  "Toggles the value of the variable `isearch-case-fold-search'."
+(isearch-define-mode-toggle case-fold "c"
+  :pred-form isearch-case-fold-search
+  :doc "Toggles the value of the variable `isearch-case-fold-search'."
   (isearch--momentary-message
    (if (setq isearch-case-fold-search
              (if isearch-case-fold-search nil 'yes))
        "case insensitive"
      "case sensitive")))
 
-(isearch-define-mode-toggle invisible "i" nil
-  "This determines whether to search inside invisible text or not.
+(isearch-define-mode-toggle invisible "i"
+  :pred-form isearch-invisible
+  :doc "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)."
-  "match %svisible text"
   (isearch--momentary-message
    (if (setq isearch-invisible
              (if isearch-invisible
--
2.5.3


From 37d169df4433be1869eac9c916e548b9bd66ff04 Mon Sep 17 00:00:00 2001
From: Artur Malabarba <address@hidden>
Date: Thu, 29 Oct 2015 00:51:21 +0000
Subject: [PATCH 2/2] * lisp/isearch.el: Display toggles and their keys

(isearch--describe-toggles): New function.
(isearch-show-toggles): New user option.
(isearch-message-prefix): Use them.
---
 lisp/isearch.el | 29 +++++++++++++++++++++++++++--
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/lisp/isearch.el b/lisp/isearch.el
index 6ec5c7f..6327068 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -1583,6 +1583,30 @@ isearch--momentary-message
        "match invisible text"
      "match visible text")))
 
+(defcustom isearch-show-toggles t
+  "Non-nil means to list options above input prompt."
+  :type 'boolean
+  :version "25.1")
+
+(defun isearch--describe-toggles ()
+  "Return a propertized description of isearch toggles."
+  (let ((toggles
+         (concat
+          #("Toggles [M-s]:  " 0 9 (face minibuffer-prompt) 12 16 (face minibuffer-prompt))
+          (mapconcat (lambda (x) (format (propertize "[%s] %s %s" 'face 'minibuffer-prompt)
+                                    (propertize (elt x 1) 'face 'default)
+                                    (capitalize (symbol-name (car x)))
+                                    (if (funcall (elt x 2))
+                                        (propertize "ON " 'face 'default) "OFF")))
+                     (reverse isearch--toggles)
+                     "  ")
+          "\n"))
+        (width (window-width (minibuffer-window))))
+    (if (> width (string-width toggles))
+        toggles
+      (replace-regexp-in-string "\\[[^[]*\\'" "\n"
+                                (substring toggles 0 width)))))
+
 
 ;; Word search
 
@@ -2592,8 +2616,9 @@ isearch-message-prefix
             (concat " [" current-input-method-title "]: "))
              ": ")
            )))
-    (propertize (concat (upcase (substring m 0 1)) (substring m 1))
-        'face 'minibuffer-prompt)))
+    (concat (when isearch-show-toggles (isearch--describe-toggles))
+            (propertize (concat (upcase (substring m 0 1)) (substring m 1))
+                        'face 'minibuffer-prompt))))
 
 (defun isearch-message-suffix (&optional c-q-hack)
   (concat (if c-q-hack "^Q" "")
--
2.5.3


reply via email to

[Prev in Thread] Current Thread [Next in Thread]