I’ve been using emacs to write my code and send it to the board using the emacs built in serial terminal. Emacs being lisp smart (among many other things) gives code color high lighting and parenthesis matching.
The terminal has cut and pasting as well as all the other editing features (in line mode). It takes a bit to get use too but once you establish a work flow its far supperior to the arduino serial terminal.
Emacs for programming
That sounds like a great way of working with uLisp. Would you consider writing up a bit more detail? How to get and install emacs, set it up, and what platforms it supports?
Is there a way to copy the lisp expression from the source file to the serial-term? (I mean by not using M-c, C-x o, C-y)?
I think it exists a emacs-mode which uses C-c e or something like this to evaluate the expression where the cursor is.
Do you know if it is possible to use something like this?
Emacs is an extensible (you can add to it) text editor that has been around since the dark ages of unix.
Its written in C and a dialect of lisp (elisp).
I believe emacs is cross platform, but I have no understanding of windoze or mackos so you’re on you’re own on how to install it here. On Linux its available either already installed or available in your distros repository.
Once installed I recommend doing the tutorial which is available holding down the control and h key then pressing t. Also, the resource that got me over the hump and on the road to using emacs for everything was the excellent podcasts done by Klaatu for hackerpublicradio, the links are as follows:
http://hackerpublicradio.org/eps.php?id=0852
https://hackerpublicradio.org/eps.php?id=0856
https://hackerpublicradio.org/eps.php?id=0861
listen to those and you’ll be well on your way to using emacs for all of your computing needs.
As far as using emacs for ulisp, I usually split the screen and have the serial terminal in one buffer (meta-x serial-term) and the scratch buffer in the other. I compose my code in the scratch buffer then cut and paste to the terminal there. You must be in line mode (C-c C-j) for this to work, and char mode (C-c C-k) sends the text to the device. If that doesn’t make sense, you haven’t listened to the podcasts ;) Anyway, I haven’t yet explored all the serial terminal can do or customized it in anyway but it is much more functional than the arduino terminal. Hope this helps.
In response to Kaef:
I don’t know of a way to push the code to the buffer with the the serial terminal in it, but that doesn’t mean its not possible.
Thanks for the information! There are several Mac versions of Emacs; for a good review see:
I’m use emacs serial-term
too. But instead of copy the code by hand,
i have the following snippet in my init.el
(emac’s config file):
(setq ulisp-term-buffer-name "/dev/ttyUSB0")
(defun ulisp-eval-last-expression-in-term ()
(interactive)
(let ((expr (buffer-substring-no-properties
(save-excursion (backward-sexp) (point))
(point))))
(with-current-buffer ulisp-term-buffer-name
(insert expr)
(term-send-input))))
(global-set-key (kbd "C-x e") 'ulisp-eval-last-expression-in-term)
With this snippet, i can place my cursor at the end of a expression (after the last closing “)
”)
and hit Ctrl-x e
to evaluate it (copy it in the serial-term
buffer and send it to the esp).
To test it yourself, you can copy this snippet in your *scratch*
buffer, evaluate each
expression per Ctrl-x Ctrl-e
or type M-x eval-buffer
to evaluate the whole buffer.
Maybe you need to adjust the variable ulisp-term-buffer-name
. Use the name
of your serial-term
buffer. I use Linux (so it’s /dev/ttyUSB0
) and FreeBSD (so it’s /dev/ttyU0
).
For other platforms, i have no idea.
If something is unclear, feel free to ask.
Hi,
does anyone knows how to save an emacs session including the serial-term config?
On emacs start I do:
- Ctrl-x 3 to get two buffers
- Ctrl-x o (switch to second (right) buffer)
- Meta-x serial-term (and enter device and baudrate)
- switch serial-term to line mode
- Ctrl-x o (go to left buffer)
- Ctrl-x-f (open source file)
I’d like to save the settings (I tried ‘save-desktop’ but it doesn’t seems to work) – any suggestions?
Regards,
Kaef
Hey,
put the following snippet in your init.el
(or to test it first, in your *scratch*
buffer and evaluate it per Meta-x eval-buffer
).
quick and dirty:
(defun setup-ulisp-workspace ()
(interactive)
(split-window-right)
(other-window 1)
(serial-term "/dev/ttyUSB0" 9600)
(term-line-mode)
(other-window 1)
(find-file "my-source-file"))
Then you can execute it per M-x setup-ulisp-workspace
.
The (find-file "my-source-file")
opens a predefined source-file - remove this if
you don’t want to open a predefined file.
You can “ask” emacs how you can code it yourself.
To map your described key functions to elisp functions simply type Ctrl-h k
before your keys.
Example:
- Ctrl-x 3 to get two buffer
in emacs, hit Ctrl-h k Ctrl-x 3
and you get split-window-right
- Ctrl-x o (switch to second (right) buffer)
in emacs, hit Ctrl-h k Ctr-x o
and you get other-window COUNT
and so on.
If you need some help for a function, type Ctrl-h f <function-name>
(or put your coursor under an lisp function and only type Ctrl-h f <RETURN>
.
If something is unclear, feel free to ask.
Regards, Jürgen
Hi Jürgen,
great! This is what I wanted to have, thank you very much.
emacs coding
What do you think is a good way learning emacs and elisp? What in your oppinion would be a good starting point?
I’m using emacs a while ago (a few years) but till now I’m just using basic (editing-) functions. Now I think it’s time to go deeper…
Kindly Regards,
Kaef
Hey,
sadly, i can’t recommend any specific resource.
I learned emacs by using it. And i can’t say from me, that i am an lisp hacker.
One important lesson for me was to understand, that i can ask emacs, which function, key-sequence, …
i need for my current task (type Ctrl-h ?
for help). And then simply using it - learning by doing.
I was often frustated by the complicated (for me) key-sequences. But now i use emacs
as mail client, notes, programming - so for all my tasks.
Keep using it, and with the time, the key-sequences / concepts are in your finger / brain muscle.
Regards, Jürgen
Hello, I use Emacs too, and I use inferior-lisp and lisp-mode with ulisp, it works well!
Put those code in ulisp.lisp, and load it in emacs, then you can connect to ulisp via M-x connect-to-ulisp
(or C-u M-x connect-to-ulisp
if you want to change the default serial device). And connect in a lisp-mode file buffer will make that buffer talk to ulisp (via C-x C-e
). Hope this is useful for other :)
(defvar ulisp-port-name "/dev/ttyUSB0"
"Serial port name for uLisp.")
(defvar ulisp-port-speed 9600
"Serial port speed for uLisp.")
(defun connect-to-ulisp (port speed)
"Run a uLisp serial process, input and output via buffer *ulisp*."
(interactive
(if current-prefix-arg
(list
(read-file-name "Serial port: " "/dev" ulisp-port-name)
ulisp-port-speed)
(list ulisp-port-name ulisp-port-speed)))
(with-current-buffer (make-comint-in-buffer "ulisp" "*ulisp*" nil)
(setq-local inferior-lisp-buffer "*ulisp*")
(inferior-lisp-mode))
(when (not (string-equal
"serial"
(process-type (get-buffer-process "*ulisp*"))))
(make-serial-process
:buffer "*ulisp*"
:port port
:speed speed
:noquery t))
(setq-local inferior-lisp-buffer "*ulisp*")
(pop-to-buffer "*ulisp*"))
Working around serial buffer overflow with Emacs
Thank you for this, it works well for me.
Using Emacs 28.2 on macOS 12.6, I got the error message
Symbol’s function definition is void: inferior-lisp-mode
So I had to add the following before it to make it work:
(require 'inf-lisp)
(I also had to remove SLIME, which probably interferes with inferior-lisp-mode in many ways.)
On my Linux Mint 22 system with Emacs 29.3 I set up the above Lisp code as indicated. Connecting to uLisp and using it works, but in the Emacs buffer a ^M
is appended to the end of every uLisp output line like this:
How can I get rid of the extra ^M
?
Working around serial buffer overflow with Emacs
^M
is just caret notation for #\Return
. I guess Emacs is expecting only #\Newline
for end-of-line, instead of #\Return#\Newline
which is what uLisp uses. There is probably some way to change this.
I tried adding comint-strip-ctrl-m
inside connect-to-ulisp
, either just after the call to inferior-lisp-mode
or as the very last expression of connect-to-ulisp
, but Emacs still prints the ^M
s. Interactively executing M-x comint-strip-ctrl-m
has no effect either.
Adding (add-hook 'comint-output-filter-functions #'comint-strip-ctrl-m)
to my ~/.emacs
did suppress the extra ^M
s. But it worked only once and now I always get ^M
s in the inferior Lisp buffer.
In addition, copying to the inferior Lisp some code longer than the serial buffer (preceeded by a line with one or more semicolons) and evaluating it locks the inferior Lisp Emacs buffer and uLisp, in that text typed on either is echoed but no evaluation takes place.
So far the full code in my ~/.emacs
is:
;;; uLisp
(require 'inf-lisp)
(defvar ulisp-port-name "/dev/ttyACM0"
"Serial port name for uLisp.")
(defvar ulisp-port-speed 9600
"Serial port speed for uLisp.")
(add-hook 'comint-output-filter-functions #'comint-strip-ctrl-m)
(defun connect-to-ulisp (port speed)
"Run a uLisp serial process, input and output via buffer *ulisp*."
(interactive
(if current-prefix-arg
(list
(read-file-name "Serial port: " "/dev" ulisp-port-name)
ulisp-port-speed)
(list ulisp-port-name ulisp-port-speed)))
(with-current-buffer (make-comint-in-buffer "ulisp" "*ulisp*" nil)
(setq-local inferior-lisp-buffer "*ulisp*")
(inferior-lisp-mode))
(when (not (string-equal
"serial"
(process-type (get-buffer-process "*ulisp*"))))
(make-serial-process
:buffer "*ulisp*"
:port port
:speed speed
:noquery t))
(setq-local inferior-lisp-buffer "*ulisp*")
(pop-to-buffer "*ulisp*"))
I use Emacs 29.3 on Linux Mint 22 Cinnamon.
Working around serial buffer overflow with Emacs