turbo-editors/turbo-gopublic Fork 0
main
Commits
Clone
git clone https://git.rickub.com/turbo-editors/turbo-go.git
git clone ssh://git@rickub.com/turbo-editors/turbo-go.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

0015-windows-support-for-terminal-windows.yaml · 84 lines · 3.5 KBYAML Blame HistoryRaw
📦 Turbo Go 3d7798b k33g 11h ago1# Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2id: 15
3title: windows support for terminal windows
4state: closed
5author:
6 name: k33g
7 email: ph.charriere@gmail.com
8createdAt: 2026-08-31T04:40:00.000Z
9updatedAt: 2026-09-02T03:51:59.496Z
10labels:
11 - priority::medium
12body: |
13 Terminal windows (#7) ship for Linux and macOS only. On Windows, `F8` opens a
14 message saying they are not supported yet and changes nothing else.
15
16 Everything above the pseudo-terminal is already portable. `Parser`, `Screen`,
17 `Encode` and `View` are pure Go with no platform assumptions, and the whole
18 VT/ANSI emulator is tested without a process behind it. What is missing is one
19 file.
20
21 ## The platform surface
22
23 `internal/terminal` isolates the whole of it in three build-tagged files, each
24 implementing the same three functions:
25
26 func openPTY() (master, slave *os.File, err error)
27 func setWinsize(f *os.File, width, height int) error
28 func childAttributes() *syscall.SysProcAttr
29
30 | File | Platform |
31 | --- | --- |
32 | `pty_linux.go` | `TIOCSPTLCK`, `TIOCGPTN` -> `/dev/pts/N` |
33 | `pty_darwin.go` | `TIOCPTYGRANT`, `TIOCPTYUNLK`, `TIOCPTYGNAME` |
34 | `pty_other.go` | returns `ErrUnsupported` |
35
36 Windows means adding `pty_windows.go` and narrowing `pty_other.go`'s build tag.
37 No other file should need to change.
38
39 ## Why it is not a fourth ioctl
40
41 Windows has no `/dev/ptmx`. The equivalent is **ConPTY**, available from
42 Windows 10 1809, and it does not fit the same shape:
43
44 - `CreatePseudoConsole` takes two pipe handles and returns an `HPCON`, rather
45 than handing back a master and a slave file.
46 - The child is started with `CreateProcess` and an attribute list carrying
47 `PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE_HANDLE` — not `os/exec`'s
48 `SysProcAttr{Setsid, Setctty}`. `exec.Cmd` may not be usable directly.
49 - Resizing is `ResizePseudoConsole(hpcon, COORD)`, not an ioctl.
50 - There is no controlling terminal and no `SIGWINCH`: job control has no
51 equivalent, and `Ctrl-C` reaches the child through the console rather than
52 through a process group.
53
54 So the contract above may need widening — most likely `Session` gaining a
55 platform-provided `resize` and `close` rather than `setWinsize` alone. Keep
56 the change inside `internal/terminal`; `internal/app` should not learn that
57 Windows exists.
58
59 ## Which shell
60
61 `shellOrDefault` falls back to `/bin/sh`, which is meaningless there. Windows
62 needs its own default — `%COMSPEC%`, or PowerShell — decided before the port,
63 because it is the first thing a user notices.
64
65 ## Notes
66
67 - `golang.org/x/sys/windows` carries the ConPTY bindings, and is already in
68 the module graph as `golang.org/x/sys`. No new dependency.
69 - The emulator sends `TERM=xterm-256color`; ConPTY emits VT sequences, so the
70 existing parser should be close to sufficient. Expect differences in how
71 the alternate screen and the cursor-visibility modes are used.
72 - This cannot be developed or tested in the current sandbox: it is Linux, and
73 no Windows machine is reachable from it. Whoever takes it needs Windows.
74
75 ## Checklist
76
77 - [ ] decide the default shell on Windows (%COMSPEC% or PowerShell)
78 - [ ] add `pty_windows.go` using `CreatePseudoConsole` / `ResizePseudoConsole`
79 - [ ] narrow the build tag on `pty_other.go`
80 - [ ] widen the platform contract if `exec.Cmd` cannot carry the HPCON
81 - [ ] run the `internal/terminal` suite on Windows and unskip what passes
82 - [ ] update `docs/*/reference/terminal.md`, which currently says Windows is unsupported
83tasks: []
84comments: []