You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Common Lisp cl-charms报‘终端不支持颜色’错误,如何启用彩色输出?

问题:cl-charms编译时提示“Your terminal does not support color”

使用cl-charms库编写终端颜色程序时,编译阶段收到错误提示Your terminal does not support color,但终端实际支持颜色。复现代码如下:

(require 'uiop)
(load "~/.sbclrc")
(ql:quickload :cl-charms)

(defun start-color ()
  (when (eql (charms/ll:has-colors) charms/ll:FALSE)
    (error "Your terminal does not support color."))
  (let ((ret-code (charms/ll:start-color)))
    (if (= ret-code 0)
        T
        (error "start-color error ~s." ret-code))))

(eval-when (:load-toplevel :compile-toplevel :execute)
  (defconstant +black+   charms/ll:COLOR_BLACK)
  (defconstant +red+     charms/ll:COLOR_RED)
  (defconstant +green+   charms/ll:COLOR_GREEN)
  (defconstant +yellow+  charms/ll:COLOR_YELLOW)
  (defconstant +blue+    charms/ll:COLOR_BLUE)
  (defconstant +magenta+ charms/ll:COLOR_MAGENTA)
  (defconstant +cyan+    charms/ll:COLOR_CYAN)
  (defconstant +white+   charms/ll:COLOR_WHITE))

(defmacro define-color-pair ((name pair) foreground background)
  `(progn
     (start-color)
     (defparameter ,name (progn (charms/ll:init-pair ,pair ,foreground ,background)
                                (charms/ll:color-pair ,pair)))))

(define-color-pair (+white/blue+ 1) +white+ +blue+)
(define-color-pair (+black/red+ 2) +black+ +red+)

(defun draw-window-background (window color-pair)
  (charms/ll:wbkgd (charms::window-pointer window) color-pair))

(defmacro with-colors ((window color-pair) &body body)
  (let ((winptr (gensym)))
    (alexandria:once-only (color-pair)
      `(let ((,winptr (charms::window-pointer ,window)))
         (charms/ll:wattron ,winptr ,color-pair)
         ,@body
         (charms/ll:wattroff ,winptr ,color-pair)))))

(defun pretty-hello-world ()
  (charms:with-curses ()
    (charms:disable-echoing)
    (charms:enable-raw-input)
    (start-color)
    (loop named hello-world
       with window = (charms:make-window 50 15 10 10)
       do (progn
            (charms:clear-window window)
            (draw-window-background window +white/blue+)
            (with-colors (window +white/blue+)
              (charms:write-string-at-point window "Hello world!" 0 0))
            (with-colors (window +black/red+)
              (charms:write-string-at-point window "Hello world!" 0 1))
            (charms:refresh-window window)

            ;; Process input
            (when (eql (charms:get-char window :ignore-error t) #\q)
              (return-from hello-world))
            (sleep 0.1)))))

(defun main ()
  (pretty-hello-world))

(sb-ext:save-lisp-and-die "colors2.exe" :toplevel #'main :executable t)

问题原因

核心问题在于颜色对的初始化时机错误:

  • define-color-pair宏在编译/加载阶段就会执行start-color函数,而此时charms:with-curses()还未运行,curses库尚未初始化终端上下文。
  • charms/ll:has-colors需要在curses完成终端初始化后,才能正确检测终端的颜色支持能力;未初始化时会直接返回FALSE,触发错误。

解决思路

将颜色对的初始化逻辑移到charms:with-curses()上下文内部,确保在curses完成终端初始化后再执行颜色相关操作,具体有两种实现方式:

方式1:修改宏逻辑,延迟初始化

  1. 修改define-color-pair宏,只定义参数和初始化函数,不立即执行初始化:
(defmacro define-color-pair ((name pair) foreground background)
  `(progn
     (defparameter ,name nil)
     (defun ,(intern (format nil "INIT-~a" name)) ()
       (charms/ll:init-pair ,pair ,foreground ,background)
       (setf ,name (charms:ll:color-pair ,pair)))))
  1. 在pretty-hello-world的with-curses块内调用初始化函数:
(defun pretty-hello-world ()
  (charms:with-curses ()
    (charms:disable-echoing)
    (charms:enable-raw-input)
    (start-color)
    ;; 初始化颜色对
    (init-+white/blue+)
    (init-+black/red+)
    ;; 后续原有逻辑不变...

方式2:直接在上下文内初始化颜色对

去掉define-color-pair宏的自动执行逻辑,直接在with-curses块内完成颜色对初始化:

(defun pretty-hello-world ()
  (charms:with-curses ()
    (charms:disable-echoing)
    (charms:enable-raw-input)
    (start-color)
    ;; 直接初始化颜色对
    (charms/ll:init-pair 1 +white+ +blue+)
    (defparameter +white/blue+ (charms/ll:color-pair 1))
    (charms/ll:init-pair 2 +black+ +red+)
    (defparameter +black/red+ (charms/ll:color-pair 2))
    ;; 后续原有逻辑不变...

额外注意事项

  • 若编译时仍触发错误,可将颜色对初始化代码放在eval-when (:execute)块中,确保仅在程序运行时执行,而非编译阶段。
  • 确认终端的TERM环境变量设置正确(如xterm-256color),curses依赖该变量识别终端能力。

内容的提问来源于stack exchange,提问作者ben.qre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 13:38:14