functional lisp config files
Build and Deploy Docs / build (push) Successful in 47s

This commit is contained in:
Arthur Barraux
2025-10-02 11:26:18 +02:00
parent 53d6572c8c
commit 3b6c60a49e
16 changed files with 482 additions and 209 deletions
+44
View File
@@ -0,0 +1,44 @@
**#%#*****###%**
*##+--------------------=##*
#*=----------------------------=*#*
#*------------------------------------*#
%+----------------------------------------=#*
#+---------------------------------------------##
*#-------------------------------------------------=##
*#----------------------------------------------------:-##
#----------------------------------------------------------##
#=-------------------------------------------------------------##
#----------------------------==----------------------------------=#*
+--------------------------+@#-%*-----------------------------------#*
+--------------------------%@@@@#-------------------------------------**
*-=-------------------------#@@*---------------------------------------=%
%*#==--------------------------------------------------------------------+#
*%%=-=--------------------------------------------------------------------=#
%=--------------------------------------------------------------------------#*
%-----------------------------------------------------------------------------**
*+--=---===----=---------------=*-----------------------------------------------**
#--=## *#%#*+==----==+**+----------------------= ***=---------------------%
*%**=-----------==== ==---------------------------------=+#+-----------------=#
*%=----------------------------------------------------------=#*---------------#
##=----------------------------------=------------------------+%=------------+#
#%+---------------------------------=*------------------------+%------------#
*#%*=-------------=-----------------#-------------------------#+----------#
**#%#*******+=======-------------#=------------------------#----------#
#===#*=======------------------#*----=-----------=--=##*-----------#
-====##=------------------------*%+------------=*#+=====----------#
--=====+#*=----------------------=-=+*#####***+=======-----------=*
%------=====*%*=-------------------------========-----------------+*
*-=--------====%%###+=--------------------------=-----------------#
#-----------=% +*##%%%%%%@@%%%%####*==---------------------**
%=-------#* #%*=-----------------+#
*%+--=## ##=-----------------=#*
** #+----=-------------------#*
%+----------------------------#*
*%-------------==----------------+#
##--------------==------------------#
*#--------------===%-----------------=%
##---------------=-##*-----------------+#
*#---------------==#+=#%-----------------%
*%---------------+# %*---------------#*
*#------------=+#* #%*=-----------#*
#****##****** *#%%##+=----%
+13
View File
@@ -0,0 +1,13 @@
(define TAB-LENGTH 2)
(define QUIT-TIMES 1)
(map-key "CTRL-q" editor-quit)
(map-key "CTRL-s" editor-save)
(map-key "ARROW-UP" '(move-cursor "up"))
(map-key "ARROW-DOWN" '(move-cursor "down"))
(map-key "ARROW-RIGHT" '(move-cursor "right"))
(map-key "ARROW-LEFT" '(move-cursor "left"))
(map-key "ENTER" editor-insert-new-line)
(map-key "CTRL-a" move-cursor-beg-line)
(map-key "CTRL-e" move-cursor-end-line)
+22
View File
@@ -0,0 +1,22 @@
#ifndef BUILTINS_H_
#define BUILTINS_H_
#include "../lisp-interpreter/dist/lisp.h"
Lisp moveCursor(Lisp args, LispError *e, LispContext ctx);
Lisp mapKey(Lisp args, LispError *e, LispContext ctx);
void registerBuiltin(char * key_sequence, LispCFunc f);
Lisp editorQuit(Lisp args, LispError *e, LispContext ctx);
Lisp l_editorSave(Lisp args, LispError *e, LispContext ctx);
Lisp l_editorInsertNewLine(Lisp args, LispError* e, LispContext ctx);
Lisp moveCursorBeginLine(Lisp args, LispError *e, LispContext ctx);
Lisp moveCursorEndLine(Lisp args, LispError* e, LispContext ctx);
#endif
+24 -1
View File
@@ -1,10 +1,12 @@
#ifndef DATA_H_ #ifndef DATA_H_
#define DATA_H_ #define DATA_H_
#include "../lisp-interpreter/dist/lisp.h" #include <stdio.h>
#include <termios.h> #include <termios.h>
#include <time.h> #include <time.h>
#include "../lisp-interpreter/dist/lisp.h"
/** /**
* \struct erow * \struct erow
* \brief Store one editor row * \brief Store one editor row
@@ -18,6 +20,18 @@ typedef struct erow {
char *render; /**< The actual line we will print */ char *render; /**< The actual line we will print */
} erow; } erow;
struct const_t {
int TAB_LENGTH;
int QUIT_TIMES;
};
struct keyBind_t {
char *key_sequence;
Lisp command;
};
/** /**
* \struct editorConfig * \struct editorConfig
* \brief Containing our editor state. * \brief Containing our editor state.
@@ -36,9 +50,18 @@ struct editorConfig {
char status_msg[80]; char status_msg[80];
time_t status_msg_time; time_t status_msg_time;
struct termios orig_termios; /**< Terminal communication interface */ struct termios orig_termios; /**< Terminal communication interface */
struct const_t constantes;
int quit_times_buffer;
FILE *fd_init_file;
Lisp env;
LispContext ctx; /** Lisp context */ LispContext ctx; /** Lisp context */
Lisp ctx_data; /** Lisp data context */ Lisp ctx_data; /** Lisp data context */
LispError ctx_error; /** Lisp ctx error */ LispError ctx_error; /** Lisp ctx error */
struct keyBind_t* key_binds;
int number_of_keybinds;
}; };
/** /**
-2
View File
@@ -25,7 +25,5 @@ enum editorKey {
#define ABUF_INIT {NULL, 0} #define ABUF_INIT {NULL, 0}
#define BELUGA_VERSION "1.0" #define BELUGA_VERSION "1.0"
#define TAB_LENGTH 4
#define QUIT_TIMES 1
#endif // DEFINE_H_ #endif // DEFINE_H_
+2
View File
@@ -10,6 +10,8 @@
* \brief Job's function is to initialize all the fields of editorConfig. * \brief Job's function is to initialize all the fields of editorConfig.
* */ * */
void initBuiltins();
void initEditor(); void initEditor();
#endif // INIT_H_ #endif // INIT_H_
+4
View File
@@ -21,8 +21,12 @@
char *editorPrompt(char *prompt); char *editorPrompt(char *prompt);
char *key_to_string(int key);
void editorMoveCursor(int key); void editorMoveCursor(int key);
int executeKeyBind(char *key_sequence);
/** /**
* \fn void editorProcessKeypress() * \fn void editorProcessKeypress()
* \brief Get the last key input and do the proper action. * \brief Get the last key input and do the proper action.
+1
View File
@@ -5,6 +5,7 @@
* interactions. \version 0.1 \date 21 septembre 2024 * interactions. \version 0.1 \date 21 septembre 2024
*/ */
#include <stdio.h>
#define _DEFAULT_SOURCE #define _DEFAULT_SOURCE
#define _BSD_SOURCE #define _BSD_SOURCE
#define _GNU_SOURCE #define _GNU_SOURCE
+1
View File
@@ -22,6 +22,7 @@ src_files = files(
'src/output.c', 'src/output.c',
'src/row_op.c', 'src/row_op.c',
'src/terminal.c', 'src/terminal.c',
'src/builtins.c',
) )
# Executable # Executable
+95
View File
@@ -0,0 +1,95 @@
#include "../include/builtins.h"
#include "../include/define.h"
#include "../include/input.h"
#include "../include/file_io.h"
#include "../include/editor_op.h"
#include "../include/data.h"
#include <stdlib.h>
#include <string.h>
Lisp mapKey(Lisp args, LispError *e, LispContext ctx) {
const char* key_sequence = lisp_string(lisp_car(args));
args = lisp_cdr(args);
// second argument
Lisp func = lisp_car(args);
E.key_binds =
(struct keyBind_t *)realloc(E.key_binds, ++E.number_of_keybinds * sizeof(struct keyBind_t));
E.key_binds[E.number_of_keybinds - 1].key_sequence = (char *) malloc(50 * sizeof(char));
strncpy(E.key_binds[E.number_of_keybinds - 1].key_sequence, key_sequence, 50);
E.key_binds[E.number_of_keybinds - 1].command = func;
return lisp_null();
}
Lisp moveCursor(Lisp args, LispError* e, LispContext ctx) {
const char *direction = lisp_string(lisp_car(args));
switch (direction[0]) {
case 'u':
editorMoveCursor(ARROW_UP);
break;
case 'd':
editorMoveCursor(ARROW_DOWN);
break;
case 'r':
editorMoveCursor(ARROW_RIGHT);
break;
case 'l':
editorMoveCursor(ARROW_LEFT);
break;
}
return lisp_null();
}
Lisp editorQuit(Lisp args, LispError* e, LispContext ctx) {
if (E.dirty && E.quit_times_buffer > 0) {
editorSetStatusMessage("WARNING! Changes hasn't been saved. Press Ctrl-Q "
"another time to quit.");
--E.quit_times_buffer;
return lisp_null();
}
write(STDOUT_FILENO, "\x1b[2J", 4);
write(STDOUT_FILENO, CURSOR_TOP_LEFT, 3);
disableRawMode();
exit(0);
return lisp_null();
}
Lisp l_editorSave(Lisp args, LispError* e, LispContext ctx) {
editorSave();
return lisp_null();
}
Lisp l_editorInsertNewLine(Lisp args, LispError* e, LispContext ctx) {
editorInsertNewLine();
return lisp_null();
}
Lisp moveCursorBeginLine(Lisp args, LispError *e, LispContext ctx) {
E.cursor_x = 0;
return lisp_null();
}
Lisp moveCursorEndLine(Lisp args, LispError* e, LispContext ctx) {
if (E.cursor_y < E.numrows) {
E.cursor_x = E.row[E.cursor_y].size;
}
return lisp_null();
}
+1
View File
@@ -1,5 +1,6 @@
#include "../include/editor_op.h" #include "../include/editor_op.h"
#include "../include/row_op.h" #include "../include/row_op.h"
#include <stdio.h>
extern struct editorConfig E; extern struct editorConfig E;
+1 -1
View File
@@ -42,7 +42,7 @@ void editorOpen(char *filename) {
free(E.filename); free(E.filename);
E.filename = strdup(filename); E.filename = strdup(filename);
fp = fopen(filename, "r"); fp = fopen(filename, "a+");
if (!fp) if (!fp)
die("fopen"); die("fopen");
+54 -4
View File
@@ -1,9 +1,35 @@
#include "../include/init.h" #include "../include/init.h"
#include "../include/data.h" #include "../include/data.h"
#include "../include/terminal.h"
#include "../include/builtins.h"
#include <stdio.h> #include <stdio.h>
#define LISP_IMPLEMENTATION
#include "../lisp-interpreter/dist/lisp.h"
#include "../lisp-interpreter/dist/lisp_lib.h"
extern struct editorConfig; extern struct editorConfig;
void registerBuiltin(char *key_sequence, LispCFunc f) {
lisp_env_define(E.ctx.p->env, lisp_make_symbol(key_sequence, E.ctx),
lisp_make_func(f), E.ctx);
}
void initBuiltins() {
// move cursor
registerBuiltin("MOVE-CURSOR", moveCursor);
registerBuiltin("MAP-KEY", mapKey);
registerBuiltin("EDITOR-QUIT", editorQuit);
registerBuiltin("EDITOR-SAVE", l_editorSave);
registerBuiltin("EDITOR-INSERT-NEW-LINE", l_editorInsertNewLine);
registerBuiltin("MOVE-CURSOR-BEG-LINE", moveCursorBeginLine);
registerBuiltin("MOVE-CURSOR-END-LINE", moveCursorEndLine);
}
void initEditor() { void initEditor() {
E.cursor_x = 0; E.cursor_x = 0;
E.cursor_y = 0; E.cursor_y = 0;
@@ -21,9 +47,33 @@ void initEditor() {
} }
E.screenrows -= 2; E.screenrows -= 2;
// E.fd_init_file = fopen("../config/init.el", "r"); E.number_of_keybinds = 0;
// E.ctx = lisp_init();
// E.ctx_data = lisp_read_file(E.fd_init_file, &E.ctx_error, E.ctx); E.fd_init_file = fopen("config/init.el", "r");
// lisp_printf(stderr, E.ctx_data); E.ctx = lisp_init();
E.env = lisp_env(E.ctx);
lisp_lib_load(E.ctx);
// Init builtins lisp functions
initBuiltins();
// Read config file
E.ctx_data = lisp_read_file(E.fd_init_file, &E.ctx_error, E.ctx);
if (E.ctx_error != LISP_ERROR_NONE) {
die("init failed");
}
lisp_eval(E.ctx_data, &E.ctx_error, E.ctx);
// To modify
E.constantes.TAB_LENGTH =
(int)lisp_eval(lisp_read("TAB-LENGTH", &E.ctx_error, E.ctx), &E.ctx_error,
E.ctx)
.val.int_val;
E.constantes.QUIT_TIMES =
(int)lisp_eval(lisp_read("QUIT-TIMES", &E.ctx_error, E.ctx), &E.ctx_error,
E.ctx)
.val.int_val;
E.quit_times_buffer = E.constantes.QUIT_TIMES;
} }
+85 -73
View File
@@ -1,11 +1,13 @@
#include "../include/input.h" #include "../include/input.h"
#include "../include/editor_op.h" #include "../include/editor_op.h"
#include "../include/file_io.h"
#include "../include/output.h" #include "../include/output.h"
#include "../include/define.h"
#include "data.h"
#include <ctype.h> #include <ctype.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <unistd.h> #include <unistd.h>
extern struct editorConfig E; extern struct editorConfig E;
@@ -30,7 +32,6 @@ char *editorPrompt(char *prompt) {
buf[--buf_len] = '\0'; buf[--buf_len] = '\0';
} }
} else if (c == ESCAPE) { } else if (c == ESCAPE) {
fprintf(stderr, "escape");
editorSetStatusMessage(""); editorSetStatusMessage("");
free(buf); free(buf);
return NULL; return NULL;
@@ -50,6 +51,70 @@ char *editorPrompt(char *prompt) {
} }
} }
char *key_to_string(int key) {
static char key_str[32];
char tmp[10];
sprintf(tmp, "%d", key);
// First test enter key
if (key == '\r') {
strcpy(key_str, "ENTER");
} else if (key >= 1 && key <= 26) { // CTRL keys
snprintf(key_str, sizeof(key_str), "CTRL-%c", 'a' + key - 1);
} else {
switch (key) {
case ARROW_UP:
strcpy(key_str, "ARROW-UP");
break;
case ARROW_DOWN:
strcpy(key_str, "ARROW-DOWN");
break;
case ARROW_LEFT:
strcpy(key_str, "ARROW-LEFT");
break;
case ARROW_RIGHT:
strcpy(key_str, "ARROW-RIGHT");
break;
case PAGE_UP:
strcpy(key_str, "PAGE-UP");
break;
case PAGE_DOWN:
strcpy(key_str, "PAGE-DOWN");
break;
case DEL_KEY:
strcpy(key_str, "DEL");
break;
case BACKSPACE:
strcpy(key_str, "BACKSPACE");
break;
case '\r':
strcpy(key_str, "ENTER");
break;
case '\x1b':
strcpy(key_str, "ESCAPE");
break;
case BEG_LINE:
strcpy(key_str, "HOME");
break;
case END_LINE:
strcpy(key_str, "END");
break;
default:
// For regular characters
if (isprint(key)) {
snprintf(key_str, sizeof(key_str), "%c", key);
} else {
snprintf(key_str, sizeof(key_str), "KEY-%d", key);
}
}
}
return key_str;
}
void editorMoveCursor(int key) { void editorMoveCursor(int key) {
erow *row = (E.cursor_y >= E.numrows) ? NULL : &E.row[E.cursor_y]; erow *row = (E.cursor_y >= E.numrows) ? NULL : &E.row[E.cursor_y];
int row_len; int row_len;
@@ -89,81 +154,28 @@ void editorMoveCursor(int key) {
} }
} }
int executeKeyBind(char *key_sequence) {
int i;
for (i = 0; i < E.number_of_keybinds; ++i) {
if (!strcmp(key_sequence, E.key_binds[i].key_sequence)) {
fprintf(stderr, "lisp function %s\n", key_sequence);
// It's a symbol, create a function call
lisp_eval(lisp_cons(E.key_binds[i].command, lisp_null(), E.ctx),
&E.ctx_error, E.ctx);
return 1;
}
}
return 0;
}
void editorProcessKeypress() { void editorProcessKeypress() {
static int quit_times = QUIT_TIMES;
int c = editorReadKey(); int c = editorReadKey();
int times;
switch (c) { if (executeKeyBind(key_to_string(c))) {
case '\r':
editorInsertNewLine();
break;
case CTRL_KEY('q'):
if (E.dirty && quit_times > 0) {
editorSetStatusMessage("WARNING! Changes hasn't been saved. Press Ctrl-Q "
"another time to quit.");
--quit_times;
return; return;
} }
write(STDOUT_FILENO, "\x1b[2J", 4);
write(STDOUT_FILENO, CURSOR_TOP_LEFT, 3);
disableRawMode();
exit(0);
break;
case CTRL_KEY('s'):
editorSave();
break;
case BEG_LINE:
E.cursor_x = 0;
break;
case END_LINE:
if (E.cursor_y < E.numrows) {
E.cursor_x = E.row[E.cursor_y].size;
}
break;
case BACKSPACE:
case CTRL_KEY('h'):
case DEL_KEY:
if (c == DEL_KEY) {
editorMoveCursor(ARROW_RIGHT);
}
editorDelChar();
break;
case PAGE_UP:
case PAGE_DOWN: {
if (c == PAGE_UP) {
E.cursor_y = E.row_offset;
} else if (c == PAGE_DOWN) {
E.cursor_y = E.row_offset + E.screenrows - 1;
if (E.cursor_y > E.numrows) {
E.cursor_y = E.numrows;
}
}
times = E.screenrows;
while (--times) {
editorMoveCursor(c == PAGE_UP ? ARROW_UP : ARROW_DOWN);
}
} break;
case ARROW_UP:
case ARROW_DOWN:
case ARROW_LEFT:
case ARROW_RIGHT:
editorMoveCursor(c);
break;
case CTRL_KEY('l'):
case '\x1b':
break;
default:
editorInsertChar(c); editorInsertChar(c);
break; E.quit_times_buffer = E.constantes.QUIT_TIMES;
}
quit_times = QUIT_TIMES;
} }
+12 -6
View File
@@ -1,4 +1,6 @@
#include "../include/row_op.h" #include "../include/row_op.h"
#include "data.h"
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
@@ -10,7 +12,7 @@ int editorRowCxToRx(erow *row, int cursor_x) {
int i; int i;
for (i = 0; i < cursor_x; ++i) { for (i = 0; i < cursor_x; ++i) {
if (row->chars[i] == '\t') { if (row->chars[i] == '\t') {
render_x += (TAB_LENGTH - 1) - (render_x % TAB_LENGTH); render_x += (E.constantes.TAB_LENGTH - 1) - (render_x % E.constantes.TAB_LENGTH);
} }
render_x++; render_x++;
} }
@@ -34,8 +36,8 @@ void editorUpdateRow(erow *row) {
} }
free(row->render); free(row->render);
row->render = malloc(row->size + tabs * (TAB_LENGTH - 1) + row->render = malloc(row->size + tabs * (E.constantes.TAB_LENGTH - 1) +
1); /**< Tabs needs TAB_LENGTH chars so TAB_LENGTH - 1 1); /**< Tabs needs E.constantes.TAB_LENGTH chars so E.constantes.TAB_LENGTH - 1
more than the first already counted. */ more than the first already counted. */
// end of counting // end of counting
@@ -43,7 +45,7 @@ void editorUpdateRow(erow *row) {
for (i = 0; i < row->size; ++i) { for (i = 0; i < row->size; ++i) {
if (row->chars[i] == '\t') { if (row->chars[i] == '\t') {
row->render[i_render++] = ' '; row->render[i_render++] = ' ';
while (i_render % TAB_LENGTH) { while (i_render % E.constantes.TAB_LENGTH) {
row->render[i_render++] = row->render[i_render++] =
' '; /**< Addind the right amount of spaces for tabs */ ' '; /**< Addind the right amount of spaces for tabs */
} }
@@ -57,10 +59,14 @@ void editorUpdateRow(erow *row) {
void editorInsertRow(int at, char *s, size_t len) { void editorInsertRow(int at, char *s, size_t len) {
if (at < 0 || at > E.numrows) { if (at < 0 || at > E.numrows) {
return; return;
} }
erow *tmp = (erow *)realloc(E.row, sizeof(erow) * (E.numrows + 1));
E.row = realloc(E.row, sizeof(erow) * (E.numrows + 1)); if (!tmp) {
return;
}
E.row = tmp;
memmove(&E.row[at + 1], &E.row[at], sizeof(erow) * (E.numrows - at)); memmove(&E.row[at + 1], &E.row[at], sizeof(erow) * (E.numrows - at));
E.row[at].size = len; E.row[at].size = len;
+1
View File
@@ -6,6 +6,7 @@
void die(const char *s) { void die(const char *s) {
write(STDOUT_FILENO, "\x1b[2J", 4); write(STDOUT_FILENO, "\x1b[2J", 4);
write(STDOUT_FILENO, CURSOR_TOP_LEFT, 3); write(STDOUT_FILENO, CURSOR_TOP_LEFT, 3);
lisp_shutdown(E.ctx);
perror(s); perror(s);
exit(1); exit(1);
} }