Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions registry/native/c/vim/compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@
#include <sys/types.h>
#include <poll.h>
#include <sys/time.h>
#include <signal.h>
/* Force termios everywhere so TIOCGWINSZ + struct winsize are visible in EVERY
* translation unit (os_unix.c's window-size query is gated on TIOCGWINSZ, which
* is only defined where <termios.h> is included). */
#include <termios.h>

/* wasi-libc declares no sigprocmask (no signals), but our posix_stubs.c
* implements it and configure detects it (HAVE_SIGPROCMASK) — declare it so
* os_unix.c's calls compile instead of failing with implicit-declaration. */
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

/* waitpid flags (no sys/wait.h with these on wasi) */
#ifndef WNOHANG
Expand Down
61 changes: 56 additions & 5 deletions registry/native/c/vim/termcap_stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,62 @@ char *tgetstr(const char *id, char **area) {
return (char *)0;
}

char *tgoto(const char *cap, int col, int row) {
(void)cap;
(void)col;
(void)row;
return (char *)0;
/* tgoto — expand a parameterized termcap capability (cursor motion T_CM,
* scroll region T_CS, etc.). With HAVE_TGETENT defined, vim routes ALL
* parameterized caps through this external tgoto; a NULL/stub return silently
* drops the escape (so t_cm/t_cs are set but never emitted → linear draw, no
* scroll region, status line on the wrong row). This is vim's own minimal
* tgoto (src/term.c, the #ifndef HAVE_TGETENT branch): parse %i, %d, %+char,
* %%; termcap convention is tgoto(cap, destcol, destline) with %d emitting the
* LINE first, then swapping to the column. */
char *tgoto(const char *cap, int col, int line) {
static char buf[64];
char *s = buf;
char *e = buf + sizeof(buf) - 1;
int x = col;
int y = line;

if (!cap) {
return "OOPS";
}
for (; s < e && *cap; cap++) {
if (*cap != '%') {
*s++ = *cap;
continue;
}
switch (*++cap) {
case 'd': {
/* emit y as decimal, then swap so the next %d emits x */
char num[16];
int n = 0;
unsigned v = (unsigned)(y < 0 ? 0 : y);
do {
num[n++] = (char)('0' + v % 10);
v /= 10;
} while (v && n < (int)sizeof(num));
while (n > 0 && s < e) {
*s++ = num[--n];
}
y = x;
break;
}
case 'i':
x++;
y++;
break;
case '+':
*s++ = (char)(*++cap + y);
y = x;
break;
case '%':
*s++ = '%';
break;
default:
return "OOPS";
}
}
*s = '\0';
return buf;
}

int tputs(const char *str, int affcnt, int (*putc_fn)(int)) {
Expand Down
10 changes: 10 additions & 0 deletions registry/native/c/vim/termios_bridge.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,16 @@ static void ensure_shadow(void) {
}
}

/* isatty: delegate to the kernel's host_tty view. wasi-libc's isatty inspects
* WASI fdstat (must be CHARACTER_DEVICE with NO seek/tell rights); a PTY fd
* that carries seek/tell rights is wrongly reported as not-a-tty, so terminal
* apps (vim) print "Output is not to a terminal" and refuse full-screen mode.
* host_tty.isatty is the authoritative PTY check the kernel exposes (a strong
* symbol overriding the weak libc alias). */
int isatty(int fd) {
return __host_tty_isatty((unsigned int)fd) ? 1 : 0;
}

int tcgetattr(int fd, struct termios *t) {
(void)fd;
if (!t) { errno = EFAULT; return -1; }
Expand Down
Loading