tFirst commit, set up terminal and fix key handling - ve - a minimal text editor (work in progress)
 (HTM) git clone git://src.adamsgaard.dk/ve
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit c477e00e088231070ea6f83ca1ad48f1b8c1ee49
 (HTM) Author: Anders Damsgaard <anders@adamsgaard.dk>
       Date:   Mon,  5 Aug 2019 11:27:23 +0200
       
       First commit, set up terminal and fix key handling
       
       Diffstat:
         A Makefile                            |      36 +++++++++++++++++++++++++++++++
         A input.c                             |      15 +++++++++++++++
         A input.h                             |       1 +
         A main.c                              |      13 +++++++++++++
         A output.c                            |       7 +++++++
         A output.h                            |       1 +
         A terminal.c                          |      58 ++++++++++++++++++++++++++++++
         A terminal.h                          |       4 ++++
       
       8 files changed, 135 insertions(+), 0 deletions(-)
       ---
 (DIR) diff --git a/Makefile b/Makefile
       t@@ -0,0 +1,36 @@
       +CFLAGS = -g -std=c99 -pedantic -Wall -Wextra
       +#LDFLAGS = -lm
       +SRC = $(wildcard *.c)
       +OBJ = $(patsubst %.c,%.o,$(SRC))
       +HDR = $(wildcard *.h)
       +BIN = ./byote
       +
       +PREFIX ?= /usr/local
       +INSTALL ?= install
       +STRIP ?= strip
       +
       +default: $(BIN)
       +
       +$(BIN): $(OBJ) $(HDR)
       +        $(CC) $(LDFLAGS) $(OBJ) -o $@
       +
       +install: $(BIN)
       +        $(STRIP) $(BIN)
       +        $(INSTALL) -m 0755 -d $(DESTDIR)$(PREFIX)/bin
       +        $(INSTALL) -m 0755 $(BIN) $(DESTDIR)$(PREFIX)/bin
       +
       +uninstall:
       +        $(RM) $(DESTDIR)$(PREFIX)/bin/$(BIN)
       +
       +test: $(BIN)
       +        make -C test/
       +
       +memtest: $(BIN)
       +        valgrind --error-exitcode=1 --leak-check=full $(BIN) -h
       +        valgrind --error-exitcode=1 --leak-check=full $(BIN) -v
       +
       +clean:
       +        $(RM) *.o
       +        $(RM) $(BIN)
       +
       +.PHONY: default install uninstall test memtest clean
 (DIR) diff --git a/input.c b/input.c
       t@@ -0,0 +1,15 @@
       +#include <stdlib.h>
       +#include "terminal.h"
       +
       +#define CTRL_KEY(k) ((k) & 0x1f)
       +
       +void
       +editor_process_keypress()
       +{
       +        char c = editor_read_key();
       +        switch (c) {
       +                case CTRL_KEY('q'):
       +                        exit(0);
       +                        break;
       +        }
       +}
 (DIR) diff --git a/input.h b/input.h
       t@@ -0,0 +1 @@
       +void editor_process_keypress();
 (DIR) diff --git a/main.c b/main.c
       t@@ -0,0 +1,13 @@
       +#include "terminal.h"
       +#include "output.h"
       +#include "input.h"
       +
       +int
       +main(int argc, char* argv[])
       +{
       +        enable_raw_mode();
       +        while (1) {
       +                editor_process_keypress();
       +        }
       +        return 0;
       +}
 (DIR) diff --git a/output.c b/output.c
       t@@ -0,0 +1,7 @@
       +#include <unistd.h>
       +
       +void
       +editor_refresh_screen()
       +{
       +        write(STDOUT_FILENO, "\x1b[2J", 4);
       +}
 (DIR) diff --git a/output.h b/output.h
       t@@ -0,0 +1 @@
       +void editor_refresh_screen();
 (DIR) diff --git a/terminal.c b/terminal.c
       t@@ -0,0 +1,58 @@
       +#include <errno.h>
       +#include <stdio.h>
       +#include <stdlib.h>
       +#include <termios.h>
       +#include <unistd.h>
       +
       +struct termios orig_termios;
       +
       +void
       +die(const char *s)
       +{
       +        perror(s);
       +        exit(1);
       +}
       +
       +void
       +disable_raw_mode()
       +{
       +        if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios) == -1)
       +                die("tcsetattr in disable_raw_mode()");
       +}
       +
       +void
       +enable_raw_mode()
       +{
       +        struct termios raw;
       +
       +        if (tcgetattr(STDIN_FILENO, &orig_termios) == -1)
       +                die("tcgetattr in enable_raw_mode()");
       +        atexit(disable_raw_mode);
       +
       +        /* fix modifier keys, set 8 bits per char, ignore interrupts */
       +        raw = orig_termios;
       +        raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
       +        raw.c_oflag &= ~(OPOST);
       +        raw.c_cflag |= (CS8);
       +        raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
       +
       +        /* set read() timeout in tenths of seconds */
       +        raw.c_cc[VMIN] = 0;
       +        raw.c_cc[VTIME] = 1;
       +
       +        /* apply terminal settings */
       +        if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1)
       +                die("tcsetattr in enable_raw_mode()");
       +}
       +
       +char
       +editor_read_key()
       +{
       +        int nread;
       +        char c;
       +        while ((nread = read(STDIN_FILENO, &c, 1)) != 1) {
       +                if (nread == -1 && errno != EAGAIN)
       +                        die("read in editor_read_key()");
       +        }
       +        return c;
       +}
 (DIR) diff --git a/terminal.h b/terminal.h
       t@@ -0,0 +1,4 @@
       +void die(const char *s);
       +void disable_raw_mode();
       +void enable_raw_mode();
       +char editor_read_key();