Compare commits
2 commits
8a6dd74ac0
...
51688b6ad6
Author | SHA1 | Date | |
---|---|---|---|
51688b6ad6 | |||
8a49a9b255 |
2 changed files with 75 additions and 40 deletions
10
config.h
10
config.h
|
@ -22,6 +22,11 @@
|
||||||
#define MAUVE_FG "\033[48;2;203;166;247m"
|
#define MAUVE_FG "\033[48;2;203;166;247m"
|
||||||
#define MAUVE_BG "\033[38;2;203;166;247m"
|
#define MAUVE_BG "\033[38;2;203;166;247m"
|
||||||
#define YELLOW_BG "\033[38;2;249;226;175m"
|
#define YELLOW_BG "\033[38;2;249;226;175m"
|
||||||
|
#define RED_FG "\033[48;2;243;139;168m"
|
||||||
|
#define RED_BG "\033[38;2;243;139;168m"
|
||||||
|
|
||||||
|
/* ERROR is red with bold and italic */
|
||||||
|
#define ERROR "\033[38;2;243;139;168m\033[1m\033[3m"
|
||||||
|
|
||||||
enum keys {
|
enum keys {
|
||||||
BACKSPACE = 127,
|
BACKSPACE = 127,
|
||||||
|
@ -87,7 +92,8 @@ typedef struct {
|
||||||
row_t *row;
|
row_t *row;
|
||||||
int dirty;
|
int dirty;
|
||||||
int mode;
|
int mode;
|
||||||
char *filename;
|
char filename[PATH_MAX];
|
||||||
|
char cwd[PATH_MAX];
|
||||||
language_t *syntax;
|
language_t *syntax;
|
||||||
} editor_t;
|
} editor_t;
|
||||||
|
|
||||||
|
@ -101,7 +107,7 @@ language_t langs[] = {
|
||||||
"//",
|
"//",
|
||||||
"/*",
|
"/*",
|
||||||
"*/",
|
"*/",
|
||||||
{ "switch", "if", "while", "for", "break", "continue", "return", "else", "struct", "union", "typedef", "static", "enum", "case", "sizeof", "#include", "int|", "long|", "double|", "float|", "char|", "unsigned|", "void|", NULL },
|
{ "switch", "if", "while", "for", "break", "continue", "return", "else", "struct", "union", "typedef", "static", "enum", "case", "sizeof", "#include", "#define", "#if", "#elseif", "#endif", "int|", "long|", "double|", "float|", "char|", "unsigned|", "void|", NULL },
|
||||||
{ ".c", ".h", ".cpp", NULL },
|
{ ".c", ".h", ".cpp", NULL },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
105
vip.c
105
vip.c
|
@ -9,6 +9,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <libgen.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -17,9 +18,10 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
struct termios newt, oldt;
|
struct termios newt, oldt;
|
||||||
int screenrows, screencols;
|
int rows, cols;
|
||||||
editor_t editor[9];
|
editor_t editor[9];
|
||||||
int editor_idx = 0;
|
int editor_idx = 0;
|
||||||
|
int editors = 0;
|
||||||
editor_t *cur_editor;
|
editor_t *cur_editor;
|
||||||
|
|
||||||
void draw_status_bar(void);
|
void draw_status_bar(void);
|
||||||
|
@ -58,7 +60,7 @@ void bprintf(const char *fmt, ...);
|
||||||
*/
|
*/
|
||||||
void draw_status_bar(void)
|
void draw_status_bar(void)
|
||||||
{
|
{
|
||||||
move_cursor(screenrows - 1, 1);
|
move_cursor(rows - 1, 1);
|
||||||
/* Reverse and bold */
|
/* Reverse and bold */
|
||||||
bprintf("\033[7m\033[1m");
|
bprintf("\033[7m\033[1m");
|
||||||
|
|
||||||
|
@ -87,8 +89,8 @@ void draw_status_bar(void)
|
||||||
|
|
||||||
char git[80], file[80], info[80], lines[80], coord[80];
|
char git[80], file[80], info[80], lines[80], coord[80];
|
||||||
int git_len = snprintf(git, sizeof(git), " %s | %s ", "master", "+1");
|
int git_len = snprintf(git, sizeof(git), " %s | %s ", "master", "+1");
|
||||||
int file_len = snprintf(file, sizeof(file), " %.20s %s",
|
int file_len = snprintf(file, sizeof(file), " %s %s",
|
||||||
cur_editor->filename ? cur_editor->filename : "[No Name]", cur_editor->dirty ? "[+]" : "");
|
strlen(cur_editor->filename) > 0 ? cur_editor->filename : "[No Name]", cur_editor->dirty ? "[+]" : "");
|
||||||
int info_len = snprintf(info, sizeof(info), " %s ", cur_editor->syntax ? cur_editor->syntax->filetype : "");
|
int info_len = snprintf(info, sizeof(info), " %s ", cur_editor->syntax ? cur_editor->syntax->filetype : "");
|
||||||
int lines_len;
|
int lines_len;
|
||||||
if (cur_editor->rows == 0 || cur_editor->rows == cur_editor->y + 1) {
|
if (cur_editor->rows == 0 || cur_editor->rows == cur_editor->y + 1) {
|
||||||
|
@ -116,8 +118,8 @@ void draw_status_bar(void)
|
||||||
}
|
}
|
||||||
bprintf("%s%s%s%s", git, BLACK_BG, WHITE_FG, file);
|
bprintf("%s%s%s%s", git, BLACK_BG, WHITE_FG, file);
|
||||||
|
|
||||||
while (file_len < screencols) {
|
while (file_len < cols) {
|
||||||
if (screencols - mode_len - git_len - file_len == info_len + lines_len + coord_len) {
|
if (cols - mode_len - git_len - file_len == info_len + lines_len + coord_len) {
|
||||||
bprintf("%s%s", info, SURFACE_1_BG);
|
bprintf("%s%s", info, SURFACE_1_BG);
|
||||||
if (cur_editor->mode == NORMAL) {
|
if (cur_editor->mode == NORMAL) {
|
||||||
bprintf(BLUE_FG);
|
bprintf(BLUE_FG);
|
||||||
|
@ -145,7 +147,7 @@ void draw_status_bar(void)
|
||||||
file_len++;
|
file_len++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bprintf("\033[0m");
|
bprintf("\033[m");
|
||||||
}
|
}
|
||||||
|
|
||||||
void refresh_screen(void)
|
void refresh_screen(void)
|
||||||
|
@ -163,14 +165,14 @@ void refresh_screen(void)
|
||||||
if (cur_editor->y < cur_editor->rowoff) {
|
if (cur_editor->y < cur_editor->rowoff) {
|
||||||
cur_editor->rowoff = cur_editor->y;
|
cur_editor->rowoff = cur_editor->y;
|
||||||
}
|
}
|
||||||
if (cur_editor->y >= cur_editor->rowoff + screenrows - 3) {
|
if (cur_editor->y >= cur_editor->rowoff + rows - 3) {
|
||||||
cur_editor->rowoff = cur_editor->y - screenrows + 3;
|
cur_editor->rowoff = cur_editor->y - rows + 3;
|
||||||
}
|
}
|
||||||
if (cur_editor->rx < cur_editor->coloff) {
|
if (cur_editor->rx < cur_editor->coloff) {
|
||||||
cur_editor->coloff = cur_editor->rx;
|
cur_editor->coloff = cur_editor->rx;
|
||||||
}
|
}
|
||||||
if (cur_editor->rx >= cur_editor->coloff + screencols) {
|
if (cur_editor->rx >= cur_editor->coloff + cols) {
|
||||||
cur_editor->coloff = cur_editor->rx - screencols + 1;
|
cur_editor->coloff = cur_editor->rx - cols + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bprintf("\033H\033[2 q");
|
bprintf("\033H\033[2 q");
|
||||||
|
@ -301,7 +303,13 @@ void del_char(void)
|
||||||
|
|
||||||
void init_editor(char *filename)
|
void init_editor(char *filename)
|
||||||
{
|
{
|
||||||
cur_editor = &editor[editor_idx];
|
if (editors > 8) {
|
||||||
|
wpprintw("%sOnly 9 tabs are allowed", ERROR);
|
||||||
|
readch();
|
||||||
|
wpprintw("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cur_editor = &editor[editors++];
|
||||||
cur_editor->x = 0;
|
cur_editor->x = 0;
|
||||||
cur_editor->y = 0;
|
cur_editor->y = 0;
|
||||||
cur_editor->rx = 0;
|
cur_editor->rx = 0;
|
||||||
|
@ -311,18 +319,17 @@ void init_editor(char *filename)
|
||||||
cur_editor->row = NULL;
|
cur_editor->row = NULL;
|
||||||
cur_editor->dirty = 0;
|
cur_editor->dirty = 0;
|
||||||
cur_editor->mode = NORMAL;
|
cur_editor->mode = NORMAL;
|
||||||
cur_editor->filename = NULL;
|
|
||||||
cur_editor->syntax = NULL;
|
cur_editor->syntax = NULL;
|
||||||
|
char cwd[PATH_MAX];
|
||||||
|
getcwd(cwd, PATH_MAX);
|
||||||
|
strcpy(cur_editor->cwd, cwd);
|
||||||
|
|
||||||
if (get_window_size(&screenrows, &screencols) == -1) {
|
if (get_window_size(&rows, &cols) == -1) {
|
||||||
die("get_window_size");
|
die("get_window_size");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur_editor->filename) {
|
|
||||||
free(cur_editor->filename);
|
|
||||||
}
|
|
||||||
if (filename) {
|
if (filename) {
|
||||||
cur_editor->filename = strdup(filename);
|
strcpy(cur_editor->filename, basename(filename));
|
||||||
|
|
||||||
FILE *fp = fopen(filename, "r");
|
FILE *fp = fopen(filename, "r");
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
|
@ -345,6 +352,8 @@ void init_editor(char *filename)
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
/* Reset dirtiness as nothing is modified yet */
|
/* Reset dirtiness as nothing is modified yet */
|
||||||
cur_editor->dirty = 0;
|
cur_editor->dirty = 0;
|
||||||
|
} else {
|
||||||
|
strcpy(cur_editor->filename, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,7 +366,7 @@ char *prompt_editor(char *prompt, void (*callback)(char *, int))
|
||||||
buf[0] = '\0';
|
buf[0] = '\0';
|
||||||
while (1) {
|
while (1) {
|
||||||
wpprintw(prompt, buf);
|
wpprintw(prompt, buf);
|
||||||
move_cursor(screenrows, prompt_len - 1 + strlen(buf));
|
move_cursor(rows, prompt_len - 1 + strlen(buf));
|
||||||
int c = readch();
|
int c = readch();
|
||||||
if (c == DEL_KEY || c == CTRL_KEY('h') || c == BACKSPACE) {
|
if (c == DEL_KEY || c == CTRL_KEY('h') || c == BACKSPACE) {
|
||||||
if (buflen != 0) {
|
if (buflen != 0) {
|
||||||
|
@ -526,12 +535,13 @@ int readch(void)
|
||||||
|
|
||||||
void save_file(void)
|
void save_file(void)
|
||||||
{
|
{
|
||||||
if (cur_editor->filename == NULL) {
|
if (strlen(cur_editor->filename) == 0) {
|
||||||
cur_editor->filename = prompt_editor("Save as: %s", NULL);
|
char *new_filename = prompt_editor("Save as: %s", NULL);
|
||||||
if (cur_editor->filename == NULL) {
|
if (new_filename == NULL) {
|
||||||
wpprintw("Save aborted");
|
wpprintw("Save aborted");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
strcpy(cur_editor->filename, new_filename);
|
||||||
select_syntax();
|
select_syntax();
|
||||||
}
|
}
|
||||||
int fd = open(cur_editor->filename, O_RDWR | O_CREAT, 0644);
|
int fd = open(cur_editor->filename, O_RDWR | O_CREAT, 0644);
|
||||||
|
@ -555,15 +565,15 @@ void save_file(void)
|
||||||
|
|
||||||
void draw_rows(void)
|
void draw_rows(void)
|
||||||
{
|
{
|
||||||
for (int y = 0; y < screenrows - 1; y++) {
|
for (int y = 0; y < rows - 1; y++) {
|
||||||
move_cursor(y + 1, 1);
|
move_cursor(y + 1, 1);
|
||||||
int filerow = y + cur_editor->rowoff;
|
int filerow = y + cur_editor->rowoff;
|
||||||
if (filerow >= cur_editor->rows) {
|
if (filerow >= cur_editor->rows) {
|
||||||
if (cur_editor->rows == 0 && y == screenrows / 2) {
|
if (cur_editor->rows == 0 && y == rows / 2) {
|
||||||
char welcome[11];
|
char welcome[11];
|
||||||
snprintf(welcome, sizeof(welcome), "VIP v%s", VERSION);
|
snprintf(welcome, sizeof(welcome), "VIP v%s", VERSION);
|
||||||
/* Length of welcome message must be 10 */
|
/* Length of welcome message must be 10 */
|
||||||
int padding = (screencols - 10) / 2;
|
int padding = (cols - 10) / 2;
|
||||||
while (padding--)
|
while (padding--)
|
||||||
bprintf(" ");
|
bprintf(" ");
|
||||||
bprintf(welcome);
|
bprintf(welcome);
|
||||||
|
@ -571,7 +581,7 @@ void draw_rows(void)
|
||||||
} else {
|
} else {
|
||||||
int len = cur_editor->row[filerow].render_size - cur_editor->coloff;
|
int len = cur_editor->row[filerow].render_size - cur_editor->coloff;
|
||||||
if (len < 0) len = 0;
|
if (len < 0) len = 0;
|
||||||
if (len > screencols) len = screencols;
|
if (len > cols) len = cols;
|
||||||
char *c = &cur_editor->row[filerow].render[cur_editor->coloff];
|
char *c = &cur_editor->row[filerow].render[cur_editor->coloff];
|
||||||
unsigned char *hl = &cur_editor->row[filerow].hl[cur_editor->coloff];
|
unsigned char *hl = &cur_editor->row[filerow].hl[cur_editor->coloff];
|
||||||
|
|
||||||
|
@ -856,7 +866,7 @@ char *syntax_to_color(int hl, size_t *len)
|
||||||
|
|
||||||
void select_syntax(void)
|
void select_syntax(void)
|
||||||
{
|
{
|
||||||
if (cur_editor->filename == NULL) return;
|
if (strlen(cur_editor->filename) == 0) return;
|
||||||
cur_editor->syntax = NULL;
|
cur_editor->syntax = NULL;
|
||||||
char *ext = strrchr(cur_editor->filename, '.');
|
char *ext = strrchr(cur_editor->filename, '.');
|
||||||
for (uint8_t i = 0; i < LANGS_LEN; i++) {
|
for (uint8_t i = 0; i < LANGS_LEN; i++) {
|
||||||
|
@ -878,13 +888,32 @@ void select_syntax(void)
|
||||||
|
|
||||||
void die(const char *s)
|
void die(const char *s)
|
||||||
{
|
{
|
||||||
bprintf("\033[2J\033[H");
|
cleanup();
|
||||||
perror(s);
|
perror(s);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handle_sigwinch(int ignore)
|
||||||
|
{
|
||||||
|
get_window_size(&rows, &cols);
|
||||||
|
if (cols < 80 || rows < 24) {
|
||||||
|
die("vip: Terminal size needs to be at least 80x24");
|
||||||
|
}
|
||||||
|
refresh_screen();
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
struct sigaction sa;
|
||||||
|
sa.sa_handler = handle_sigwinch;
|
||||||
|
sa.sa_flags = SA_RESTART;
|
||||||
|
sigemptyset(&sa.sa_mask);
|
||||||
|
|
||||||
|
if (sigaction(SIGWINCH, &sa, NULL) == -1) {
|
||||||
|
perror("sigaction");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
bprintf("\033[?1049h\033[2J\033[2q");
|
bprintf("\033[?1049h\033[2J\033[2q");
|
||||||
if (tcgetattr(STDIN_FILENO, &oldt) == -1) {
|
if (tcgetattr(STDIN_FILENO, &oldt) == -1) {
|
||||||
die("tcgetattr");
|
die("tcgetattr");
|
||||||
|
@ -939,10 +968,10 @@ int main(int argc, char **argv)
|
||||||
if (c == PAGE_UP) {
|
if (c == PAGE_UP) {
|
||||||
cur_editor->y = cur_editor->rowoff;
|
cur_editor->y = cur_editor->rowoff;
|
||||||
} else if (c == PAGE_DOWN) {
|
} else if (c == PAGE_DOWN) {
|
||||||
cur_editor->y = cur_editor->rowoff + screenrows - 1;
|
cur_editor->y = cur_editor->rowoff + rows - 1;
|
||||||
if (cur_editor->y > cur_editor->rows) cur_editor->y = cur_editor->rows;
|
if (cur_editor->y > cur_editor->rows) cur_editor->y = cur_editor->rows;
|
||||||
}
|
}
|
||||||
int times = screenrows;
|
int times = rows;
|
||||||
while (times--)
|
while (times--)
|
||||||
move_xy(c == PAGE_UP ? ARROW_UP : ARROW_DOWN);
|
move_xy(c == PAGE_UP ? ARROW_UP : ARROW_DOWN);
|
||||||
break;
|
break;
|
||||||
|
@ -1017,7 +1046,7 @@ int main(int argc, char **argv)
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
if (cur_editor->dirty) {
|
if (cur_editor->dirty) {
|
||||||
wpprintw("\033[1m\033[38;2;255;0;0mNo write since last change for buffer \"%s\"\033[0m", cur_editor->filename);
|
wpprintw("%sNo write since last change for buffer \"%s\"", ERROR, cur_editor->filename);
|
||||||
cur_editor->mode = NORMAL;
|
cur_editor->mode = NORMAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1096,13 +1125,10 @@ int main(int argc, char **argv)
|
||||||
if (c == 'p') {
|
if (c == 'p') {
|
||||||
c = readch();
|
c = readch();
|
||||||
if (c == 'v') {
|
if (c == 'v') {
|
||||||
char cwd[PATH_MAX];
|
|
||||||
getcwd(cwd, PATH_MAX);
|
|
||||||
|
|
||||||
pid_t pid = fork();
|
pid_t pid = fork();
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
/* Child process */
|
/* Child process */
|
||||||
execlp("ccc", "ccc", cwd, "-p", NULL);
|
execlp("ccc", "ccc", cur_editor->cwd, "-p", NULL);
|
||||||
_exit(1); /* Exit if exec fails */
|
_exit(1); /* Exit if exec fails */
|
||||||
} else if (pid > 0) {
|
} else if (pid > 0) {
|
||||||
/* Parent process */
|
/* Parent process */
|
||||||
|
@ -1110,6 +1136,9 @@ int main(int argc, char **argv)
|
||||||
FILE *f = fopen("/home/night/.cache/ccc/opened_file", "r");
|
FILE *f = fopen("/home/night/.cache/ccc/opened_file", "r");
|
||||||
char opened_file[PATH_MAX];
|
char opened_file[PATH_MAX];
|
||||||
fread(opened_file, sizeof(char), PATH_MAX, f);
|
fread(opened_file, sizeof(char), PATH_MAX, f);
|
||||||
|
opened_file[strcspn(opened_file, "\n")] = 0;
|
||||||
|
|
||||||
|
init_editor(opened_file);
|
||||||
} else {
|
} else {
|
||||||
/* Fork failed */
|
/* Fork failed */
|
||||||
}
|
}
|
||||||
|
@ -1144,16 +1173,16 @@ void cleanup(void)
|
||||||
*/
|
*/
|
||||||
void wpprintw(const char *fmt, ...)
|
void wpprintw(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
char buffer[screencols];
|
char buffer[cols];
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
vsnprintf(buffer, sizeof(buffer), fmt, args);
|
vsnprintf(buffer, sizeof(buffer), fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
move_cursor(screenrows, 1);
|
move_cursor(rows, 1);
|
||||||
/* Clear line and print formatted string */
|
/* Clear line and print formatted string */
|
||||||
bprintf("\033[K%s", buffer);
|
bprintf("\033[K%s\033[0m", buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void move_cursor(int row, int col)
|
void move_cursor(int row, int col)
|
||||||
|
|
Loading…
Reference in a new issue