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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions initrd/etc/vim/vimrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
" Stellux system defaults
set nocompatible
set backspace=indent,eol,start
2 changes: 1 addition & 1 deletion userland/apps/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
APP_DIRS := init hello shell ls cat rm stat touch sleep true false clear ptytest date \
clockbench stlxdm stlxterm doom ping ifconfig nslookup arp udpecho tcpecho \
fetch polltest dropbear blackjack wordle hangman snake tetris \
grep wc head threadtest uname kill cxxtest synctest python
grep wc head threadtest uname kill cxxtest synctest python vim
APP_COUNT := $(words $(APP_DIRS))

all:
Expand Down
17 changes: 9 additions & 8 deletions userland/apps/stlxterm/src/keymap.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ static int emit(char *out, int out_size, const char *seq, int len) {
return len;
}

int keymap_translate(uint16_t usage, uint8_t modifiers,
int keymap_translate(uint16_t usage, uint8_t modifiers, int app_cursor,
char *out, int out_size) {
if (!out || out_size < 1) return 0;

Expand Down Expand Up @@ -57,16 +57,17 @@ int keymap_translate(uint16_t usage, uint8_t modifiers,
switch (usage) {
case 0x28: out[0] = '\r'; return 1;
case 0x29: out[0] = '\x1b'; return 1;
case 0x2A: out[0] = '\x7f'; return 1;
case 0x2A: out[0] = '\b'; return 1;
case 0x2B: out[0] = '\t'; return 1;
case 0x2C: out[0] = ' '; return 1;

case 0x4F: return emit(out, out_size, "\x1b[C", 3);
case 0x50: return emit(out, out_size, "\x1b[D", 3);
case 0x51: return emit(out, out_size, "\x1b[B", 3);
case 0x52: return emit(out, out_size, "\x1b[A", 3);
case 0x4A: return emit(out, out_size, "\x1b[H", 3);
case 0x4D: return emit(out, out_size, "\x1b[F", 3);
/* Arrows follow DECCKM: CSI form normally, SS3 form in application mode */
case 0x4F: return emit(out, out_size, app_cursor ? "\x1bOC" : "\x1b[C", 3);
case 0x50: return emit(out, out_size, app_cursor ? "\x1bOD" : "\x1b[D", 3);
case 0x51: return emit(out, out_size, app_cursor ? "\x1bOB" : "\x1b[B", 3);
case 0x52: return emit(out, out_size, app_cursor ? "\x1bOA" : "\x1b[A", 3);
case 0x4A: return emit(out, out_size, app_cursor ? "\x1bOH" : "\x1b[H", 3);
case 0x4D: return emit(out, out_size, app_cursor ? "\x1bOF" : "\x1b[F", 3);
case 0x4C: return emit(out, out_size, "\x1b[3~", 4);
case 0x49: return emit(out, out_size, "\x1b[2~", 4); /* Insert */
case 0x4B: return emit(out, out_size, "\x1b[5~", 4); /* Page Up */
Expand Down
2 changes: 1 addition & 1 deletion userland/apps/stlxterm/src/keymap.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#include <stdint.h>

int keymap_translate(uint16_t usage, uint8_t modifiers,
int keymap_translate(uint16_t usage, uint8_t modifiers, int app_cursor,
char *out, int out_size);

#endif // STLXTERM_KEYMAP_H
1 change: 1 addition & 0 deletions userland/apps/stlxterm/src/stlxterm.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ int main(void) {
if (evt.type == STLXGFX_EVT_KEY_DOWN) {
char seq[8];
int len = keymap_translate(evt.key.usage, evt.key.modifiers,
term->app_cursor_keys,
Comment thread
FlareCoding marked this conversation as resolved.
seq, sizeof(seq));
if (len > 0) {
write(master_fd, seq, (size_t)len);
Expand Down
40 changes: 39 additions & 1 deletion userland/apps/stlxterm/src/term.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,9 @@ static void csi_dispatch_private(term_state_t *t, char cmd) {

if (cmd == 'h') {
switch (p0) {
case 1: /* DECCKM: application cursor keys */
t->app_cursor_keys = 1;
break;
case 25: /* DECTCEM: show cursor */
t->cursor_visible = 1;
break;
Expand All @@ -200,6 +203,9 @@ static void csi_dispatch_private(term_state_t *t, char cmd) {
}
} else if (cmd == 'l') {
switch (p0) {
case 1: /* DECCKM: normal cursor keys */
t->app_cursor_keys = 0;
break;
case 25: /* DECTCEM: hide cursor */
t->cursor_visible = 0;
break;
Expand Down Expand Up @@ -450,7 +456,10 @@ static void feed_byte(term_state_t *t, unsigned char ch) {
t->csi_param_count = 0;
t->csi_current_param = 0;
t->csi_private = 0;
t->csi_discard = 0;
t->state = TERM_ST_CSI;
} else if (ch == ']') { /* OSC: consume until BEL or ST */
t->state = TERM_ST_OSC;
} else if (ch == '7') { /* DECSC: save cursor */
save_cursor(t);
t->state = TERM_ST_NORMAL;
Expand All @@ -477,13 +486,21 @@ static void feed_byte(term_state_t *t, unsigned char ch) {
case TERM_ST_CSI:
if (ch == '?' && t->csi_param_count == 0 && t->csi_current_param == 0) {
t->csi_private = 1;
} else if (ch == '<' || ch == '=' || ch == '>') {
/* Prefixed protocol sequences are consumed and ignored */
t->csi_discard = 1;
} else if (ch >= '0' && ch <= '9') {
t->csi_current_param = t->csi_current_param * 10 + (ch - '0');
} else if (ch == ';') {
csi_push_param(t);
} else if (ch >= 0x20 && ch <= 0x2F) {
/* Intermediate bytes mark sequences we do not implement */
t->csi_discard = 1;
} else if (ch >= 0x40 && ch <= 0x7E) {
csi_push_param(t);
if (t->csi_private) {
if (t->csi_discard) {
/* Fully consumed, deliberately ignored */
} else if (t->csi_private) {
csi_dispatch_private(t, (char)ch);
} else {
csi_dispatch(t, (char)ch);
Expand All @@ -495,6 +512,25 @@ static void feed_byte(term_state_t *t, unsigned char ch) {
t->state = TERM_ST_NORMAL;
}
break;

case TERM_ST_OSC:
if (ch == '\x07') {
t->state = TERM_ST_NORMAL;
} else if (ch == '\x1b') {
t->state = TERM_ST_OSC_ESC;
}
break;

case TERM_ST_OSC_ESC:
/* ESC backslash is ST, anything else starts a new escape whose
follower byte must be reprocessed */
if (ch == '\\') {
t->state = TERM_ST_NORMAL;
} else {
t->state = TERM_ST_ESC;
feed_byte(t, ch);
}
break;
Comment thread
cursor[bot] marked this conversation as resolved.
}
}

Expand All @@ -520,10 +556,12 @@ void term_init(term_state_t *t, int rows, int cols) {
t->saved_bold = 0;
t->saved_reverse = 0;
t->using_alt_screen = 0;
t->app_cursor_keys = 0;
t->state = TERM_ST_NORMAL;
t->csi_param_count = 0;
t->csi_current_param = 0;
t->csi_private = 0;
t->csi_discard = 0;
for (int r = 0; r < TERM_MAX_ROWS; r++) {
memset(&t->cells[r], ' ', TERM_MAX_COLS);
memset(&t->attrs[r], 0, TERM_MAX_COLS * sizeof(term_attr_t));
Expand Down
6 changes: 5 additions & 1 deletion userland/apps/stlxterm/src/term.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,16 @@ typedef struct {
int alt_cursor_col;
int using_alt_screen;

// DECCKM application cursor keys, consulted by the key encoder
int app_cursor_keys;

// Parser state
enum { TERM_ST_NORMAL, TERM_ST_ESC, TERM_ST_CSI } state;
enum { TERM_ST_NORMAL, TERM_ST_ESC, TERM_ST_CSI, TERM_ST_OSC, TERM_ST_OSC_ESC } state;
int csi_params[TERM_CSI_MAX_PARAMS];
int csi_param_count;
int csi_current_param;
int csi_private;
int csi_discard;
} term_state_t;

void term_init(term_state_t *t, int rows, int cols);
Expand Down
1 change: 1 addition & 0 deletions userland/apps/vim/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build/
91 changes: 91 additions & 0 deletions userland/apps/vim/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#
# Stellux Vim Build
#
# Cross-compiles Vim with --features=tiny for Stellux OS.
# Uses musl libc, no ncurses (builtin termcap), no GUI.
#
# Sources are a minimal vendored subset of upstream vim tag v9.1.0000.
# regexp_bt.c and regexp_nfa.c are textually included by regexp.c and
# must not be compiled standalone.
#

USERLAND_ROOT ?= $(shell cd ../.. && pwd)
include ../../mk/toolchain.mk

SRC_DIR := src
BUILD_DIR := build/$(ARCH)
BIN_DIR := $(USERLAND_ROOT)/build/$(ARCH)/bin

# Vim-specific CFLAGS
VIM_CFLAGS := \
--target=$(TARGET_TRIPLE) \
--sysroot=$(SYSROOT) \
-nostdlibinc \
-isystem $(SYSROOT)/include \
-std=gnu11 -O2 -g \
-Wall -Wno-unused-parameter -Wno-unused-variable \
-Wno-sign-compare -Wno-missing-field-initializers \
-Wno-implicit-fallthrough -Wno-string-plus-int \
-Wno-unused-function -Wno-parentheses \
-Wno-missing-braces -Wno-tautological-compare \
-Wno-pointer-sign -Wno-empty-body \
-fno-stack-protector \
-I$(SRC_DIR) -I$(SRC_DIR)/proto \
-DHAVE_CONFIG_H \
-DFEAT_TINY

# All Vim source files (from BASIC_SRC + required extras)
VIM_SOURCES := \
alloc.c arabic.c arglist.c autocmd.c beval.c blob.c blowfish.c \
buffer.c bufwrite.c change.c charset.c cindent.c clientserver.c \
clipboard.c cmdexpand.c cmdhist.c crypt.c crypt_zip.c debugger.c \
dict.c diff.c digraph.c drawline.c drawscreen.c edit.c eval.c \
evalbuffer.c evalfunc.c evalvars.c evalwindow.c ex_cmds.c \
ex_cmds2.c ex_docmd.c ex_eval.c ex_getln.c fileio.c filepath.c \
findfile.c float.c fold.c getchar.c hardcopy.c hashtab.c help.c \
highlight.c if_cscope.c indent.c insexpand.c json.c list.c \
locale.c logfile.c main.c map.c mark.c match.c mbyte.c memfile.c \
memline.c menu.c message.c misc1.c misc2.c mouse.c move.c \
normal.c ops.c option.c optionstr.c os_unix.c popupmenu.c \
popupwin.c profiler.c quickfix.c regexp.c register.c screen.c \
scriptfile.c search.c session.c sha256.c sign.c sound.c spell.c \
spellfile.c spellsuggest.c strings.c syntax.c tag.c term.c \
testing.c textformat.c textobject.c textprop.c time.c typval.c \
ui.c undo.c usercmd.c userfunc.c version.c viminfo.c window.c \
auto/pathdef.c \
stellux_stubs.c

# Note: gui_xim.c, if_xcmdsrv.c, pty.c, terminal.c, vim9*.c excluded
# (not needed for tiny build on Stellux)

VIM_OBJECTS := $(VIM_SOURCES:%.c=$(BUILD_DIR)/%.o)

TARGET := $(BIN_DIR)/vim

all: $(TARGET)

$(TARGET): $(VIM_OBJECTS)
$(UQ)mkdir -p $(dir $@)
@echo "[LD] vim ($(ARCH))"
$(UQ)$(CC) -nostdlib -fuse-ld=lld --target=$(TARGET_TRIPLE) \
-static -o $@ \
$(SYSROOT)/lib/crt1.o $(SYSROOT)/lib/crti.o \
$(VIM_OBJECTS) \
-L$(SYSROOT)/lib -Wl,--start-group -lstlx -lc -lm $(BUILTINS_LIB) -Wl,--end-group \
$(SYSROOT)/lib/crtn.o

$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c
$(UQ)mkdir -p $(dir $@)
@echo "[CC] $< ($(ARCH))"
$(UQ)$(CC) $(VIM_CFLAGS) -c $< -o $@

$(BUILD_DIR)/auto/%.o: $(SRC_DIR)/auto/%.c
$(UQ)mkdir -p $(dir $@)
@echo "[CC] $< ($(ARCH))"
$(UQ)$(CC) $(VIM_CFLAGS) -c $< -o $@

clean:
$(UQ)rm -rf build
$(UQ)rm -f $(TARGET)

.PHONY: all clean
Loading
Loading