[Top][All Lists]

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

Re: binding c-h in isearch

From: Juri Linkov
Subject: Re: binding c-h in isearch
Date: Sat, 19 Apr 2008 23:07:07 +0300
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.0.60 (x86_64-pc-linux-gnu)

>> I think a good binding for C-h in isearch-mode would be the following:
>>     (define-key isearch-mode-map "\C-h" help-map)
>> I gives what Richard wants since it uses the global definition of C-h,
>> and still it is intuitive to use just like its global definition when
>> a minor mode is active:
>> C-h m describes the isearch mode among other minor modes,
> Sounds good, indeed.
> Could we tweak this so it gives an info closer to what
> isearch-help-mode gives?  I.e. move the info from isearch-forward's
> docstring to isearch-mode's docstring, and tweak C-h m so that
> isearch-mode's info comes first.

I think it is useful to leave the full info on `isearch-forward' to be
helpful for `C-h k C-s' to get the full info about isearch.  But as
Johan pointed out there are other problems with this approach.

I wrote a patch that cures all there problems by using the proper
treatment of help commands in isearch mode.  It uses `make-help-screen'
to create isearch specific help screen, creates a new map `isearch-help-map'
and binds all characters to `isearch-other-control-char' (exactly as
`isearch-mode-map' binds all characters to this command before redefining
some of them in isearch mode).  This fixes the problem Johan reported, so
any character not redefined will be passed to `isearch-other-control-char'
to treat it normally and to exit isearch before invoking its global
help command.

Also I noticed another problem: when `same-window-buffer-names' or
`same-window-regexps' is redefined to display the *Help* buffer in the
same window, it makes impossible to continue using isearch in the current
window because it continues operating on the *Help* buffer in the same
window.  So it is necessary to bind `same-window-buffer-names' and
`same-window-regexps' to nil temporarily to force displaying the Help
buffer in another window.

All these changes provide the following new behavior: in isearch mode
to get isearch specific help, the user types `C-h' and sees the message:

   C-h (Type ? for further options)-

After typing `?' or `C-h' or `f1', the user sees the full help screen
with most important isearch help commands: `b', `k' and `m'.
(`c' is useless because the "I-search: " prompt overwrites the
single line displayed in the echo area by `describe-key-briefly')

These three help commands are important in isearch mode, because it is
impossible to easily get their information outside isearch mode using
global help commands.  All the rest global help commands are not isearch
specific, so e.g. `C-h f isearch-forward' gives the same info in isearch
mode as well as globally.  In isearch mode, these global help commands
will exit isearch mode and invoke their global definitions, as Richard
wants according to his comment in isearch.el.

This patch also removes the full list of all isearch commands from the
docstring of `isearch-mode' because most other modes don't have such
a list in their docstrings, and anyway this list is now available via
`C-h b'.  (Also it leaves a single sentence on its docstring, and prepends
the word "function" before the reference to `isearch-forward' in the
docstring to force this link to lead to the definition of the function,
not the variable).

