The Alive extension makes VSCode a powerful Common Lisp development platform. Alive hooks directly into the Swank server that Emacs Slime uses and is fully compatible with VSCode’s ability to develop remotely in containers, WSL, Remote machines, etc. It has no dependencies beyond a version of Common Lisp running on the target platform that can run the Swank server. It currently supports:
The Alive extension in VSCode is compatible with ANSI Common Lisp, and these instructions should work for any of them as long as the Alive REPL starts up successfully. The examples all use SBCL.
hello.lisp
View/Command Palette
and start an instance of SBCL running a Swank server attached to your VSCode REPL by choosing: Alive: Start REPL And Attach
.
REPL Connected
REPL Connected
message, open up VSCode’s Output on the menu at the top where it says View:Output
and choose Swank Trace
from the pulldown. This output is the output from the running lisp image and will get you started on figuring out what might be going wrong.Congrats, You now have a VSCode instance running a REPL attached to a Swank server running on port 4005 of a running SBCL image. You can now evaluate statements in your file and they will be processed in your running SBCL instance.
To disconnect your REPL and shut down your SBCL instance, open the Command Palette on the menu at the top where it says View/Command Palette
and choose: Alive: Detach from REPL
There are keybindings for every operation, feel free to explore and modify those as needed.
RecipesAll recipes assume you have a file open in VSCode running with an attached REPL unless otherwise stated.
When evaluating an expression, you choose the expression to evaluate by putting your cursor anywhere in or immediately following the s-expression that you wish to evaluate.
Evaluate a statement in-line(+ 2 2)
View/Command Palette
and choose Alive: Inline Eval
You will see a small pop up that says => 4 (3 bits, #x4, #o4, #b100)
, which is the result
Evaluating a statement in-line is exactly the same as sending it to the REPL. The only difference is how it is displayed.
(+ 2 2)
View/Command Palette
and choose Alive: Send To REPL
CL-USER>
(+ 2 2)
4
CL-USER>
Compile a file
(+ 2 2)
View/Command Palette
and choose Alive: Compile
CL-USER>
; compiling file "/Users/jason/Desktop/hello.lisp" (written 14 SEP 2021 04:24:37 AM):
; wrote /Users/jason/Desktop/hello.fasl
; compilation finished in 0:00:00.001
Use the Interactive Debugger to abort
(defun divide (x y)
(/ x y))
View/Command Palette
and choose Alive: Inline Eval
to load your define
function into your image.(divide 1 0)
View/Command Palette
and choose Alive: Inline Eval
to run your divide function in your image.Restarts
section, choose option 2 to Abort.(defun divide (x y)
(assert (not (zerop y))
(y)
"The second argument can not be zero.")
(/ x y))
View/Command Palette
and choose Alive: Inline Eval
to load your define
function into your image.(divide 1 0)
View/Command Palette
and choose Alive: Inline Eval
to run your divide function in your image.Restarts
section, choose option 0 to “Retry assertion with new value for Y”.1
=> 1 (1 bit, #x1, #o1, #b1)
, which is the result of the new value. You’re now back to your editor and still-running REPL after crashing out into the debugger, having it let you change the value that caused the crash, and then proceeding like you never typed that bad 0
value.More ideas for what can be done with the debugger can be found on the error handling page.
Expand a macro(loop for x in '(a b c d e) do
(print x))
View/Command Palette
and choose Alive: Macro Expand
to expand the for-loop macro.(BLOCK NIL
(LET ((X NIL)
(#:LOOP-LIST-559
(SB-KERNEL:THE* (LIST :USE-ANNOTATIONS T
:SOURCE-FORM '(A B C D E))
'(A B C D E))))
(DECLARE (IGNORABLE #:LOOP-LIST-559)
(IGNORABLE X))
(TAGBODY
SB-LOOP::NEXT-LOOP
(SETQ X (CAR #:LOOP-LIST-559))
(SETQ #:LOOP-LIST-559 (CDR #:LOOP-LIST-559))
(PRINT X)
(IF (ENDP #:LOOP-LIST-559)
(GO SB-LOOP::END-LOOP))
(GO SB-LOOP::NEXT-LOOP)
SB-LOOP::END-LOOP)))
Disassemble a function
(defun hello (name)
(format t "Hello, ~A~%" name))
View/Command Palette
and choose Alive: Inline Eval
to load the function into your image.View/Command Palette
and choose Alive: Disassemble
print out the machine code of your compiled function.; disassembly for HELLO
; Size: 172 bytes. Origin: #x70052478B4 ; HELLO
; 8B4: AC0A40F9 LDR R2, [THREAD, #16] ; binding-stack-pointer
; 8B8: 4C0F00F9 STR R2, [CFP, #24]
; 8BC: AC4642F9 LDR R2, [THREAD, #1160] ; tls: *STANDARD-OUTPUT*
; 8C0: 9F8501F1 CMP R2, #97
; 8C4: 61000054 BNE L0
; 8C8: 4AFDFF58 LDR R0, #x7005247870 ; '*STANDARD-OUTPUT*
; 8CC: 4C1140F8 LDR R2, [R0, #1]
; 8D0: L0: 4C1700F9 STR R2, [CFP, #40]
; 8D4: E0031BAA MOV NL0, CSP
; 8D8: 7A0701F8 STR CFP, [CSP], #16
; 8DC: EAFCFF58 LDR R0, #x7005247878 ; "Hello, "
; 8E0: 4B1740F9 LDR R1, [CFP, #40]
; 8E4: B6FBFF58 LDR LEXENV, #x7005247858 ; #<SB-KERNEL:FDEFN WRITE-STRING>
; 8E8: 970080D2 MOVZ NARGS, #4
; 8EC: FA0300AA MOV CFP, NL0
; 8F0: DE9240F8 LDR LR, [LEXENV, #9]
; 8F4: C0033FD6 BLR LR
; 8F8: 3B039B9A CSEL CSP, OCFP, CSP, EQ
; 8FC: E0031BAA MOV NL0, CSP
; 900: 7A0701F8 STR CFP, [CSP], #16
; 904: 4A2F42A9 LDP R0, R1, [CFP, #32]
; 908: D6FAFF58 LDR LEXENV, #x7005247860 ; #<SB-KERNEL:FDEFN PRINC>
; 90C: 970080D2 MOVZ NARGS, #4
; 910: FA0300AA MOV CFP, NL0
; 914: DE9240F8 LDR LR, [LEXENV, #9]
; 918: C0033FD6 BLR LR
; 91C: 3B039B9A CSEL CSP, OCFP, CSP, EQ
; 920: E0031BAA MOV NL0, CSP
; 924: 7A0701F8 STR CFP, [CSP], #16
; 928: 2A4981D2 MOVZ R0, #2633
; 92C: 4B1740F9 LDR R1, [CFP, #40]
; 930: D6F9FF58 LDR LEXENV, #x7005247868 ; #<SB-KERNEL:FDEFN WRITE-CHAR>
; 934: 970080D2 MOVZ NARGS, #4
; 938: FA0300AA MOV CFP, NL0
; 93C: DE9240F8 LDR LR, [LEXENV, #9]
; 940: C0033FD6 BLR LR
; 944: 3B039B9A CSEL CSP, OCFP, CSP, EQ
; 948: EA031DAA MOV R0, NULL
; 94C: FB031AAA MOV CSP, CFP
; 950: 5A7B40A9 LDP CFP, LR, [CFP]
; 954: BF0300F1 CMP NULL, #0
; 958: C0035FD6 RET
; 95C: E00120D4 BRK #15 ; Invalid argument count trap
Create a skeleton Common Lisp system
This recipe creates a new Common Lisp System, so it does not need a running REPL.
experiment
for your new projectcd experiment
code .
View/Command Palette
and generate a system skeleton: Alive: System Skeleton
The content of those files is as follows:
experiment.asd
:
(in-package :asdf-user)
(defsystem "experiment"
:class :package-inferred-system
:depends-on ("experiment/src/app")
:description ""
:in-order-to ((test-op (load-op "experiment/test/all")))
:perform (test-op (o c) (symbol-call :test/all :test-suite)))
(defsystem "experiment/test"
:depends-on ("experiment/test/all"))
(register-system-packages "experiment/src/app" '(:app))
(register-system-packages "experiment/test/all" '(:test/all))
src/app.lisp
:
(defpackage :app
(:use :cl))
(in-package :app)
test/all.lisp
:
(defpackage :test/all
(:use :cl
:app)
(:export :test-suite))
(in-package :test/all)
(defun test-suite ()
(format T "Test Suite~%"))
Optional Custom Configurations Configuring VSCode Alive to work with Quicklisp
Assuming that you have quicklisp installed and configured to load on init, quicklisp just works.
Configuring VSCode Alive to work with CLPM in the default contextAssuming that you have CLPM installed and configured, modify your vscode settings to look like this:
"alive.swank.startupCommand":[
"clpm",
"exec",
"--",
"sbcl",
"--eval",
"(asdf:load-system :swank)",
"--eval",
"(swank:create-server)"
],
This will start up sbcl in the default clpm context
Configuring VSCode Alive to work with CLPM using a bundle clpmfileAssuming that you have CLPM installed and configured and a bundle configured in the root of your home directory that contains swank as a dev dependency, modify your vscode settings to look like this:
"alive.swank.startupCommand":[
"clpm",
"bundle",
"exec",
"--",
"sbcl",
"--eval",
"(asdf:load-system :swank)",
"--eval",
"(swank:create-server)"
],
This will start up sbcl in your bundle’s clpm context
Configuring VSCode Alive to work with RoswellAssuming that you have Roswell installed, modify your vscode settings to look like this:
"alive.swank.startupCommand": [
"ros",
"run",
"--eval",
"(require :asdf)",
"--eval",
"(asdf:load-system :swank)",
"--eval",
"(swank:create-server)"
]
Connecting VSCode Alive to a Docker container
These instructions will work for remote connections, wsl connections, and github Codespaces as well using the Remote - SSH
and Remote - WSL
, and Github Codespaces
extensions, respectively assuming you have the extensions installed. For this example, make sure you have the Containers extension installed and configured.
docker pull clfoundation/sbcl
docker run -it clfoundation/sbcl bash
Remote Explorer
icon.Attach to Container
.Explorer
. You may need to tell it to view the files in your container if it isn’t already showing them.Side Bar
and choose New File
. Name the file hello.lisp
Extensions
iconInstall in Container...
button for the Alive
pluginhello.lisp
file and follow the “Connect VSCode to a REPL” instructions at the beginning of these recipesPage source: vscode-alive.md
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4