Enabling autocomplete in sbcl - autocomplete

I have recently started to learn lisp, and have mainly bin using clisp and vim. I wanted to try sbcl as well, since this is often recommended as one of the best, free lisp compilers. There is one thing, though, which makes sbcl more difficult to use for me: I can not get autocomplete in the REPL, which I do have in clisp. That is, when I start sbcl and type the following (as an example),
* (requi<tab>
where <tab> is the literal tab character, I do not get a list of completions, but rather a verbose tab character. In clisp, <tab> will complete the previous line to * (require.
As I am fairly new to lisp, the autocomplete functionality in clisp is really handy, so it would really be very convenient if anyone could explain how to get it in sbcl as well.

One way of getting an autocompleting repl in SBCL is to use linedit, from http://common-lisp.net/project/linedit/. A second is to use rlwrap, a readline wrapper, with a suitable completions file. (I think it's fair to say that neither of these is as commonly used as emacs, which of course also provides a completing REPL with a number of other useful features.)

I don't know of a way to get an auto-completing REPL in SBCL, but I find that interfacing with my lisp environment from within SLIME is quite handy and at that point, you can use C-c C-i for auto-completion.

Actually it's completely possible. Yes, You want to work with Common Lisp via Emacs and Slime (I prefer SLY). But it's another wall beginners hit.
You want to just play from the REPL?
The following instructions allow autocomplete in SBCL with rlwrap.
https://www.cliki.net/CMUCL%20Hints
1) install rlwrap
2) create shell alias, for example putting text like
alias rs="rlwrap sbcl"
into your ~/.bashrc (or ~/.profile or whatever).
(or you can continue calling sbcl rlwrapped via "rlwrap sbcl")
3)Edi Weitz created a completion list file that is now gone from his website, so i'm linking to the Internet Archive. save this wordlist into a file "sbcl"
https://web.archive.org/web/20031207221537/http://weitz.de/files/cmucl_completions
4)You can try putting the file according to the instructions on Cliki, this will only apply for the user you are logged in under. I wanted it to work for all users, so I put the "sbcl" file into my rlwrap completion directory, which is in
/usr/share/rlwrap/completions/
So now I have a file /usr/share/rlwrap/completions/sbcl
That contains the words.
5)Create / adjust
~/.inputrc file add the line
TAB: complete
5) Done, now in a new terminal (or after reloading .bashrc)
I can launch SBCL via rlwrap with the alias "rs"
start typing (def (or whatever) and hit TAB, and get auto-completion suggestions.
Beginner Bonus - if you want to edit lisp in the terminal, from the REPL, in say, vim with parinfer, try magic-ed, which will allow you to edit files from the repl. Configuring SBCL to use ED is esoteric. This solves that issue for You.
https://github.com/sanel/magic-ed
With tab auto-completion and convenient way to edit lisp from the terminal, one can start learning Common Lisp in the terminal.

If you want to use sbcl, emacs and slime, follow this Modern Common Lisp on Linux tutorial. The tutorial mentions installing quicklisp and especially (ql:quickload "quicklisp-slime-helper"), an elispscript which getting slime to do autocomplete and more.

Related

Use mit-scheme with REPL and editor together

I'm going through SICP course and as recommended installed mit-scheme. I want to use the REPL together with a scheme file. The reason is because I can add scheme code in the file and then run the commands in REPL. What I have works, but the problem is every time I edit the file, I have to quit terminal and reload the file for REPL to see changes.
Is there a way to reload the file easily or some other way for REPL to see changes from the file?
This my setup:
I installed mit-scheme with brew install mit-scheme
I have a local file named code.scm
In terminal, I load the file with mit-scheme --load /Users/name/Desktop/code.scm
Terminal now starts the REPL and everything works. The problem is that if I add new code to the file code.scm, I have to quit terminal and call this again: mit-scheme --load /Users/name/Desktop/code.scm
System details:
macOS Catalina - 10.15.6
Default Mac Terminal app - Version 2.10
MIT/GNU Scheme running under OS X
The text editor I use is Atom - 1.50.0
Question Edit #1 (Based on answer below)
I tried following instructions but this is complicated.
This is what I did:
Run mit-scheme < /Users/Desktop/code.scm
After this I ran mit-scheme --edit to open Edwin. I tried to use the code inside of the code.scm file but it doesn't recognize it. This is the code in code.scm file:
This is what I want to be able to do:
Notice in this picture, I can type a command, press enter and it automatically runs command. However, I want to be able to call (fib 5) and it references the function in code.scm file.
Could someone explain step by step how to do this? It's confusing looking at documentation for scheme websites.
There's actually a built-in load procedure available in the MIT Scheme REPL.
Evaluating
(load "path/to/file.scm")
causes the Scheme file located at path/to/file.scm to be evaluated at the top level (note that the double quotes around the file name are required).
And, as it turns out, this same function can be used to reload a file.
With this in mind, a possible "workflow" might look like this:
Create new source file
Evaluate (load "path/to/file.scm") in the REPL
Edit source file
Evaluate (load "path/to/file.scm") in the REPL
...etc.
Unfortunately, I don't think there is a built-in "reload" procedure.
But...if you find yourself reloading a lot (as I imagine you will), you can always quickly write your own at the beginning of a hacking session:
(define (reload)
(load "path/to/file.scm"))
And then just call (reload) whenever you make a change to your source file.
If you're interesting in using Emacs, I'd say it's worth a shot.
There's a bit of a learning curve, but it's not as steep as it looks up front :)
Also, I cannot recommend the Racket programming language(s) enough.
There is an incredibly straightforward way to set it up for SICP, and it's a much more forgiving environment than Emacs.
Let me know if you are interested and want any help getting started.
You should use emacs with xscheme.el. It works much better.
If you continue as you do, you can also do mit-scheme < code.scm or mit-scheme --edit code.scm and you will also get a *repl* buffer inside edwin.
I recommend you the emacs way, however.
A (load "/path/to/file") command should be available to you within MIT Scheme and the Edwin editor it comes with. However, I would actually recommend that you use Emacs, and use Geiser within that to access both the REPL and to help with scheme file editing. It also makes dealing with various Scheme REPLs such as Chez Scheme, Racket, MIT Scheme, Guile, Chicken, Gambit and Chibi Scheme fairly effortless. The same (load "/path/to/file") command would then be available to you within the REPL running under Geiser, within Emacs, but is generally much more powerful and seamless than when using the "naked" REPL. Emacs is very well tuned to use with Scheme and LISP. Highly recommended.
Evaluate entire buffer: press M-o (M is Alt on Windows). When in source file window, press it. It will evaluate the entire buffer i.e. (re)load the entire source file (without even saving it first). I found it by googling "mit scheme edwin tutorial". Edwin is kind of Emacs itself.
This page says: "C-c C-s when done in a scheme-mode buffer [i.e. Scheme source file window], will switch to the Scheme interaction buffer [i.e. REPL]". i.e. you press C-x C-s to save file, M-o to evaluate (i.e. load), C-c C-s to switch to the REPL.
If you've split your screen with C-x 2 between a source file buffer and the REPL ("interactions buffer"), you can switch between them by pressing C-x o (for "go to the other window").

