Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add mode: REPL history commands (M-p etc.) insert, not replace. #823

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

slburson
Copy link

The REPL history commands (M-p/M-n) do not work the way I prefer. After I've evaluated a top-level form, I frequently want to wrap it in some more calls and evaluate it again. (Yes, I know about the * variables, but I don't always like to use them; the expression I want to wrap and re-evaluate may not be one of the last three I entered, or maybe I just don't want to deal with the context sensitivity.) What I like to be able to do is to type the new calls first, then pull up the desired form from the history, such that it's inserted at point, then hit Enter. I use Paredit, so I shouldn't even need to type any close-parens. For example, given

CL-USER> (foo)
"Value of foo"
CL-USER>

I want to be able to type ( b a r Space M-p Enter to evaluate (bar (foo)).

The existing commands do not support this usage; if I type anything before doing M-p, that is automatically taken as a search string. I can disable that by doing C-Space C-u M-p, but then I lose the close paren(s) following point that Paredit inserted for me; I have to put them back manually, which in my configuration requires typing C-q before each one.

The changes in this PR are to support my preferred usage model. They are conditioned on a new custom variable, slime-repl-history-recall-mode, which defaults to replace so that the standard behavior is unchanged. When it's set to insert, though, automatic searching is turned off, and recalled history elements are inserted at point without deleting any of the user's text. (Of course one can still use M-r to search.)

Comment on lines 978 to 994
(defun slime-repl-history-replace (direction &optional regexp)
"Replace the current input with the next line in DIRECTION.
(defun slime-repl-history-recall (direction &optional regexp)
"Recall the next history entry in DIRECTION.
Replace the current input with it if SLIME-REPL-HISTORY-RECALL-MODE
is REPLACE, or just insert it at point if this mode is INSERT.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I renamed this since it no longer necessarily replaces.

@stassats
Copy link
Member

That is a somewhat confusing option to have, can you achieve the behavior you want by adding an advice for slime-repl-replace-input?

@slburson
Copy link
Author

slburson commented Apr 24, 2024

For my own use, I don't really care whether you merge the PR; I can run my forked version. But I expect other Paredit users will appreciate this option. (If you do merge it, I will add a note here to help people discover the feature.)

Also, if you try the insert mode, I think you'll find that what it does is very simple. It's just like C-y/M-y. It's also how Franz Allegro ELI has always worked (I used it for many years).

@luismbo
Copy link
Member

luismbo commented Apr 24, 2024

FWIW, this has been proposed before: #184

I wonder if this feature could be offered as independent interactive commands?

This refactors the functionality so that instead of one custom
variable, 'slime-repl-history-recall-mode', there are now two,
'slime-repl-history-autosearch-mode' and
'slime-repl-history-paredit-compatibility', which can be set
orthogonally.  The former controls only the behavior of M-p when the
input line is nonempty; the latter makes a few tweaks so that things
work nicely for users of ParEdit and similar balanced-parenthesis
packages.
@slburson
Copy link
Author

I've done some refactoring which I hope will make this code both more flexible and easier for users to understand. Instead of a single customization variable, slime-repl-history-recall-mode, there are now two:

  • slime-repl-history-autosearch-mode controls what happens when M-p is typed when the input line is nonempty. If it's true, the contents are used as a search string as before; if false, this behavior is disabled.
  • slime-repl-paredit-compatibility makes a few tweaks to make things work more nicely for users of ParEdit and other balanced-delimiter-editing packages.

While I was at this, I couldn't resist making it so that walking off either end of the history (unless you have history wrapping turned on) puts your input line back to the state it was in before you first typed M-p. When autosearch is on, this requires re-inserting the original text; in ParEdit compatibility mode, it even puts the trailing parens back, with point in the right place.

The other thing ParEdit compatibility mode does is to make C-c C-u kill the entire input, not just from the prompt to point, since point is rarely at the end in ParEdit mode. There may well be more such tweaks that would be desirable that I haven't noticed yet.

I did make one incompatible change to existing behavior. If you type some text and then hit M-r, the existing text is retained, and the history entry is inserted at point. Previously, the existing text was simply discarded in this case; I don't expect anybody will be especially attached to this behavior, but I could be wrong 😸

I have made some effort to test this code, but I'm not sure it's ready for merging yet.

@slburson slburson marked this pull request as draft April 25, 2024 06:20
@slburson
Copy link
Author

Oh, thanks, @luismbo. I'm glad to have @rpgoldman also agitating for this feature. Of course there are multiple ways to implement it; if it's considered preferable to do it with key rebinding rather than customization variables, I can redo it. But it seems to me that customization variables will be easier for users to find.

Resets search-in-progress when you run off the end of the history.
Lets you start from the far end of the history with an initial M-n.
Adds more special handling for the case where autosearch and
paredit-compatibility are both on.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants