RSS Feed

Lisp Project of the Day


You can support this project by donating at:

Donate using PatreonDonate using Liberapay

Or see the list of project sponsors.


Tests 🥺
CI 🤨

Two days ago I reviewed the cl-ncurses. CL-Charms is also a binding to ncurses, but uses more universal and portable CFFI instead of UFFI.

By the way, LEM (Common Lisp Emacs) uses cl-charms for it's console backend.

CL-Charms provides a high-level API besides a low level. I've ported my previous echo program to it:

(defun main (&rest argv)
  (declare (ignorable argv))
  (with-curses ()
    (enable-extra-keys *standard-window*)

    (write-string-at-cursor *standard-window*
                            "Type any character to see it in bold:

    (let ((ch (get-char *standard-window*)))

        ((eql ch (code-char 265))
         (write-string-at-cursor *standard-window*
                                 "F1 Key pressed"))
         (write-string-at-cursor *standard-window*
                                 "The pressed key is ")

         (cl-charms/low-level:attron cl-charms/low-level:a_bold)
         (write-string-at-cursor *standard-window*
                                 (format nil "~A~%" ch))
         (cl-charms/low-level:attroff cl-charms/low-level:a_bold)))

      (get-char *standard-window*))))

Interesting that cl-charms/low-level package can be used as a drop-in replacement for cl-ncurses and my second example worked without any changes except a change in the use clause.

A few words about portability


I must admit, that working with such kind of bindings can be problematic. For example, I haven't any problems using neither cl-ncurses nor cl-charms on OSX, but there was a problem with starting an example program on Ubuntu Bionic.

On Ubuntu cl-ncurses is unable to find and you have to load it manually like that:

;; These paths are harcoded in the cl-ncurses:
(defvar *ncurses-search-paths*
  #-win32'("/usr/local/lib64/" "/usr/local/lib/" "/lib64/" "/lib/" "/usr/lib64/" "/usr/lib/")

;; On Ubuntu Bionic you have to add this
;; before cl-ncurses initscr call:
(uffi:load-foreign-library "/lib/x86_64-linux-gnu/"
                           :module "cl-ncurses")


CL-Charms has another problem. It requires the libncurses5-dev package to be installed on Ubuntu. Without that, it has problem when compiling the CFFI Grovel's files:

; cc -o /root/.cache/common-lisp/sbcl-1.5.6-linux-x64/root/.roswell/lisp/quicklisp/dists/quicklisp/software/cl-charms-20200218-git/src/low-level/curses-grovel__grovel-tmpBF3HHBTQ.o -c -g -Wall -Wundef -Wsign-compare -Wpointer-arith -O3 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Wunused-parameter -fno-omit-frame-pointer -momit-leaf-frame-pointer -fno-pie -fPIC -I/root/.roswell/lisp/quicklisp/dists/quicklisp/software/cffi_0.21.0/ /root/.cache/common-lisp/sbcl-1.5.6-linux-x64/root/.roswell/lisp/quicklisp/dists/quicklisp/software/cl-charms-20200218-git/src/low-level/curses-grovel__grovel.c
/root/.cache/common-lisp/sbcl-1.5.6-linux-x64/root/.roswell/lisp/quicklisp/dists/quicklisp/software/cl-charms-20200218-git/src/low-level/curses-grovel__grovel.c:6:10: fatal error: ncurses.h: No such file or directory
 #include <ncurses.h>
compilation terminated.
Unhandled CFFI-GROVEL:GROVEL-ERROR in thread #<error printing a SB-THREAD:THREAD: #<PRINT-NOT-READABLE {10042938A3}>>: Subprocess #<UIOP/LAUNCH-PROGRAM::PROCESS-INFO {100428DCF3}>
 with command ("cc" "-o" "/root/.cache/common-lisp/sbcl-1.5.6-linux-x64/root/.roswell/lisp/quicklisp/dists/quicklisp/software/cl-charms-20200218-git/src/low-level/curses-grovel__grovel-tmpBF3HHBTQ.o" "-c" "-g" "-Wall" "-Wundef" "-Wsign-compare" "-Wpointer-arith" "-O3" "-D_LARGEFILE_SOURCE" "-D_LARGEFILE64_SOURCE" "-D_FILE_OFFSET_BITS=64" "-Wunused-parameter" "-fno-omit-frame-pointer" "-momit-leaf-frame-pointer" "-fno-pie" "-fPIC" "-I/root/.roswell/lisp/quicklisp/dists/quicklisp/software/cffi_0.21.0/" "/root/.cache/common-lisp/sbcl-1.5.6-linux-x64/root/.roswell/lisp/quicklisp/dists/quicklisp/software/cl-charms-20200218-git/src/low-level/curses-grovel__grovel.c")
 exited with error code 1

Backtrace for: #<SB-THREAD:THREAD "main thread" RUNNING {10004F04C3}>
0: (SB-DEBUG::DEBUGGER-DISABLED-HOOK #<CFFI-GROVEL:GROVEL-ERROR "~a" {1004291F73}> #<unused argument> :QUIT T)

Possible Solution?

Probably, @borodust's claw and bodge-blobs-support can solve these issues?

Brought to you by 40Ants under Creative Commons License