Tmux etc
This commit is contained in:
parent
276853ba84
commit
1cb167b597
361 changed files with 77302 additions and 4 deletions
|
|
@ -0,0 +1,137 @@
|
|||
# Working with swank/slime
|
||||
|
||||
Since ncurses is single threaded, it is only ever allowed to call
|
||||
ncurses functions from the thread that initialized the screen. As this
|
||||
thread must be the one controlling the terminal, ncurses must only
|
||||
be called from the REPL prompt directly. With a recent enough croatoan
|
||||
version, slime/swank does work though, but it requires a bit of extra
|
||||
work. The following is an example of how one would work with croatoan
|
||||
using slime/swank. First, a bit of boiler plate:
|
||||
|
||||
```
|
||||
;; load croatoan and swank
|
||||
(eval-when (:compile-toplevel :execute :load-toplevel)
|
||||
(ql:quickload '(:croatoan :swank)))
|
||||
|
||||
;; Defining a package is always a good idea
|
||||
(defpackage #:scratch
|
||||
(:use #:cl)
|
||||
(:export #:main))
|
||||
|
||||
(in-package #:scratch)
|
||||
|
||||
;; The main screen, we need a global so that we can access it from
|
||||
;; slime
|
||||
(defparameter *scr* nil)
|
||||
|
||||
;; Main entry point, to be called from the terminal thread, it will
|
||||
;; initialize the screen and enter the event loop
|
||||
(defun main ()
|
||||
(croatoan:with-screen (scr
|
||||
;; Set input blocking to 100 ms. This _must_
|
||||
;; be set for swank to work, otherwise
|
||||
;; get-event will block and croatoan only
|
||||
;; polls the job queue when a key is pressed.
|
||||
:input-blocking 100
|
||||
;; Do not override the swank debugger hook,
|
||||
;; as we want to enter the slime debugger in
|
||||
;; emacs when a error occurs.
|
||||
:bind-debugger-hook nil)
|
||||
;; Set *scr* to the initilized scr so that we can access it form
|
||||
;; the swank thread and then enter the event-loop.
|
||||
(croatoan:run-event-loop (setf *scr* scr))))
|
||||
|
||||
;; Initialize swank, setting dont-close will prevent the server from
|
||||
;; shutting down in case slime disconnects. The default port is 4005,
|
||||
;; one can specify a different one with :port.
|
||||
(swank:create-server :dont-close t)
|
||||
|
||||
;; Initialize screen and enter the event loop
|
||||
(main)
|
||||
```
|
||||
|
||||
This should be saved in a file and then loaded directly from sbcl (or
|
||||
any other CL Implementation known to work with croatoan). For sbcl
|
||||
this would be (when saved to `scratch.lisp`):
|
||||
|
||||
```
|
||||
sbcl --load scratch.lisp
|
||||
```
|
||||
|
||||
The user should now see a blank terminal window with the cursor placed
|
||||
at the top left corner. Time to connect to it from slime, form within
|
||||
emacs run:
|
||||
|
||||
```
|
||||
M-x slime-connect
|
||||
```
|
||||
|
||||
Once started, we need to change into the right package, do this by
|
||||
entering (inside the SLIME repl):
|
||||
|
||||
```
|
||||
CL-USER> (in-package :scratch)
|
||||
```
|
||||
|
||||
To now run something inside the terminal thread one must use
|
||||
`CROATOAN:SUBMIT`:
|
||||
|
||||
```
|
||||
SCRATCH> (croatoan:submit (croatoan:add-string *scr* "Hey!"))
|
||||
```
|
||||
|
||||
And voila, thats the basics of working with croatoan from slime!
|
||||
The next thing one might want to do is set some keybindings, for
|
||||
example, bind `c` to clear the screen:
|
||||
|
||||
```
|
||||
SCRATCH> (croatoan:submit
|
||||
(croatoan:bind *scr* #\c (lambda (win event)
|
||||
(croatoan:clear *scr*))))
|
||||
```
|
||||
|
||||
And `q` to quit the event loop:
|
||||
|
||||
```
|
||||
SCRATCH> (croatoan:submit
|
||||
(croatoan:bind *scr* #\q 'croatoan:exit-event-loop))
|
||||
```
|
||||
|
||||
There is one caveat though, `*STANDARD-OUTPUT*` differs between the
|
||||
swank and the terminal thread. It is set to the swank output stream
|
||||
(which prints everything to the slime repl) inside the swank thread,
|
||||
and bound to the terminal stdin/stdout inside the terminal
|
||||
thread. Hence doing the following, would mess up the terminal screen
|
||||
instead of printing to the slime repl:
|
||||
|
||||
```
|
||||
SCRATCH> (croatoan:submit (format t "Hellou!~%"))
|
||||
```
|
||||
|
||||
What we need is a way to refer to the swank stream, which can be easily
|
||||
achieved by setting another global to whatever stream
|
||||
`*STANDARD-OUTPUT*` points to inside the slime repl:
|
||||
|
||||
```
|
||||
SCRATCH> (defparameter *swank-output* *standard-output*)
|
||||
```
|
||||
|
||||
If we now run:
|
||||
|
||||
```
|
||||
SCRATCH> (croatoan:submit (format *swank-output* "Hellou!~%"))
|
||||
```
|
||||
|
||||
We should see `Hellou!` printed in the slime repl.
|
||||
|
||||
This is quite helpful, especially when debugging something within the
|
||||
terminal thread:
|
||||
|
||||
```
|
||||
SCRATCH> (croatoan:submit
|
||||
(croatoan:bind *scr* :resize
|
||||
(lambda (win event)
|
||||
(format *swank-output* "Terminal resized to width: ~a, height: ~a~%"
|
||||
(croatoan:width win)
|
||||
(croatoan:height win)))))
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue