If you're not using much system calls, one simple way is to capture the byte sequences that would be sent to the terminal, and simulate the byte sequences that would be received.
Another option might be to connect it to `screen` or `tmux`, and scrape the characters and attributes from there, or feed it to a terminal GUI program like `xterm` and scrape the pixels from there. And synthesize the input to the terminal emulator.
Interesting. Lisp is hard not because of the language. I read the source code and unlike python etc it is straightforward.
but the setup is hard. Clojure setup is still a bit hard. But at least package management is
Easy. Asdf ...
The most difficult issue is it is more or less pure. Whilst the c external interface seems easier. But it is not designed from ground up as one of the language in a system. JavaScript sort of work with HTML and CSS and not dealing with this. You do have canvas. But not for simple terminal io like this.
Somehow it is kind of lost on space experience. Great language and great ecosystem. Just out there, alone and for their own kind.
But nice to read. Still find it hard to read python after writing. Even there is only one way to do so.
I was obsessed with Clojure, and getting started with the language took me so long because I couldn't figure out how to do xyz when starting a project. Eventually I gave up and started doing things shittily and it worked out. I grok a lot of the build process, and I highly recommending just taking the time to read about it and getting familiar.
It's annoying to learn about cause it's not explicitly productive, but it's worthwhile.
TXR Lisp setup is easy. If you have to build from source (not a user of a distro that has packaged it like Guix or Void, then:
./configure && make && sudo make install
Then there is a txr executable with some auto-loaded library files in /usr/share, and that's it. The txr executable performs all the sysrooting calculations so you can move an installation of it anywhere, as long as you keep the relative locations of the files the same (the installation tree shape). If you have a tarball of it, it will unpack and run from anywhere.
The documentation is all in a single man page, covering everything.
TXR is designed from the ground up as a system utility integrated well into a POSIX environment.
TXR requires no package management or build system because the load function behaves sanely. If you load a file that is located in path/to/dir, and that file itself does a (load "foo") at its own top level, then that top-level load look for path/to/dir/foo.tlo (compiled file) or path/to/dir/foo.tl (source): i.e relative to the same directory as the parent file that is being load-ed.
There is no need to mess around with irksome path schemes (look for stuff here, look for stuff there, ...). You're in the driver's seat: put the pieces you need where you want, load each of their main files, and that's it.
We can make a package just by putting some files into a directory, and documenting which one is the main one that is to be loaded. That one loads the others using relative paths, and that's that.
A module/program's main file can rebuild itself and the others like this:
(defvarl myfiles '#"main foo bar baz xyzzy") ;; word list lit, same as '("main" "foo" ...)
(each ((f myfiles))
(or (compile-update-file `@f.tl` `@f.tlo`)
(load f))
compile-update-file checks the existence and time stamps, rebuilding the .tlo if it is missing or older than the .tl file. Compilation usually has the same effect as loading, so in that case we don't have to load. If compile-update-file returns nil, then it means it did nothing; we load the existing compiled file then.
> But it is not designed from ground up as one of the language in a system.
I know exactly what you mean there; that is why I designed TXR from the ground up in the form factor of a utility that fits into the surrounding OS environment instead of being a kind of immigrant from a Lisp planet. It's Lisp, for Unix and C people -- with a decent Windows port.
As of the setup, you certainly need to spend some time to get it right the first time, but later it is easy (and it is not overwhelmingly hard for the first time either). I think that this is true for any software stack you are about to use for the first time.
7 comments
[ 2.5 ms ] story [ 31.9 ms ] thread(A terminal library I wrote, which doesn't do as much as this CL one, uses byte stream I/O almost entirely. https://www.neilvandyke.org/racket/charterm/ )
Another option might be to connect it to `screen` or `tmux`, and scrape the characters and attributes from there, or feed it to a terminal GUI program like `xterm` and scrape the pixels from there. And synthesize the input to the terminal emulator.
but the setup is hard. Clojure setup is still a bit hard. But at least package management is Easy. Asdf ...
The most difficult issue is it is more or less pure. Whilst the c external interface seems easier. But it is not designed from ground up as one of the language in a system. JavaScript sort of work with HTML and CSS and not dealing with this. You do have canvas. But not for simple terminal io like this.
Somehow it is kind of lost on space experience. Great language and great ecosystem. Just out there, alone and for their own kind.
But nice to read. Still find it hard to read python after writing. Even there is only one way to do so.
It's annoying to learn about cause it's not explicitly productive, but it's worthwhile.
The documentation is all in a single man page, covering everything.
TXR is designed from the ground up as a system utility integrated well into a POSIX environment.
TXR requires no package management or build system because the load function behaves sanely. If you load a file that is located in path/to/dir, and that file itself does a (load "foo") at its own top level, then that top-level load look for path/to/dir/foo.tlo (compiled file) or path/to/dir/foo.tl (source): i.e relative to the same directory as the parent file that is being load-ed.
There is no need to mess around with irksome path schemes (look for stuff here, look for stuff there, ...). You're in the driver's seat: put the pieces you need where you want, load each of their main files, and that's it.
We can make a package just by putting some files into a directory, and documenting which one is the main one that is to be loaded. That one loads the others using relative paths, and that's that.
A module/program's main file can rebuild itself and the others like this:
compile-update-file checks the existence and time stamps, rebuilding the .tlo if it is missing or older than the .tl file. Compilation usually has the same effect as loading, so in that case we don't have to load. If compile-update-file returns nil, then it means it did nothing; we load the existing compiled file then.> But it is not designed from ground up as one of the language in a system.
I know exactly what you mean there; that is why I designed TXR from the ground up in the form factor of a utility that fits into the surrounding OS environment instead of being a kind of immigrant from a Lisp planet. It's Lisp, for Unix and C people -- with a decent Windows port.
https://www.nongnu.org/txr/txr-manpage.html#N-0260AE30
It even supports the coreutils "stty -g" string format for saving and restoring termios settings.
As of the setup, you certainly need to spend some time to get it right the first time, but later it is easy (and it is not overwhelmingly hard for the first time either). I think that this is true for any software stack you are about to use for the first time.