4

Can I assign a key binding starting with C-s such as:

(global-set-key (kbd "C-s C-w") 'isearch-forward-symbol-at-point)

but I want to keep (kbd "C-s") for i-search.


I am having following error:

error: Key sequence C-s C-w starts with non-prefix key C-s

To ensure normal operation, you should investigate and remove the
cause of the error in your initialization file.  Start Emacs with
the ‘--debug-init’ option to view a complete error backtrace.
Tyler
  • 21,719
  • 1
  • 52
  • 92
alper
  • 1,238
  • 11
  • 30
  • This is surely a duplicate question, but I don't have the time to look it up. Hope someone will. – Drew Feb 05 '20 at 00:58
  • sure sounds like a duplicate, but I couldn't find one. Check the manual: https://www.gnu.org/software/emacs/manual/html_node/elisp/Key-Binding-Commands.html , especially the description of `global-unset-key`. A longer explanation is at the end this article: https://www.masteringemacs.org/article/mastering-key-bindings-emacs – Tyler Feb 05 '20 at 03:23
  • I changed your title to something more descriptive, I think. Change it back if you don't like it! – Tyler Feb 05 '20 at 14:44
  • Thanks, I like it :-) @Tyler – alper Feb 05 '20 at 14:48
  • @Drew this question is a more specific version of https://emacs.stackexchange.com/questions/5716/how-do-i-add-a-keybinding-to-a-keymap-that-is-on-a-prefix-key?rq=1 Should it be closed, or is it useful to have a separate question for isearch specifically? – Tyler Feb 06 '20 at 17:12
  • @Tyler: No, I don't think it's a dup of that one. That one is about binding a key in a keymap. This one is about redefining a key that's bound to a command, to bind it instead to a prefix command. Or simply how to bind a key to a prefix command. The answer involves use of `define-prefix-command` and binding the key to a keymap. (Sometimes `define-prefix-command` is not needed explicitly.) – Drew Feb 06 '20 at 23:22

2 Answers2

4

As I understand your question, you want C-s to start an interactive search, as it normally does, but if you press C-w after you've started that search, you want it to switch to isearch-symbol-at-point.

First off, the feature you're after is almost the same as the default behaviour bound to C-s C-M-w. That will call isearch-yank-symbol-or-char, which is close, but not identical to isearch-symbol-at-point. Maybe that's close enough.

If you really want to call isearch-forward-symbol-at-point, without overwriting the default behaviour of C-s, you'll need to add the new binding to the isearch-mode-map:

(define-key isearch-mode-map (kbd "C-w")
  'isearch-forward-symbol-at-point)

Note that this will overwrite the default definition of C-s C-w, which is to call the function isearch-yank-word-or-char.

The default options to isearch are described in the manual (info "(emacs) Isearch Yank")

Tyler
  • 21,719
  • 1
  • 52
  • 92
  • When I use this in emacs v28 I am seeing following error: `Wrong number of arguments: (lambda (direction) "If reversing, start the search from the other end of the current match." (if (eq isearch-forward (eq direction 'forward)) nil (if isearch-other-end (progn (goto-char isearch-other-end))))), 2` when the search is completed and come back to top of the file. Is it possible to fix it? – alper Feb 21 '21 at 20:24
  • @alper I cannot reproduce this error in Emacs 28.0.50. Have you tried starting from emacs -Q, and evaluating only the `define-key` form from my answer? I suspect there's something else in your config causing the problem. – Tyler Feb 22 '21 at 14:17
  • I found a small bug, not sure could it be related to this. On following example (https://gist.github.com/avatar-lavventura/2a26b7c64386167f86e443656d62c614) when I do C-s on top of first _PATH work it does not see the second _PATH. I think instead of capturing `_PATH` it captures `_PATH=` – alper Mar 04 '21 at 22:22
  • this matches the symbol at point, and I think in this mode both _ and = are recognized as part of a symbol name, not as punctuation. So this is the expected behaviour. To change this, you would need to use a different function, or modify the syntax classes for this mode. – Tyler Mar 05 '21 at 01:38
  • Got it seems like its `Shell-script mode` where can I find its syntax classes? – alper Mar 05 '21 at 11:28
  • @alper See `sh-mode-syntax-table`, https://www.gnu.org/software/emacs/manual/html_node/elisp/Syntax-Tables.html – Tyler Mar 05 '21 at 17:17
0

The C-s needs to be assigned as a prefix command.

eg

(define-prefix-command 'myprefix)
(global-set-key (kbd "C-s") 'myprefix)
(global-set-key (kbd "C-s C-s") 'helm-occur)
RichieHH
  • 848
  • 4
  • 9
  • I am confused I want to keep `C-s` key binding for the `isearch` @RichieHH – alper Feb 05 '20 at 10:08
  • 2
    @alper: then how is emacs to guess that you mean to type a second `C-s`? It can either be a prefix or it can be a key bound to a command, but it cannot be both. – NickD Feb 05 '20 at 12:56