+
Skip to content

Conversation

mushkevych
Copy link
Contributor

@mushkevych mushkevych commented Aug 16, 2025

plan9: add minimal Plan 9 backend for tcell (raw /dev/cons, resize via /dev/wctl, terminfo screen)

Summary

This PR introduces limited Plan 9 support for tcell behind build tags, enabling tcell-based applications (e.g., tview/cview) to compile and run on Plan 9 under vt(1) (VT100 emulator). The implementation uses Plan 9’s native console and window-control files to provide raw input, output, and resize notifications, while reusing tcell’s existing terminfo screen path.

Scope: No behavioral changes on non-Plan9 platforms. Public API is unchanged except for Plan 9–specific implementations.


Motivation

Upstream currently documents Plan 9 as unsupported. This PR provides a clean, low-risk baseline that:

  • lets Plan 9 users build and run tcell apps in a console window,
  • isolates all Plan 9 code via //go:build plan9,
  • preserves existing behavior on other platforms.

Technical Overview

New/updated files (Plan 9 only)

  • tty_plan9.go

    • Opens /dev/cons (read/write) for console I/O.

    • Toggles raw mode by writing "rawon"/"rawoff" to /dev/consctl.

    • Listens for resize events by blocking on /dev/wctl.

    • Implements Tty interface, lifecycle (Start/Stop/Close) with idempotency:

      • Re-creates stopCh and re-opens /dev/wctl on resume.
      • Avoids double-close of channels/FDs.
    • WindowSize() honors TCELL_LINES/TCELL_COLS and LINES/COLUMNS; defaults to 80×24:

      return WindowSize{Width: cols, Height: lines}, nil
  • tscreen_plan9.go

    • Plan 9 constructor:

      func NewConsoleScreen() (Screen, error) {
          tty, err := NewDevTty()
          if err != nil { return nil, err }
          return NewTerminfoScreenFromTty(tty)
      }
    • Plan 9 initializer:
      Ensures t.tty is set during Screen.Init():

      func (t *tScreen) initialize() error {
          if t.tty == nil {
              tty, err := NewDevTty()
              if err != nil { return err }
              t.tty = tty
          }
          return nil
      }
    • Note: We do not redefine screen.go::NewScreen().

  • charset_plan9.go

    • Implements getCharset() returning "UTF-8" (Plan 9 is built around Unicode, using UTF-8 system-wide - the encoding invented at Bell Labs by Ken Thompson and Rob Pike while they, alongside other Plan 9 pioneers, were developing the system).

Architecture & Data Flow

  • Input: /dev/cons in raw mode → tcell input decoder (UTF-8).
  • Output: escape sequences written to /dev/cons, interpreted by vt(1) (VT100).
  • Resize: blocking read on /dev/wctl; on change, invoke NotifyResize callback; WindowSize() returns rows/cols via env or default.

Compatibility & Risk

  • No changes for Linux/macOS/Windows/FreeBSD/OpenBSD/NetBSD/Solaris/WASM paths.
  • Plan 9 code is fully gated behind //go:build plan9.
  • Public API surface is unchanged on other platforms.

Known Limitations (Plan 9)

  1. Colors: Under vt(1) (TERM=vt100), expect monochrome (VT100 typically lacks ANSI color). If another terminal on Plan 9 provides ANSI/xterm capabilities and TERM is set accordingly, terminfo can enable more features.
  2. Mouse & bracketed paste: Not wired. vt(1) does not emit xterm mouse/paste sequences; adding support would require a terminal that does, plus glue in the Plan 9 TTY path.
  3. Window size: Derived from LINES/COLUMNS (or TCELL_LINES/TCELL_COLS) with a default 80×24. We do not compute rows/cols from pixel geometry; /dev/wctl resize is handled as an event trigger only.
  4. CI runtime: We only cross-compile Plan 9 (GOOS=plan9) in CI (if added). No runtime tests on Plan 9 yet.

Testing

Docker one-shot build

docker run --rm -it \
  -v "$PWD":/src \
  -w /src \
  --entrypoint /bin/bash \
  golang:1.23-bookworm -lc '
set -euxo pipefail

# Ensure Go is on PATH
export PATH=/usr/local/go/bin:$PATH
GO=${GO:-/usr/local/go/bin/go}

$GO version
$GO mod download

echo "[linux/amd64] compile all packages (library + demos) ..."
GOOS=linux GOARCH=amd64 $GO build ./...

echo "[plan9/amd64] compile all packages (sanity check Plan 9 path) ..."
CGO_ENABLED=0 GOOS=plan9 GOARCH=amd64 $GO build ./...

echo "[produce demo binaries]"
mkdir -p build/linux build/plan9

find _demos -type f -name \*.go ! -name \*_test.go ! -name sixel.go | while IFS= read -r f; do
  rel=${f#_demos/}
  name=${rel%.go}
  linux_out="build/linux/$name"
  plan9_out="build/plan9/${name}.out"

  mkdir -p "$(dirname "$linux_out")" "$(dirname "$plan9_out")"

  echo "[linux/amd64] $f -> $linux_out"
  GOOS=linux GOARCH=amd64 $GO build -o "$linux_out" "$f"

  echo "[plan9/amd64] $f -> $plan9_out"
  CGO_ENABLED=0 GOOS=plan9 GOARCH=amd64 $GO build -o "$plan9_out" "$f"
done

echo "Artifacts:"
ls -l build/linux build/plan9

'

@mushkevych mushkevych marked this pull request as ready for review August 16, 2025 21:44
@mushkevych mushkevych marked this pull request as draft August 16, 2025 21:45
@mushkevych
Copy link
Contributor Author

Passing manual test.
NOTE: the vt terminal is required.
screenshot_boxes
screenshot_colors
screenshot_hellow_world
screenshot_unicode

@mushkevych mushkevych marked this pull request as ready for review August 18, 2025 03:50
@mushkevych
Copy link
Contributor Author

@gdamore the PR is ready for review.

@mushkevych mushkevych changed the title [WIP] Adding minimal support for Plan9 Adding minimal support for Plan9 Aug 18, 2025
Copy link
Owner

@gdamore gdamore left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general this looks pretty good, and thank you for doing this. I cannot attest to it actually working, so I hope you've done that.

I have a reservation about the console_stub.go change, please see my comments there to double check if that's really what you meant to do. If it is, I'd like to get a better explanation behind it.

(Basically "console" is a Windows thing in tcell, so I am surprised if any non windows platforms want anything besides the stub... it seems like you're using the tty support modified for plan 9, which looks reasonable based on your comments.)

@mushkevych
Copy link
Contributor Author

@gdamore thank you for the review. i have reversed the console_stub as you requested.

@mushkevych
Copy link
Contributor Author

@gdamore
I was wondering if there are any pending concerns preventing from merging this PR.

@gdamore
Copy link
Owner

gdamore commented Aug 20, 2025 via email

Copy link
Owner

@gdamore gdamore left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Thanks for this.

@gdamore gdamore merged commit 25ed758 into gdamore:main Aug 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载