I am trying to learn how to use cl-readline
. One thing I want to do is bind the "(" key to a function, which inserts "()" and move the cursor between the two characters. I actually know how to do it with bash's bind
command:
bind '"(": "\C-q(\C-q)\C-b"'
But I have no idea how to do it with cl-readline
. So far I have tried something like:
(defun insert-paren (arg key)
(declare (ignore arg key))
(rl:insert-text "()")
(rl:insert-text (format nil "~C[1D" #\Esc)))
(rl:bind-keyseq "(" #'insert-paren)
According to https://tldp.org/HOWTO/Bash-Prompt-HOWTO/x361.html, "\033[1D" is the escape sequence to move the cursor backward.
But it does not work. It will insert the text like below, rather than move the cursor backward:
()^[[1D
cl-readline
didn't have the forward and backward char functions, which are defined in readline.
I pushed a commit that adds them (doc update and example usage there will come in the coming days).
Here's an example, adapted from cl-readline-example. We bind a key that will insert text and move the cursor, once we get a readline prompt.
(defun insert-and-move (arg key)
(rl:insert-text "()")
(rl:backward-char)) ;; edit: the 1 1 arguments are now optional.
(defun run-example ()
(rl:bind-keyseq "\\C-o" #'insert-and-move)
(rl:bind-keyseq "(" #'insert-and-move)
(rl:bind-keyseq "\\C-\(" #'insert-and-move)
(handler-case
(progn
(rl:readline :prompt "my readline > ")
… )
(run-example)
run the example:
$ sbcl --script example.lisp
now you can use (
or C-(
or C-o
to enter two ( )
and have the cursor in-between.