Screw it, adding all the languages
Haven't decided which language to write this in yet. Have some basic code in a couple of languages whilst deciding. Likely will choose C, but who knows.master
commit
010c7cf906
@ -0,0 +1,9 @@
|
||||
c/n3
|
||||
c/nob
|
||||
c/nob.old
|
||||
d/main
|
||||
d/main.o
|
||||
odin/n3
|
||||
rust/main
|
||||
rust/nob
|
||||
test.txt
|
||||
@ -0,0 +1,140 @@
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define SHOW_ALTERNATIVE_SCREEN "\033[?1049h"
|
||||
#define SHOW_NORMAL_SCREEN "\033[?1049l"
|
||||
#define HIDE_CURSOR "\033[?25l"
|
||||
#define SHOW_CURSOR "\033[?25h"
|
||||
#define CLEAR_SCREEN "\033[2J"
|
||||
|
||||
#define MOVE_CURSOR_HOME "\033[H"
|
||||
#define MOVE_CURSOR_UP "\x1b[1A"
|
||||
#define MOVE_CURSOR_DOWN "\x1b[1B"
|
||||
#define MOVE_CURSOR_RIGHT "\x1b[1C"
|
||||
#define MOVE_CURSOR_LEFT "\x1b[1D"
|
||||
|
||||
// man console_codes
|
||||
|
||||
// Directions
|
||||
// A - Up
|
||||
// B - Down
|
||||
// C - Right
|
||||
// D - Left
|
||||
|
||||
typedef struct {
|
||||
int line;
|
||||
int column;
|
||||
int number_of_lines;
|
||||
int number_of_columns;
|
||||
bool resized;
|
||||
bool should_exit;
|
||||
struct termios original_termios;
|
||||
} State;
|
||||
|
||||
static State state = {0};
|
||||
|
||||
|
||||
void sigwinch_handler(int signal)
|
||||
{
|
||||
fprintf(stderr, "INFO: received signal \"%s\"\n", strsignal(signal));
|
||||
|
||||
state.resized = true;
|
||||
}
|
||||
|
||||
bool get_terminal_size()
|
||||
{
|
||||
struct winsize ws;
|
||||
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
state.number_of_columns = ws.ws_col;
|
||||
state.number_of_lines = ws.ws_row;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void enable_raw_mode(void)
|
||||
{
|
||||
struct termios t = state.original_termios;
|
||||
|
||||
if (tcgetattr(STDIN_FILENO, &state.original_termios) == -1) {
|
||||
perror("tcgetattr");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
t = state.original_termios;
|
||||
t.c_lflag &= ~(ECHO | ICANON | ISIG); // turn off echo, canonical mode, signals
|
||||
t.c_iflag &= ~(IXON | ICRNL); // disable Ctrl-S/Q and CR->NL
|
||||
t.c_oflag &= ~(OPOST); // disable all output processing
|
||||
t.c_cc[VMIN] = 1; // read() returns after 1 byte
|
||||
t.c_cc[VTIME] = 0; // no timeout
|
||||
|
||||
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &t) == -1) {
|
||||
perror("tcsetattr");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// TODO: switch to sigaction
|
||||
signal(SIGWINCH, sigwinch_handler);
|
||||
signal(SIGINT, SIG_IGN);
|
||||
|
||||
enable_raw_mode();
|
||||
|
||||
printf(SHOW_ALTERNATIVE_SCREEN);
|
||||
printf(HIDE_CURSOR);
|
||||
|
||||
printf(MOVE_CURSOR_HOME);
|
||||
fflush(stdout);
|
||||
|
||||
get_terminal_size(&state);
|
||||
|
||||
char c;
|
||||
while (true) {
|
||||
ssize_t n = read(STDIN_FILENO, &c, 1);
|
||||
if (n == -1) continue;
|
||||
|
||||
if (c == 'q') break;
|
||||
|
||||
switch (c) {
|
||||
case 'h':
|
||||
printf("%s%s", MOVE_CURSOR_LEFT, MOVE_CURSOR_LEFT);
|
||||
break;
|
||||
case 'j':
|
||||
printf("%s%s", MOVE_CURSOR_DOWN, MOVE_CURSOR_LEFT);
|
||||
break;
|
||||
case 'k':
|
||||
printf("%s%s", MOVE_CURSOR_UP, MOVE_CURSOR_LEFT);
|
||||
break;
|
||||
case 'l':
|
||||
break;
|
||||
}
|
||||
|
||||
if (c == 'h') printf(MOVE_CURSOR_LEFT);
|
||||
if (c == 'j') printf(MOVE_CURSOR_DOWN);
|
||||
if (c == 'k') printf(MOVE_CURSOR_UP);
|
||||
if (c == 'l') printf(MOVE_CURSOR_RIGHT);
|
||||
|
||||
printf(CLEAR_SCREEN);
|
||||
|
||||
printf("\033[43m \033[0m");
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
tcsetattr(STDIN_FILENO, TCSAFLUSH, &state.original_termios);
|
||||
printf(SHOW_NORMAL_SCREEN);
|
||||
printf(SHOW_CURSOR);
|
||||
fflush(stdout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#define NOB_IMPLEMENTATION
|
||||
#define NOB_STRIP_PREFIX
|
||||
#include "nob.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
NOB_GO_REBUILD_URSELF(argc, argv);
|
||||
|
||||
Cmd cmd = {0};
|
||||
cmd_append(&cmd, "cc");
|
||||
cmd_append(&cmd, "-Wall");
|
||||
cmd_append(&cmd, "-Wextra");
|
||||
cmd_append(&cmd, "-o", "n3");
|
||||
cmd_append(&cmd, "main.c");
|
||||
|
||||
if (!cmd_run(&cmd)) return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
import core.stdc.errno;
|
||||
import core.stdc.stdio;
|
||||
import core.stdc.stdlib;
|
||||
import core.sys.posix.fcntl;
|
||||
import core.sys.posix.signal;
|
||||
import core.sys.posix.sys.ioctl;
|
||||
import core.sys.posix.unistd;
|
||||
|
||||
extern(C) void handle_sigwinch() {
|
||||
printf("terminal has been resized");
|
||||
}
|
||||
|
||||
extern(C) int main(int argc, char **argv) {
|
||||
winsize ws;
|
||||
|
||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws);
|
||||
signal(SIGWINCH, handle_sigwinch);
|
||||
|
||||
printf("Lines: %d\n", ws.ws_row);
|
||||
printf("Columns %d\n", ws.ws_col);
|
||||
|
||||
while (true) {
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,72 @@
|
||||
package main
|
||||
|
||||
import "core:fmt"
|
||||
import "core:os"
|
||||
import "core:sys/unix"
|
||||
|
||||
foreign import libc "system:c"
|
||||
|
||||
// Terminal codes
|
||||
CLEAR_CODE :: "\033[2J"
|
||||
HIDE_CURSOR :: "\033[?25l"
|
||||
RESET :: "\0033[0m"
|
||||
|
||||
TIOCGWINSZ :: 0x5413
|
||||
|
||||
winsize :: struct {
|
||||
ws_row: u16,
|
||||
ws_col: u16,
|
||||
ws_xpixel: u16,
|
||||
ws_ypixel: u16,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c")
|
||||
foreign libc {
|
||||
ioctl :: proc(fd: i32, request: u64, #c_vararg args: ..any) -> i32 ---
|
||||
signal :: proc(signum: i32, handler: proc "c" (i32)) -> rawptr ---
|
||||
}
|
||||
|
||||
SIGWINCH :: 28
|
||||
|
||||
resize_occurred := false
|
||||
|
||||
signal_handler :: proc "c" (sig: i32) {
|
||||
resize_occurred = true
|
||||
}
|
||||
|
||||
get_terminal_size :: proc() -> (rows, cols: int, ok: bool) {
|
||||
ws: winsize
|
||||
|
||||
result := ioctl(i32(os.stdout), TIOCGWINSZ, &ws)
|
||||
|
||||
if result == -1 {
|
||||
return 0, 0, false
|
||||
}
|
||||
|
||||
return int(ws.ws_row), int(ws.ws_col), true
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
signal(SIGWINCH, signal_handler)
|
||||
|
||||
if len(os.args) != 2 {
|
||||
fmt.eprintln("INCORRECT NUMBER OF COMMAND LINE ARGUMENTS")
|
||||
return
|
||||
}
|
||||
|
||||
filename := os.args[1]
|
||||
data, ok := os.read_entire_file_from_filename(os.args[1])
|
||||
if !ok {
|
||||
fmt.eprintfln("ERROR: failed to open file: %s", filename)
|
||||
}
|
||||
|
||||
for {
|
||||
if resize_occurred {
|
||||
resize_occurred = false
|
||||
rows, cols, ok := get_terminal_size()
|
||||
if ok {
|
||||
fmt.printf("Terminal resized! New size: %d rows x %d cols\n", rows, cols)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue