Emacs key bindings in Guile REPL?

Anyone here figured how to get the guile REPL to enable Emacs key-bindings? LLM suggested changes to ~/.inputrc to specify Emacs mode but that didn’t seem to work. Also, looking at the linked libs for the guile binary suggests perhaps no readline?

This is answered within man guile [1]:

FILES

    ~/.guile

A Guile script that is executed before any other processing occurs. For example, the following .guile activates guile’s readline interface:

 (use-modules (ice-9 readline))
 (activate-readline)

Tested it on Guile 3.0.9@msys2 and 3.0.7@ubuntu, works fine :slight_smile:


  1. But I originally found the answer on StackOveflow: terminal - How to use arrow keys in mzscheme/guile REPL? - Stack Overflow ↩︎

1 Like

Correct that the guix guile package does not include readline support. Must install guile-readline and then reload the GUIX /etc/profile or just get a new login shell.

Without that package the changes to ~/.guile causes REPL to throw error at startup.

ref: Error starting Guile with `readline` support - Stack Overflow

Ah, I’m not on Guix, seems like both msys2 and Ubuntu/Debian distribute that module by default.

Or you could use guix-home to set it up :slight_smile:

And then just use

(home-environment
 # ...
 (services
  (list
   # ...
   home-guile-service)))

Previous attempts at guix-home failed. Mostly due to lack of guile experience. Working on that though.

guix shell is a better option for one-off command executions like this:

guix shell guile guile-readline -- guile

That will launch the Guile command line REPL with the guile-readline package available as a package.

I don’t know Guix custom configuration language, but doesn’t your service definition as-is not enable readline, as it is disabled by default? :sweat_smile:

For me it was not sufficient to just install the package. I also had to barf a couple of lines into a dotfile to enable. I don’t know enough about guix-home to know if that service definition is a custom thing which might include the dotfile stuff or … I’d like to know though as one of the two goals I have coming out of the guile-beginner’s course is to figure out if I want to replace stow + dotfiles with guile ecosystem tooling.

Guix Home is a lot more powerful than a plain Stow setup, but it’s also a bit more complex if the stuff you’re trying to configure doesn’t have pre-existing home services.

I currently use a mix of Stow and Guix Home because I haven’t bothered writing home services for everything yet :slight_smile:

I believe you have found a bug, because it does actually work :laughing: but you’re right, they should be off by default.

I must’ve overlooked it because this service produces the exact thing I want and didn’t question it that it worked as I wanted, not as I intended :slight_smile:

Edit: No, it was just me being stupid… home-guile-service is actually a reference to a variable somewhere else:

(define home-guile-service
  (service home-guile-service-type
           (home-guile-configuration
            (use-readline #t)
            (use-colorized #t))))

I have more than 1 machine configured with Guix Home that shares some configuration (like this) and I haven’t quite figured out how I want to do that, so I have about 3 different ways of doing it :sweat_smile:

The downside of using guix home specifically (I don’t know about other guile ecosystem tooling) is that (as far as I know) you’re dependent on Guix.

This is great for machines where I run Guix, but also means I need something else for those where I don’t :slight_smile: I haven’t quite figured out what I want yet, so yeah right now I also have a mix of Stow and guix home :slight_smile:

1 Like

In my last attempt at a guix-home config the one place where I stopped before a river crossing was because I run Debian 12 with a Guix userland binary install. I wanted to manage services but that would mean systemd and not, uh…what is it in Guix…herd. I wasn’t sure how far off the ranch I would be trying to manage systemd stuff. Note that it being possible was less of a concern than would I be nearly the only one attempting it.

Once I learn more guile perhaps I’ll wade back in and see if I make it across.

Perhaps this exists but it would be kinda cool if guix had a construct for leveraging ~/.dotfiles and stow “virtualized”. Borrowing a term from, like Puppet or Terraform, the home “Provider” could be configured to clone a repo and then do stow magic.

That would would allow ~/.dotfiles to be leveraged on less advanced ( :wink: ) OSes which do not have any guix-y tooling.

I’m able to do this in my guix shell and readline is activated once I activated in the ~/.guile file with

(use-modules (ice-9 readline))
(activate-readline)

However, I can’t get the REPL inside emacs run-geiser to pick up readline support. I didn’t see any packages for guile-readline in the package-install either. Any pointers?

Wish I could help you. In my Emacs (vanilla…no Doom etc) the Emacs key-bindings carry through after an M-x run-guile. I’m using Emacs and Guile stuff from Guix.

1 Like

That’s strange, Geiser itself should take care of REPL history for you and Emacs’ own built in key bindings should take care of the rest. As far as I know, the readline module shouldn’t be needed in the context of Geiser, only the terminal Guile REPL.

1 Like

Maybe it’s because I’m an evil user?
I can go into normal mode when I’m at the prompt and then I can use c-p and c-n to access history. But that’s it, I can’t use any other readline commands like c-a or c-e. Also I need to be exactly where the prompt is to enter back into insert mode, so that’s a bit painful.

That seems very likely to me. I’ve never actually used Evil in anger but I do seem to recall that there are certain modes where it needs to be manually adjusted. Perhaps there’s an override of some sort necessary for the REPL.

2 Likes

For anyone else stumbling here later, I just added some keybindings for evil-collection. Here’s my full snippet:

(use-package geiser-guile
  :straight t
  :after org
  :config
  (evil-collection-define-key 'normal 'geiser-repl-mode-map
	"k" 'comint-previous-input
	"j" 'comint-next-input)
  (org-babel-do-load-languages
   'org-babel-load-languages
   '((scheme . t))))

So now in normal mode I can access the previous commands entered which is the biggest thing I needed.

For org-babel here’s the src block header I’m using:

#+begin_src scheme :tangle yes :noweb yes :results output :session UniqueName

If values are not printed then the :results needs to be changed to value to see the return values. Only the last return value is shown.

1 Like