Skip to content

Instantly share code, notes, and snippets.

@robertmaxwilliams
Created April 21, 2021 15:10
Show Gist options
  • Save robertmaxwilliams/22a3fa0b5a3c7a4c930f252853f8ba5a to your computer and use it in GitHub Desktop.
Save robertmaxwilliams/22a3fa0b5a3c7a4c930f252853f8ba5a to your computer and use it in GitHub Desktop.
A typewriter in ncurses. Don't worry just write. It'll all be okay.
// Fair use for whatever, don't need no license 'cause it's not useful.
// Compile with gcc -lncurses typewriter.c
// Also if you haven't installed ncurses-dev you'll need that, I used
// sudo apt-get install libncurses5-dev libncursesw5-dev
// output is written to foo.txt
#include <ncurses.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int WIDTH = 80;
int AUTO_NL = 1;
char buffer[1001];
const int BUF_LEN = 1000;
FILE * fp;
void makenewline(int y) {
move(y, 0);
printw("> ");
move(y, WIDTH+3);
printw("|");
move(y, 2);
}
void put_line_to_file() {
int x;
int y;
getyx(stdscr, y, x);
move(y, 2);
winnstr(stdscr, buffer, BUF_LEN);
buffer[WIDTH + 1] = '\0';
fputs(buffer, fp);
fputs("\n", fp);
fflush(fp);
move(y, x);
}
void quit() {
put_line_to_file(fp);
endwin();
fclose(fp);
}
int main(int argc, char** argv) {
if (argc > 1) {
printf("How to use this program:\n");
printf("No arguments are allowed, supply an argument to show this help screen\n");
printf("Lines are appended to foo.txt as you write.\n");
printf("Press F1 or ctrl-C to quit\n");
printf("Press F2 to toggle auto line wrap\n");
printf("That's it.\n");
return 1;
}
int ch;
int x = 0;
int y = 0;
int width;
int height;
fp = fopen("foo.txt", "a");
initscr();
//raw(); raw mode is good if we want to disable leaving
cbreak();
keypad(stdscr, TRUE);
noecho();
scrollok(stdscr, TRUE);
//halfdelay(1);
printw("Don't worry, it's over now. Now there is just typewriter, nothing else.\n");
printw("Isn't it better like this? Don't you feel calmer already?\n\n");
time_t rawtime;
struct tm *info;
time(&rawtime);
info = localtime(&rawtime);
strftime(buffer, BUF_LEN, "%B %d, %Y at %I:%M %p", info);
fprintf(fp, "\n[NEW ENTRY] %s\n", buffer);
getyx(stdscr, y, x);
makenewline(y);
while (1) {
getmaxyx(stdscr, height, width);
if (width < WIDTH + 3) {
// if window is narrower than text, give up
quit();
printf("Window got to small - I got scared and quit.\n");
return 1;
}
getyx(stdscr, y, x);
ch = getch();
if(ch == KEY_F(1) || ch == 27) {
quit();
printf("Exited normally\n");
return 0;
} else if(ch == KEY_F(2)) {
// toggle auto newline
AUTO_NL = !(AUTO_NL);
} else if (ch == KEY_BACKSPACE) {
// backspace (non-destructive)
if (x > 2) {
move(y, x-1);
}
} else if (ch == '\n' || ch == KEY_ENTER) {
// write out and make new line
put_line_to_file(fp);
makenewline(y+1);
} else if (ch >= 32 && ch <= 176) {
// if a normal char is entered (printable ascii),
if (x >= WIDTH+2) {
if (AUTO_NL) {
// auto newline
put_line_to_file(fp);
makenewline(y+1);
} else {
// or print in place and alert the user
move(y, x-1);
flash();
}
}
// And finally put it on the screen.
printw("%c", ch);
} else {
// ignore any other keypresses
}
getyx(stdscr, y, x);
if (y >= height-2) {
scrl(1);
move(y-1, x);
}
}
// unreachable code since I don't use breaks
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment