Often there is a function which then asks for another keystroke to determine how to act. Examples for this are the cdlatex functions cdlatex-math-modify
, cdlatex-environment
, or the reftex function reftex-reference
. (I think it reads the keystroke with the readchar
.)
I want to write an elisp-expression, which calls the function and then "presses the key", such that the function does its behavior in the special case.
e.g. I want to write a function called vec
which, when evaluated, does the same thing, as cdlatex-math-modify
when I press >
next.
.
Edit: If this helps, here is the code for two functions, in which this is used. I think the important thing is that the char is read by readchar
or read-char-exclusive
. Because a person in a comment pointed out it is good to see the implementation in elisp code, here is the full code.
First for the function reftex-select-with-char
:
(defun reftex-select-with-char (prompt help-string &optional delay-time scroll)
;; Offer to select something with PROMPT and, after DELAY-TIME seconds,
;; also with HELP-STRING.
;; When SCROLL is non-nil, use SPC and DEL to scroll help window.
(let ((char ?\?))
(save-window-excursion
(catch 'exit
(message "%s (?=Help)" prompt)
(when (or (sit-for (or delay-time 0))
(= ?\? (setq char (read-char-exclusive))))
(reftex-kill-buffer "*RefTeX Select*")
(switch-to-buffer-other-window "*RefTeX Select*")
(insert help-string)
(goto-char 1)
(unless (and (pos-visible-in-window-p (point-min))
(pos-visible-in-window-p (point-max)))
(enlarge-window (1+ (- (count-lines (point-min) (point-max))
(reftex-window-height)))))
(setq truncate-lines t))
(if (and (pos-visible-in-window-p (point-min))
(pos-visible-in-window-p (point-max)))
nil
(setq prompt (concat prompt (if scroll " (SPC/DEL=Scroll)" ""))))
(message "%s" prompt)
(and (equal char ?\?) (setq char (read-char-exclusive)))
(while t
(cond ((equal char ?\C-g) (keyboard-quit))
((equal char ?\?))
((and scroll (equal char ?\ ))
(condition-case nil (scroll-up) (error nil))
(message "%s" prompt))
((and scroll (equal char ?\C-? ))
(condition-case nil (scroll-down) (error nil))
(message "%s" prompt))
(t (message "")
(reftex-kill-buffer "*RefTeX Select*")
(throw 'exit char)))
(setq char (read-char-exclusive)))))))
For the Function cdlatex-math-modify
we have: (They key is read by readchar
. The source is https://github.com/cdominik/cdlatex/blob/master/cdlatex.el)
defun cdlatex-math-modify (arg)
"Modify previous char/group/macro with math accent/style.
This macro modifies the character or TeX macro or TeX group BEFORE point
with a math accent or a style.
If the character before point is white space, an empty modifying form
is inserted and the cursor positioned properly.
If the object before point looks like word, this macro modifies the last
character of it.
All this happens only, when the cursor is actually inside a LaTeX math
environment. In normal text, it does just a self-insert.
The accent and style commands and their properties are defined in the
constant `cdlatex-math-modify-alist'."
(interactive "P")
(catch 'exit
(let ((inside-math (cdlatex--texmathp))
(win (selected-window))
char (help-is-on nil) ass acc rmdot it cmd extrabrac)
(catch 'exit1
(save-window-excursion
(while t
(if help-is-on
(progn
(cdlatex-turn-on-help
"AVAILABLE MODIFIERS. (?=SCROLL)"
(if inside-math 1 2)
cdlatex-math-modify-alist-comb help-is-on t)
(message "Math modify: "))
(message "Math modify: (?=HELP)"))
(if (and (not help-is-on)
(sit-for cdlatex-auto-help-delay))
(setq char ?\?)
(setq char (read-char)))
(cond
((= char ?\C-g)
(keyboard-quit))
((= char ?\?)
(if help-is-on
(progn
(setq help-is-on (+ help-is-on (- (window-height) 1)))
(if (> help-is-on (count-lines (point-min) (point-max)))
(setq help-is-on 1)))
(setq help-is-on 1)))
((equal char cdlatex-math-modify-prefix)
(select-window win)
(insert cdlatex-math-modify-prefix)
(message "")
(throw 'exit t))
(t (throw 'exit1 t))))))
(message "")
(setq ass (assoc char cdlatex-math-modify-alist-comb))
(if (not ass)
(progn
(insert cdlatex-math-modify-prefix char)
(throw 'exit t)))
(setq ass (cdr ass))
(setq cmd (nth (if inside-math 0 1) ass))
(setq acc (nth 2 ass))
(setq rmdot (nth 3 ass))
(setq it (nth 4 ass))
(if (not cmd) (error "No such modifier `%c' %s math mode" char
(if inside-math "inside" "outside")))
(cond
((cdlatex-region-active-p)
(let ((beg (min (region-beginning) (region-end)))
(end (max (region-beginning) (region-end))))
(goto-char end)
(point-to-register ?x)
(goto-char beg)
(insert "{")
(if acc (forward-char -1))
(insert cmd)
(if (not acc) (insert " "))
(register-to-point ?x)
(insert "}")))
(arg
(point-to-register ?x)
(backward-word arg)
(insert "{")
(if acc (forward-char -1))
(insert cmd)
(if (not acc) (insert " "))
(register-to-point ?x)
(insert "}"))
((or (bolp)
(not cdlatex-modify-backwards)
(memq (preceding-char) '(?\ ?$ ?- ?{ ?\( )))
;; Just insert empty form and position cursor
(if acc
(insert cmd "{?")
(insert "{" cmd " ?"))
(if it (insert "\\/"))
(insert "}")
(search-backward "?")
(delete-char 1))
(t
;; Modify preceding character or word
(point-to-register ?x)
(if (= (preceding-char) ?\})
;; its a group
(progn (setq extrabrac nil)
(backward-list 1)
(if (not acc) (forward-char 1)))
;; not a group
(forward-char -1)
(if (looking-at "[a-zA-Z]")
;; a character: look if word or macro
(progn
(setq extrabrac t)
(re-search-backward "[^a-zA-Z]")
(cond
((= (following-char) ?\\))
((not inside-math) (forward-char 1))
(t (register-to-point ?x)
(forward-char -1)
(if (and rmdot (looking-at "[ij]"))
(progn (insert "\\")
(forward-char 1)
(insert "math")
(point-to-register ?x)
(forward-char -6))))))
(setq extrabrac t)))
(if extrabrac (progn (insert "{")
(if acc (forward-char -1))))
(insert cmd)
(if (not acc) (insert " "))
(register-to-point ?x)
(if extrabrac (insert "}")))))))
readchar
was enough. Now I have added the full source code of the relevant functions. Thank you for answering!interactive
spec), and then see where the result of reading is used. Typically, when used interactively a command reads something in theinteractive
spec and passes what was read as an argument. If that's the case then you can just pass the value you want as that arg to the function.