From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: charles@aurox.ch (Charles A. Roelli) Newsgroups: gmane.emacs.bugs Subject: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc Date: Thu, 15 Nov 2018 20:57:12 +0100 Message-ID: References: <83muroyzfk.fsf@gnu.org> <83woqrx9pt.fsf@gnu.org> <835zy3tfrb.fsf@gnu.org> <83bm7pueej.fsf@gnu.org> <834ld6m5jk.fsf@gnu.org> <831s7tauzy.fsf@gnu.org> Reply-To: charles@aurox.ch NNTP-Posting-Host: blaine.gmane.org X-Trace: blaine.gmane.org 1542311650 3078 195.159.176.226 (15 Nov 2018 19:54:10 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Thu, 15 Nov 2018 19:54:10 +0000 (UTC) Cc: 32990@debbugs.gnu.org To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Thu Nov 15 20:54:05 2018 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gNNiH-0000g8-0E for geb-bug-gnu-emacs@m.gmane.org; Thu, 15 Nov 2018 20:54:05 +0100 Original-Received: from localhost ([::1]:40537 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gNNkN-0001pM-Bt for geb-bug-gnu-emacs@m.gmane.org; Thu, 15 Nov 2018 14:56:15 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:34124) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gNNkF-0001p5-CQ for bug-gnu-emacs@gnu.org; Thu, 15 Nov 2018 14:56:08 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gNNkD-0005m1-Fm for bug-gnu-emacs@gnu.org; Thu, 15 Nov 2018 14:56:07 -0500 Original-Received: from debbugs.gnu.org ([208.118.235.43]:50209) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gNNkA-0005lU-Q6 for bug-gnu-emacs@gnu.org; Thu, 15 Nov 2018 14:56:03 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1gNNkA-0004Zh-Gw for bug-gnu-emacs@gnu.org; Thu, 15 Nov 2018 14:56:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: charles@aurox.ch (Charles A. Roelli) Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 15 Nov 2018 19:56:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 32990 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 32990-submit@debbugs.gnu.org id=B32990.154231175517573 (code B ref 32990); Thu, 15 Nov 2018 19:56:02 +0000 Original-Received: (at 32990) by debbugs.gnu.org; 15 Nov 2018 19:55:55 +0000 Original-Received: from localhost ([127.0.0.1]:54467 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gNNk2-0004ZL-J6 for submit@debbugs.gnu.org; Thu, 15 Nov 2018 14:55:55 -0500 Original-Received: from sinyavsky.aurox.ch ([37.35.109.145]:60504) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gNNk0-0004Z8-CI for 32990@debbugs.gnu.org; Thu, 15 Nov 2018 14:55:53 -0500 Original-Received: from sinyavsky.aurox.ch (sinyavsky.aurox.ch [127.0.0.1]) by sinyavsky.aurox.ch (Postfix) with ESMTP id 52E432296A for <32990@debbugs.gnu.org>; Thu, 15 Nov 2018 20:00:27 +0000 (UTC) Authentication-Results: sinyavsky.aurox.ch (amavisd-new); dkim=pass reason="pass (just generated, assumed good)" header.d=aurox.ch DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=aurox.ch; h= references:reply-to:subject:subject:in-reply-to:to:from:from :message-id:date:date; s=dkim; t=1542312023; x=1543176024; bh=H7 hiw24pcfjVT1jdqYjpRJQgIMgL4p3EbLGz0odQSyI=; b=fVqZ3S7wWcddNVM2NT FrEsfkPUuoq44q+X4KwIaMALXgjFkcGtz6pShAX1pQSj14aTKqeLsPjRqj9qBNA3 2xjRjnVJupNw64+/lPMiCextBphP7XRj4qMeWZKeezd4n01ZDFeQzOJyzsLGdYr4 HkcIW/gutgpIoScW7ztAELDpE= X-Virus-Scanned: Debian amavisd-new at test.virtualizor.com Original-Received: from sinyavsky.aurox.ch ([127.0.0.1]) by sinyavsky.aurox.ch (sinyavsky.aurox.ch [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id UVvqEnQ3nE0V for <32990@debbugs.gnu.org>; Thu, 15 Nov 2018 20:00:23 +0000 (UTC) Original-Received: from gray (unknown [IPv6:2a02:1205:34ff:bc50:c62c:3ff:fe30:b864]) by sinyavsky.aurox.ch (Postfix) with ESMTPSA id 611C42295D; Thu, 15 Nov 2018 20:00:23 +0000 (UTC) In-reply-to: <831s7tauzy.fsf@gnu.org> (message from Eli Zaretskii on Sat, 10 Nov 2018 16:05:05 +0200) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:152428 Archived-At: > Date: Sat, 10 Nov 2018 16:05:05 +0200 > From: Eli Zaretskii > > I think we should at least describe in the doc string what is > described in "Basic Isearch", which would mean adding > isearch-delete-char. Other than that, I'm okay with this text. Ok, I will add that in too. > > I remember reading somewhere a suggestion for adding a toolbar (and > > (or) a dedicated menu) for use during isearch-mode, to help the > > discoverability of these myriad keybindings. That could be a good > > alternative to listing verbosely every binding in the docstring. > > I agree, but we should make sure clicking the menu won't exit Isearch. > > Thanks. There's a first draft of a menu- and tool-bar for Isearch at the end of this message (on branch master). Clicking the menu items and icons should work okay with the mouse, but I haven't yet found a way to show the menu with either "tmm-menubar" or TTY menus, since activating these functions will normally exit Isearch. diff --git a/lisp/isearch.el b/lisp/isearch.el index 035ff69..1f8a611 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -489,6 +489,142 @@ 'isearch-mode-help ;; Define isearch-mode keymap. +(defvar isearch-menu-bar-map + (let ((map (make-sparse-keymap "Isearch"))) + (define-key map [isearch-complete] + '(menu-item "Complete current search string" isearch-complete + :help "Complete current search string over search history")) + (define-key map [isearch-complete-separator] + '(menu-item "--")) + (define-key map [isearch-query-replace-regexp] + '(menu-item "Replace search string as regexp" isearch-query-replace-regexp + :help "Replace matches for current search string as regexp")) + (define-key map [isearch-query-replace] + '(menu-item "Replace search string" isearch-query-replace + :help "Replace matches for current search string")) + (define-key map [isearch-occur] + '(menu-item "Show all matches for search string" isearch-occur + :help "Show all matches for current search string")) + (define-key map [isearch-highlight-regexp] + '(menu-item "Highlight all matches for search string" + isearch-highlight-regexp + :help "Highlight all matches for current search string")) + (define-key map [isearch-search-replace-separator] + '(menu-item "--")) + (define-key map [isearch-toggle-specified-input-method] + '(menu-item "Turn on specific input method" + isearch-toggle-specified-input-method + :help "Turn on specific input method for search")) + (define-key map [isearch-toggle-input-method] + '(menu-item "Toggle input method" isearch-toggle-input-method + :help "Toggle input method for search")) + (define-key map [isearch-input-method-separator] + '(menu-item "--")) + (define-key map [isearch-char-by-name] + '(menu-item "Search for char by name" isearch-char-by-name + :help "Search for character by name")) + (define-key map [isearch-quote-char] + '(menu-item "Search for literal char" isearch-quote-char + :help "Search for literal char")) + (define-key map [isearch-special-char-separator] + '(menu-item "--")) + (define-key map [isearch-toggle-word] + '(menu-item "Word matching" isearch-toggle-word + :help "Word matching" + :button (:toggle + . (eq isearch-regexp-function 'word-search-regexp)))) + (define-key map [isearch-toggle-symbol] + '(menu-item "Symbol matching" isearch-toggle-symbol + :help "Symbol matching" + :button (:toggle + . (eq isearch-regexp-function + 'isearch-symbol-regexp)))) + (define-key map [isearch-toggle-regexp] + '(menu-item "Regexp matching" isearch-toggle-regexp + :help "Regexp matching" + :button (:toggle . isearch-regexp))) + (define-key map [isearch-toggle-invisible] + '(menu-item "Invisible text matching" isearch-toggle-invisible + :help "Invisible text matching" + :button (:toggle . isearch-invisible))) + (define-key map [isearch-toggle-char-fold] + '(menu-item "Character folding matching" isearch-toggle-char-fold + :help "Character folding matching" + :button (:toggle + . (eq isearch-regexp-function + 'char-fold-to-regexp)))) + (define-key map [isearch-toggle-case-fold] + '(menu-item "Case folding matching" isearch-toggle-case-fold + :help "Case folding matching" + :button (:toggle . isearch-case-fold-search))) + (define-key map [isearch-toggle-lax-whitespace] + '(menu-item "Lax whitespace matching" isearch-toggle-lax-whitespace + :help "Lax whitespace matching" + :button (:toggle . isearch-lax-whitespace))) + (define-key map [isearch-toggle-separator] + '(menu-item "--")) + (define-key map [isearch-del-char] + '(menu-item "Delete last character from search string" isearch-del-char + :help "Delete last character from search string")) + (define-key map [isearch-yank-pop] + '(menu-item "Yank previous kill on search string" isearch-yank-pop + :help "Replace yanked previous kill on search string")) + (define-key map [isearch-yank-kill] + '(menu-item "Yank current kill on search string" isearch-yank-kill + :help "Append current kill to search string")) + (define-key map [isearch-yank-line] + '(menu-item "Yank rest of line on search string" isearch-yank-line + :help "Yank the rest of the current line on search string")) + (define-key map [isearch-yank-symbol-or-char] + '(menu-item "Yank symbol/char on search string" + isearch-yank-symbol-or-char + :help "Yank next symbol or char on search string")) + (define-key map [isearch-yank-word-or-char] + '(menu-item "Yank word/char on search string" + isearch-yank-word-or-char + :help "Yank next word or char on search string")) + (define-key map [isearch-yank-char] + '(menu-item "Yank char on search string" isearch-yank-char + :help "Yank char at point on search string")) + (define-key map [isearch-yank-separator] + '(menu-item "--")) + (define-key map [isearch-edit-string] + '(menu-item "Edit current search string" isearch-edit-string + :help "Edit current search string")) + (define-key map [isearch-ring-retreat] + '(menu-item "Edit previous search string" isearch-ring-retreat + :help "Edit previous search string in Isearch history")) + (define-key map [isearch-ring-advance] + '(menu-item "Edit next search string" isearch-ring-advance + :help "Edit next search string in Isearch history")) + (define-key map [isearch-delete-char] + '(menu-item "Cancel last input item" isearch-delete-char + :help "Cancel the last Isearch command")) + (define-key map [isearch-repeat-backward] + '(menu-item "Repeat search backward" isearch-repeat-backward + :help "Repeat current search backward")) + (define-key map [isearch-repeat-forward] + '(menu-item "Repeat search forward" isearch-repeat-forward + :help "Repeat current search forward")) + (define-key map [isearch-nonincremental] + '(menu-item "Nonincremental search" isearch-exit + :help "Start nonincremental search" + :visible (string-equal isearch-string ""))) + (define-key map [isearch-exit] + '(menu-item "Finish search" isearch-exit + :help "Finish search leaving point where it is" + :visible (not (string-equal isearch-string "")))) + (define-key map [isearch-abort] + '(menu-item "Remove characters not found" isearch-abort + :help "Quit current search" + :visible (not isearch-success))) + (define-key map [isearch-cancel] + `(menu-item "Cancel search" isearch-cancel + :help "Cancel current search and return to starting point" + :filter ,(lambda (binding) + (if isearch-success 'isearch-abort binding)))) + map)) + (defvar isearch-mode-map (let ((i 0) (map (make-keymap))) @@ -595,9 +731,58 @@ isearch-mode-map ;; characters to the search string. See iso-transl.el. (define-key map "\C-x8\r" 'isearch-char-by-name) + (define-key map [menu-bar search-menu] + (list 'menu-item "Isearch" isearch-menu-bar-map)) + map) "Keymap for `isearch-mode'.") +(defvar isearch-tool-bar-old-map nil + "Variable holding the old local value of `tool-bar-map', if any.") + +(defun isearch-tool-bar-image (image-name) + "Return an image specification for IMAGE-NAME." + (eval (tool-bar--image-expression image-name))) + +(defvar isearch-tool-bar-map + (let ((map (make-sparse-keymap))) + (define-key map [isearch-describe-mode] + (list 'menu-item "Help" 'isearch-describe-mode + :help "Get help for Isearch" + :image '(isearch-tool-bar-image "help"))) + (define-key map [isearch-occur] + (list 'menu-item "Show hits" 'isearch-occur + :help "Show each search hit" + :image '(isearch-tool-bar-image "index"))) + (define-key map [isearch-query-replace] + (list 'menu-item "Replace" 'isearch-query-replace + :help "Replace search string" + :image '(isearch-tool-bar-image "search-replace"))) + (define-key map [isearch-delete-char] + (list 'menu-item "Undo" 'isearch-delete-char + :help "Undo last input item" + :image '(isearch-tool-bar-image "undo"))) + (define-key map [isearch-exit] + (list 'menu-item "Finish" 'isearch-exit + :help "Finish search leaving point where it is" + :image '(isearch-tool-bar-image "exit") + :visible '(not (string-equal isearch-string "")))) + (define-key map [isearch-cancel] + (list 'menu-item "Abort" 'isearch-cancel + :help "Abort search" + :image '(isearch-tool-bar-image "close") + :filter (lambda (binding) + (if isearch-success 'isearch-abort binding)))) + (define-key map [isearch-repeat-forward] + (list 'menu-item "Repeat forward" 'isearch-repeat-forward + :help "Repeat search forward" + :image '(isearch-tool-bar-image "right-arrow"))) + (define-key map [isearch-repeat-backward] + (list 'menu-item "Repeat backward" 'isearch-repeat-backward + :help "Repeat search backward" + :image '(isearch-tool-bar-image "left-arrow"))) + map)) + (defvar minibuffer-local-isearch-map (let ((map (make-sparse-keymap))) (set-keymap-parent map minibuffer-local-map) @@ -733,6 +918,12 @@ isearch--saved-overriding-local-map (nconc minor-mode-alist (list '(isearch-mode isearch-mode)))) +;; We add an entry for `isearch-mode' to `minor-mode-map-alist' so +;; that `isearch-menu-bar-map' can show on the menu bar. +(or (assq 'isearch-mode minor-mode-map-alist) + (nconc minor-mode-map-alist + (list (cons 'isearch-mode isearch-mode-map)))) + (defvar-local isearch-mode nil) ;; Name of the minor mode, if non-nil. (define-key global-map "\C-s" 'isearch-forward) @@ -978,6 +1169,10 @@ isearch-mode isearch-original-minibuffer-message-timeout minibuffer-message-timeout minibuffer-message-timeout nil) + (if (local-variable-p 'tool-bar-map) + (setq isearch-tool-bar-old-map tool-bar-map)) + (setq-local tool-bar-map isearch-tool-bar-map) + ;; We must bypass input method while reading key. When a user type ;; printable character, appropriate input method is turned on in ;; minibuffer to read multibyte characters. @@ -1144,6 +1339,12 @@ isearch-done (setq input-method-function isearch-input-method-function) (kill-local-variable 'input-method-function)) + (if isearch-tool-bar-old-map + (progn + (setq-local tool-bar-map isearch-tool-bar-old-map) + (setq isearch-tool-bar-old-map nil)) + (kill-local-variable 'tool-bar-map)) + (force-mode-line-update) ;; If we ended in the middle of some intangible text, @@ -2486,7 +2687,10 @@ isearch-pre-command-hook ;; `set-transient-map' thingy like `universal-argument--mode'. ((not (eq overriding-terminal-local-map isearch--saved-overriding-local-map))) ;; Don't exit Isearch for isearch key bindings. - ((commandp (lookup-key isearch-mode-map key nil))) + ((or (commandp (lookup-key isearch-mode-map key nil)) + (commandp + (lookup-key + `(keymap (tool-bar menu-item nil ,isearch-tool-bar-map)) key)))) ;; Optionally edit the search string instead of exiting. ((eq search-exit-option 'edit) (setq this-command 'isearch-edit-string))