when setting up "Slime" in "emacs"(latest version) how do i tell it to load swank faster?

the slime manual says this:
"Loading Swank faster
For SBCL, we recommend that you create a custom core file with socket support and POSIX
bindings included because those modules take the most time to load. To create such a core,
execute the following steps:
shell$ sbcl
*(mapc ’require ’(sb-bsd-sockets sb-posix sb-introspect sb-cltl2 asdf))
*(save-lisp-and-die "sbcl.core-for-slime")
After that, add something like this to your ‘.emacs’:
(setq slime-lisp-implementations
’((sbcl ("sbcl" "--core" "sbcl.core-for-slime"))))"
I know how to add stuff to my .emacs file but what exactly do i do for the part below i\e where, exactly, and how do i execute the steps below....i\e where do i type it.
"execute the following steps:
shell$ sbcl
* (mapc ’require ’(sb-bsd-sockets sb-posix sb-introspect sb-cltl2 asdf))
* (save-lisp-and-die "sbcl.core-for-slime")"
please be specific ...I'm a noob
I know how to add stuff to my .emacs file but what exactly do i do for
the part below i\e where, exactly, and how do i execute the steps
below....i\e where do i type it. "execute the following steps:
You start up your Lisp implementation in a shell, and enter in its REPL. While Slime is a Common Lisp (and a few languages more) environment for Emacs, the actual CL implementation is not included or part of Emacs. (Emacs itself uses a somewhat similar but different dialect, Emacs Lisp.)
So, you have to install SBCL separately, start it, and then enter the commands above in its REPL.
(mapc #'require '(sb-bsd-sockets sb-posix sb-introspect sb-cltl2 asdf))
Note that you have to use ', not ’ for it to work. This will load the systems in your Lisp image, and:
(save-lisp-and-die "sbcl.core-for-slime")
will save that image into the file sbcl.core-for-slime. When you tell SBCL to use that image (also called core image), you won't have to load the above systems again, because they are already part of the loaded image. That's what the
(setq slime-lisp-implementations
'((sbcl ("sbcl" "--core" "sbcl.core-for-slime"))))
in your .emacs does – it tells SLIME to use the command sbcl --core sbcl.core-for-slime when starting SBCL.
Also note, that Common Lisp is the name of the language, while CLISP is just an implementation, like SBCL. I'll retag your question accordingly.
Shell is a command-line interface to your computer. In Emacs, you may get to a shell by entering M-xshell (ie., pressing these keys in sequence: EscxshellEnter). A new window will come up, and in it a shell prompt waiting for your input. Enter sbcl at the prompt to start SBCL; you may then enter the lisp code snippets to create a new core.
For the above to work, you have to have SBCL installed first (eg, by following the instructions at www.sbcl.org).

How to get SLIME to autocomplete symbols from loaded other packages?

I think this used to work out of the box in Emacs 23, but in 24 it doesn't.
So, suppose I have Alexandria package loaded with Quicklisp. If I run (apropos "curry") in the REPL, for example, it finds the function definition, similarly, if I run (describe 'curry) etc. But SLIME refuses to autocomplete (cur| (point is shown by pipe) to anything.
How to tell SLIME where to look for sources / what is it missing?
EDIT:
Also, if I do ,in-packageRETALEXANDRIARET it will autocomplete, but I hoped it would autocomplete for any loaded package w/o me having to specify what package to look in. Or is there no other way?
There is no way that I know of to do this in SLIME. I'm not sure it would be practical to use but it should be feasible to implement this by looking at how completion and apropos are implemented and mix them up in a new function. Bonus points for a customize-var to toggle completion style.
https://github.com/slime/slime

Scala REPL in Emacs

I like to do my Scala development in Emacs, and from time to time, I use the REPL to test out snippets of code or to load and test some code I've just written. I'm using Scala 2.9.1, and I've noticed that when I open the REPL in a terminal buffer, things are substantially broken. In particular, I am unable to remove any characters from the current line, and cannot move the cursor backward on the current line. This is highly frustrating as any time I mistype something, I have to begin the command anew. I was wondering if anyone else is having this problem using the Scala REPL under Emacs, and if anyone has a potential solution.
I find that rlwrap (readline wrapper) plays well with emacs' ansi-term and scala. Just call "rlwrap scala", and you'll have the usual bash line editing, as well as history, working properly. As a bonus, your history will span multiple invocations of scala, so you won't lose everything you've typed after exiting the Scala REPL.
If rlwrap doesn't work for you, just switching to line-mode in ansi-term (C-x C-j by default) will allow you to use emacs-style editing on the line, but without the shell niceties like history and completion.
Ensime has already been mentioned, so I'll just second that as a great option if you don't mind the setup involved.
You may install ENSIME and follow instructions. I don't know about your way to invoke REPL, but REPL called from ENSIME works (it allows moving the cursor backward and deleting symbols, I've checked).
You could try using the ammonite repl, amm. I can confirm tab completion works in the emacs ansi-term. This is true for its default mode (based on stty) or you can use JLine3 with amm. Note that the Dotty (tentative Scala 3) repl, dotr, is also based on amm and also has working tab-completion in ansi-term.

What program can help a REPL shell remember and search history?

I'm playing with Paul Graham's arc, and it's getting really annoying that the up arrow inserts ^[[A instead of the previous command, and ^R doesn't work as in shell. I vaguely remember there being a simple way to run Arc's REPL in a program which will remember the input history - does anyone know what it is?
Perhaps you're thinking of rlwrap?
I like rlwrap too, but other options include:
Emacs modes:
shell
term
comint
Slime (works with Common Lisps and Clojure, probably not with Arc)
ssfe (the frontend part of sirc)
jline (especially if the REPL is written in Java, which arc is not)
nex3's arc on github comes with a script arc.sh which calls rlwrap by default, and an emacs mode to use the history with alt+P and alt+N.