17 Commits

Author SHA1 Message Date
Arthur Barraux ce94e9fb87 permission files
Build and Deploy Docs / build (push) Failing after 43s
2025-10-06 11:28:49 +02:00
Arthur Barraux 29a92ce904 Merge Lisp branch
Build and Deploy Docs / build (push) Failing after 1m24s
2025-10-05 22:05:21 +02:00
Arthur Barraux 9348ae668a Add open file key-bind
Build and Deploy Docs / build (push) Failing after 40s
2025-10-05 21:44:58 +02:00
Arthur Barraux 9157b94398 Adding usefull keybinds
Build and Deploy Docs / build (push) Successful in 50s
2025-10-02 14:59:28 +02:00
Arthur Barraux 3b6c60a49e functional lisp config files
Build and Deploy Docs / build (push) Successful in 47s
2025-10-02 11:26:18 +02:00
arthur 53d6572c8c Revert doxygen deployement
Build and Deploy Docs / build (push) Successful in 37s
2025-09-25 12:10:44 +02:00
arthur d083948dfe Update .gitea/workflows/build.yml
Build and Deploy Docs / build (push) Failing after 30s
2025-09-25 11:35:41 +02:00
arthur 09ef5c0f3b Update .gitea/workflows/build.yml
Build and Deploy Docs / build (push) Failing after 1m26s
2025-09-25 11:25:52 +02:00
arthur e4691669b8 Update .gitea/workflows/build.yml
Build and Deploy Docs / build (push) Failing after 1m54s
2025-09-25 11:22:11 +02:00
arthur 27ae0a684f Update .gitea/workflows/build.yml
Build and Deploy Docs / build (push) Failing after 1m33s
2025-09-25 11:06:53 +02:00
Arthur Barraux 3505084527 second try
Meson Build and Deploy / build (push) Failing after 1m23s
2025-09-25 11:00:53 +02:00
Arthur Barraux 02d7f27ec3 Merge remote-tracking branch 'gitea/lisp' into lisp
Meson Build and Deploy / build (push) Failing after 53s
2025-09-25 10:48:09 +02:00
Arthur Barraux 7dded62db9 add doxygen deployement 2025-09-25 10:47:07 +02:00
Arthur Barraux 72178adebb submodeule update 2025-06-12 16:56:10 +02:00
Arthur Barraux 7a98f89531 readme update 2025-06-12 16:53:21 +02:00
Arthur Barraux 3e562c1071 add blisp submodule 2025-06-02 10:36:22 +02:00
Arthur Barraux bff3f84ecd Configurable settings with blisp 2025-06-02 10:31:31 +02:00
20 changed files with 683 additions and 318 deletions
+1 -8
View File
@@ -1,9 +1,8 @@
name: Meson Build and Deploy name: Build and Deploy Docs
on: on:
push: push:
branches: ["lisp"] branches: ["lisp"]
pull_request:
jobs: jobs:
build: build:
@@ -28,9 +27,3 @@ jobs:
- name: Run tests - name: Run tests
run: meson test -C build --print-errorlogs || true run: meson test -C build --print-errorlogs || true
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: beluga
path: build/
+2 -2
View File
@@ -1,3 +1,3 @@
tmp/* build/*
bin/*
doc/* doc/*
beluga.wiki/*
+4 -4
View File
@@ -4,17 +4,17 @@ Beluga is a project of CLI text editor that will fit perfectly with your azerty
## Requirements ## Requirements
You will only need **make** or **gcc** to compile the editor. You will only need **cmake** and **clang** to compile the editor.
## Installation ## Installation
Here is the installation line : Here is the installation line for development version:
```git clone --branch V1.0 --single-branch https://github.com/le-cocotier/beluga.git ~/.beluga && cd ~/.beluga && make build``` ```git clone --recurse-submodules https://github.com/le-cocotier/beluga.git ~/.beluga && cd ~/.beluga && mkdir build && cd build && cmake ../ && make beluga```
The executable file will be in `bin/beluga`. Feel free to add it to your path. The executable file will be in `bin/beluga`. Feel free to add it to your path.
You can either run `make all` if you're interested by the doxygen documentation. You can either run `make all` or `make doc_doxygen` if you're interested by the doxygen documentation.
## Getting start ## Getting start
+43
View File
@@ -0,0 +1,43 @@
**#%#*****###%**
*##+--------------------=##*
#*=----------------------------=*#*
#*------------------------------------*#
%+----------------------------------------=#*
#+---------------------------------------------##
*#-------------------------------------------------=##
*#----------------------------------------------------:-##
#----------------------------------------------------------##
#=--------------------------------------------------------------##
+--------------------------+@#-%*-----------------------------------#*
+--------------------------%@@@@#-------------------------------------** BELUGA - VERSION 1.1
*-=-------------------------#@@*---------------------------------------=%
%*#==--------------------------------------------------------------------+# ----- KEY-BINDS -----
*%%=-=--------------------------------------------------------------------=# CTRL-q leave
%=--------------------------------------------------------------------------#* CTRL-s save
%-----------------------------------------------------------------------------** CTRL-o open-file
*+--=---===----=---------------=*-----------------------------------------------**
#--=## *#%#*+==----==+**+----------------------= ***=---------------------%
*%**=-----------==== ==---------------------------------=+#+-----------------=#
*%=----------------------------------------------------------=#*---------------#
##=----------------------------------=------------------------+%=------------+#
#%+---------------------------------=*------------------------+%------------#
*#%*=-------------=-----------------#-------------------------#+----------#
**#%#*******+=======-------------#=------------------------#----------#
#===#*=======------------------#*----=-----------=--=##*-----------#
-====##=------------------------*%+------------=*#+=====----------#
--=====+#*=----------------------=-=+*#####***+=======-----------=*
%------=====*%*=-------------------------========-----------------+*
*-=--------====%%###+=--------------------------=-----------------#
#-----------=% +*##%%%%%%@@%%%%####*==---------------------**
%=-------#* #%*=-----------------+#
*%+--=## ##=-----------------=#*
** #+----=-------------------#*
%+----------------------------#*
*%-------------==----------------+#
##--------------==------------------#
*#--------------===%-----------------=%
##---------------=-##*-----------------+#
*#---------------==#+=#%-----------------%
*%---------------+# %*---------------#*
*#------------=+#* #%*=-----------#*
#****##****** *#%%##+=----%
+34
View File
@@ -0,0 +1,34 @@
;; MACROS
(define TAB-LENGTH 4)
(define QUIT-TIMES 1)
;; FUNCTIONS
(define editor-delete-next-char (lambda () (
(move-cursor "right")
(editor-delete-previous-char)
)
)
)
;; KEY MAPPING
(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)
(map-key "BACKSPACE" editor-delete-previous-char)
(map-key "DEL" editor-delete-next-char)
(map-key "PAGE-UP" move-cursor-page-up)
(map-key "PAGE-DOWN" move-cursor-page-down)
(map-key "CTRL-o" editor-open-file)
+32
View File
@@ -0,0 +1,32 @@
#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);
Lisp deletePreviousChar(Lisp args, LispError *e, LispContext ctx);
Lisp editorMoveCursorPageUp(Lisp args, LispError* e, LispContext ctx);
Lisp editorMoveCursorPageDown(Lisp args, LispError *e, LispContext ctx);
Lisp editorOpenFile(Lisp args, LispError *e, LispContext ctx);
Lisp editorPrintC(Lisp args, LispError *e, LispContext ctx);
#endif
+32 -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,23 @@ typedef struct erow {
char *render; /**< The actual line we will print */ char *render; /**< The actual line we will print */
} erow; } erow;
enum editorStatus_e {
IDLE,
READ_ONLY,
READ_AND_WRITE,
};
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.
@@ -33,12 +52,23 @@ struct editorConfig {
erow *row; /**< Store all the rows printed */ erow *row; /**< Store all the rows printed */
int dirty; int dirty;
char *filename; char *filename;
enum editorStatus_e state;
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;
}; };
/** /**
@@ -53,4 +83,5 @@ struct abuf {
extern struct editorConfig E; extern struct editorConfig E;
#endif #endif
+1 -3
View File
@@ -24,8 +24,6 @@ enum editorKey {
#define ABUF_INIT {NULL, 0} #define ABUF_INIT {NULL, 0}
#define BELUGA_VERSION "1.0" #define BELUGA_VERSION "1.1"
#define TAB_LENGTH 4
#define QUIT_TIMES 1
#endif // DEFINE_H_ #endif // DEFINE_H_
+3
View File
@@ -10,6 +10,9 @@
char *editorRowsToString(int *buffer_len); char *editorRowsToString(int *buffer_len);
void editorCloseFile(void);
void editorOpen(char *filename); void editorOpen(char *filename);
void editorSave(); void editorSave();
+3
View File
@@ -1,6 +1,7 @@
#ifndef INIT_H_ #ifndef INIT_H_
#define INIT_H_ #define INIT_H_
#include "builtins.h"
#include "data.h" #include "data.h"
#include "terminal.h" #include "terminal.h"
#include <stdio.h> #include <stdio.h>
@@ -10,6 +11,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_
+5
View File
@@ -5,6 +5,7 @@
#include "define.h" #include "define.h"
#include "output.h" #include "output.h"
#include "terminal.h" #include "terminal.h"
#include "builtins.h"
#include <unistd.h> #include <unistd.h>
// KEYS keycode // KEYS keycode
@@ -21,8 +22,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.
+6
View File
@@ -5,6 +5,8 @@
* interactions. \version 0.1 \date 21 septembre 2024 * interactions. \version 0.1 \date 21 septembre 2024
*/ */
#include <unistd.h>
#define _DEFAULT_SOURCE #define _DEFAULT_SOURCE
#define _BSD_SOURCE #define _BSD_SOURCE
#define _GNU_SOURCE #define _GNU_SOURCE
@@ -23,11 +25,15 @@ int main(int argc, char *argv[]) {
enableRawMode(); enableRawMode();
initEditor(); initEditor();
if (argc >= 2) { if (argc >= 2) {
E.state = READ_AND_WRITE;
editorOpen(argv[1]); editorOpen(argv[1]);
} else {
editorOpen("assets/beluga.txt");
} }
editorSetStatusMessage("HELP: Ctrl-S = save | Ctrl-Q = quit"); editorSetStatusMessage("HELP: Ctrl-S = save | Ctrl-Q = quit");
while (1) { while (1) {
editorRefreshScreen(); editorRefreshScreen();
editorProcessKeypress(); editorProcessKeypress();
+6 -30
View File
@@ -1,39 +1,15 @@
project('editor', 'c', project('beluga', 'c',
version : '1.0.0', version : '1.1',
default_options : [ default_options : [
'warning_level=2', 'c_std=none',
] ]
) )
# Check if we're using Clang and add Clang-specific options
cc = meson.get_compiler('c') cc = meson.get_compiler('c')
m = cc.find_library('m', required: true) m = cc.find_library('m', required: false)
if cc.get_id() == 'clang'
add_project_arguments([
'-Wextra',
'-Wpedantic',
'-Wno-unused-parameter',
'-fcolor-diagnostics' # Colored output
], language : 'c')
# Add debug options for debug builds
if get_option('buildtype') == 'debug'
add_project_arguments([
'-fsanitize=address', # AddressSanitizer
'-fsanitize=undefined', # UndefinedBehaviorSanitizer
'-g3', # Full debug info
'-O0' # No optimization
], language : 'c')
add_project_link_arguments([
'-fsanitize=address',
'-fsanitize=undefined'
], language : 'c')
endif
endif
# Include directory # Include directory
inc_dir = include_directories('include') inc_dir = include_directories('include', 'lisp-interpreter/dist')
# Source files # Source files
src_files = files( src_files = files(
@@ -46,12 +22,12 @@ 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
executable('beluga', executable('beluga',
src_files, src_files,
include_directories : inc_dir, include_directories : inc_dir,
install : true,
dependencies: [m] dependencies: [m]
) )
+141
View File
@@ -0,0 +1,141 @@
#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 <stdio.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) {
fprintf(stderr, "Cursor is moving\n");
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();
}
Lisp deletePreviousChar(Lisp args, LispError* e, LispContext ctx) {
editorDelChar();
return lisp_null();
}
Lisp editorMoveCursorPageUp(Lisp args, LispError* e, LispContext ctx) {
E.cursor_y = E.row_offset;
int times = E.screenrows;
while (--times) {
editorMoveCursor(ARROW_UP);
}
return lisp_null();
}
Lisp editorMoveCursorPageDown(Lisp args, LispError* e, LispContext ctx) {
E.cursor_y = E.row_offset + E.screenrows - 1;
if (E.cursor_y > E.numrows) {
E.cursor_y = E.numrows;
}
int times = E.screenrows;
while (--times) {
editorMoveCursor(ARROW_DOWN);
}
return lisp_null();
}
Lisp editorOpenFile(Lisp args, LispError *e, LispContext ctx) {
char *filename = editorPrompt("Path : %s");
if (filename)
editorOpen(filename);
return lisp_null();
}
Lisp editorPrintC(Lisp args, LispError *e, LispContext ctx) {
char c = lisp_char(lisp_car(args));
editorInsertChar(c);
return lisp_null();
}
+2
View File
@@ -1,5 +1,7 @@
#include "../include/editor_op.h" #include "../include/editor_op.h"
#include "../include/row_op.h" #include "../include/row_op.h"
#include "data.h"
extern struct editorConfig E; extern struct editorConfig E;
+22 -1
View File
@@ -1,6 +1,7 @@
#include "../include/file_io.h" #include "../include/file_io.h"
#include "../include/input.h" #include "../include/input.h"
#include "../include/output.h" #include "../include/output.h"
#include "data.h"
#include <fcntl.h> #include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -36,13 +37,33 @@ char *editorRowsToString(int *buffer_len) {
return buf; return buf;
} }
void editorCloseFile(void) {
E.cursor_x = 0;
E.cursor_y = 0;
E.rx = 0;
E.row_offset = 0;
E.col_offset = 0;
E.numrows = 0;
E.row = NULL;
E.dirty = 0;
E.filename = NULL;
E.status_msg[0] = '\0';
E.status_msg_time = 0;
}
void editorOpen(char *filename) { void editorOpen(char *filename) {
FILE *fp; FILE *fp;
// Test if a file is already open
if (E.filename != NULL) {
editorCloseFile();
E.state = READ_AND_WRITE;
}
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");
+58 -4
View File
@@ -1,9 +1,38 @@
#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);
registerBuiltin("EDITOR-DELETE-PREVIOUS-CHAR", deletePreviousChar);
registerBuiltin("MOVE-CURSOR-PAGE-UP", editorMoveCursorPageUp);
registerBuiltin("MOVE-CURSOR-PAGE-DOWN", editorMoveCursorPageDown);
registerBuiltin("EDITOR-OPEN-FILE", editorOpenFile);
registerBuiltin("EDITOR-INSERT-CHAR", editorPrintC);
}
void initEditor() { void initEditor() {
E.cursor_x = 0; E.cursor_x = 0;
E.cursor_y = 0; E.cursor_y = 0;
@@ -14,6 +43,7 @@ void initEditor() {
E.row = NULL; E.row = NULL;
E.dirty = 0; E.dirty = 0;
E.filename = NULL; E.filename = NULL;
E.state = READ_ONLY;
E.status_msg[0] = '\0'; E.status_msg[0] = '\0';
E.status_msg_time = 0; E.status_msg_time = 0;
if (getWindowSize(&E.screenrows, &E.screencols) == -1) { if (getWindowSize(&E.screenrows, &E.screencols) == -1) {
@@ -21,9 +51,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.lisp", "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;
} }
+87 -73
View File
@@ -1,11 +1,12 @@
#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 <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 +31,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 +50,73 @@ 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");
fprintf(stderr, "pagr up\n");
break;
case PAGE_DOWN:
strcpy(key_str, "PAGE-DOWN");
break;
case DEL_KEY:
fprintf(stderr, "delete key\n");
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 +156,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;
} }
+14 -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;
@@ -96,6 +102,8 @@ void editorDelRow(int at) {
* \param at Index of where we want to insert the char */ * \param at Index of where we want to insert the char */
void editorRowInsertChar(erow *row, int at, int c) { void editorRowInsertChar(erow *row, int at, int c) {
if (E.state == READ_ONLY)
return;
if (at < 0 || at > row->size) { if (at < 0 || at > row->size) {
at = row->size; at = row->size;
} }
+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);
} }