Index: lisp/isearch.el
RCS file: /sources/emacs/emacs/lisp/isearch.el,v
retrieving revision 1.316
diff -c -r1.316 isearch.el
*** lisp/isearch.el     18 Apr 2008 10:29:23 -0000      1.316
--- lisp/isearch.el     19 Apr 2008 20:04:05 -0000
*** 322,327 ****
--- 322,396 ----
+ ;; Define isearch help map.
+ (eval-when-compile (require 'help-macro))
+ (make-help-screen isearch-help-for-help-internal
+   "Type a help option: [bkm] or ?"
+   "You have typed %THIS-KEY%, the help character.  Type a Help option:
+ \(Type \\<help-map>\\[help-quit] to exit the Help command.)
+ b           Display all isearch key bindings.
+ k KEYS      Display the full documentation for the isearch key sequence.
+ m           Display documentation of isearch mode.
+ You can't type here other help keys available in the global help map,
+ but outise of this help window when you type them in isearch mode,
+ they exit isearch mode before displaying global help."
+   isearch-help-map)
+ (defvar isearch-help-map
+   (let ((i 0)
+       (map (make-sparse-keymap)))
+     (while (< i 256)
+       (define-key map (vector i) 'isearch-other-control-char)
+       (setq i (1+ i)))
+     (define-key map (char-to-string help-char) 'isearch-help-for-help)
+     (define-key map [help] 'isearch-help-for-help)
+     (define-key map [f1] 'isearch-help-for-help)
+     (define-key map "?" 'isearch-help-for-help)
+     (define-key map "b" 'isearch-describe-bindings)
+     (define-key map "k" 'isearch-describe-key)
+     (define-key map "m" 'isearch-describe-mode)
+     (define-key map "q" 'help-quit)
+     map)
+   "Keymap for characters following the Help key for isearch mode.")
+ (defun isearch-help-for-help ()
+   "Display isearch help menu."
+   (interactive)
+   (let (same-window-buffer-names same-window-regexps)
+     (isearch-help-for-help-internal))
+   (isearch-update))
+ (defun isearch-describe-bindings ()
+   "Show a list of all keys defined in isearch mode, and their definitions.
+ This is like `describe-bindings', but displays only isearch keys."
+   (interactive)
+   (let (same-window-buffer-names same-window-regexps)
+     (with-help-window "*Help*"
+       (with-current-buffer standard-output
+       (princ "Isearch Mode Bindings:\n")
+       (princ (substitute-command-keys "\\{isearch-mode-map}"))))))
+ (defun isearch-describe-key ()
+   "Display documentation of the function invoked by isearch key."
+   (interactive)
+   (let (same-window-buffer-names same-window-regexps)
+     (call-interactively 'describe-key))
+   (isearch-update))
+ (defun isearch-describe-mode ()
+   "Display documentation of isearch mode."
+   (interactive)
+   (let (same-window-buffer-names same-window-regexps)
+     (describe-function 'isearch-forward))
+   (isearch-update))
+ (defalias 'isearch-mode-help 'isearch-describe-mode)
  ;; Define isearch-mode keymap.
  (defvar isearch-mode-map
*** 391,396 ****
--- 460,466 ----
      ;; Turned off because I find I expect to get the global definition--rms.
      ;; ;; Instead bind C-h to special help command for isearch-mode.
      ;; (define-key map "\C-h" 'isearch-mode-help)
+     (define-key map "\C-h" isearch-help-map)
      (define-key map "\M-n" 'isearch-ring-advance)
      (define-key map "\M-p" 'isearch-ring-retreat)
*** 575,580 ****
--- 645,654 ----
  Type \\[isearch-complete] to complete the search string using the search ring.
+ Type \\[isearch-describe-bindings] to display all isearch key bindings.
+ Type \\[isearch-describe-key] to display documentation of isearch key.
+ Type \\[isearch-describe-mode] to display documentation of isearch mode.
  If an input method is turned on in the current buffer, that input
  method is also active while you are typing characters to search.  To
  toggle the input method, type \\[isearch-toggle-input-method].  It
*** 627,638 ****
    (interactive "P\np")
    (isearch-mode nil (null not-regexp) nil (not no-recursive-edit)))
- (defun isearch-mode-help ()
-   (interactive)
-   (describe-function 'isearch-forward)
-   (isearch-update))
  ;; isearch-mode only sets up incremental search for the minor mode.
  ;; All the work is done by the isearch-mode commands.
--- 701,706 ----
*** 644,652 ****
  (defun isearch-mode (forward &optional regexp op-fun recursive-edit word-p)
!   "Start isearch minor mode.  Called by `isearch-forward', etc.
! \\{isearch-mode-map}"
    ;; Initialize global vars.
    (setq isearch-forward forward
--- 712,719 ----
  (defun isearch-mode (forward &optional regexp op-fun recursive-edit word-p)
!   "Start isearch minor mode.
! It is called by the function `isearch-forward' and other related functions."
    ;; Initialize global vars.
    (setq isearch-forward forward

Juri Linkov

reply via email to

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