24 Commits

Author SHA1 Message Date
Arthur Barraux 756deba83e remove .cache repo for cleaning
Build project / build (push) Failing after 33s
2025-10-18 15:12:06 +02:00
Arthur Barraux 85e8067e41 clean up the repo
Build project / build (push) Failing after 1m22s
2025-10-18 15:06:23 +02:00
Arthur Barraux 09d78f48e9 Merge remote-tracking branch 'gitea/lisp'
Build project / build (push) Successful in 1m3s
2025-10-06 11:37:39 +02:00
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 6cd79b5c76 downgrade version of runner upload
Meson Build and Deploy / build (push) Successful in 25s
2025-09-24 11:14:22 +02:00
Arthur Barraux 8844d2f064 meson bulid changes
Meson Build and Deploy / build (push) Failing after 29s
2025-09-24 11:04:16 +02:00
Arthur Barraux d8fc7d2d67 adding lisp-interpreter
Meson Build and Deploy / build (push) Failing after 29s
2025-09-24 10:58:09 +02:00
Arthur Barraux ab482df604 get submodules
Meson Build and Deploy / build (push) Failing after 1m31s
2025-09-24 10:48:45 +02:00
Arthur Barraux be31e83fb9 update build.yml
Meson Build and Deploy / build (push) Failing after 1m21s
2025-09-24 10:45:11 +02:00
Arthur Barraux 54db6321ad add CI/CD config
Meson Build and Deploy / build (push) Failing after 1m54s
2025-09-24 10:29:31 +02:00
Arthur Barraux 8ce621dfde Made Editor Config global 2025-09-19 14:31:12 +02:00
Arthur Barraux 91e247d1de adding meson build 2025-09-19 11:02:44 +02:00
31 changed files with 6101 additions and 611 deletions
+8 -4
View File
@@ -1,9 +1,8 @@
name: CMake Build and Deploy name: Build project
on: on:
push: push:
branches: ["main"] branches: ["main"]
pull_request:
jobs: jobs:
build: build:
@@ -12,14 +11,19 @@ jobs:
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v4
with:
tokens: ${{ secrets.GITEA_TOKEN }}
- name: Install dependencies - name: Install dependencies
run: | run: |
sudo apt-get update sudo apt-get update
sudo apt-get install -y cmake build-essential sudo apt-get install -y meson ninja-build gcc
- name: Configure Meson
run: meson setup build
- name: Build project - name: Build project
run: cmake --build build -- -j$(nproc) run: meson compile -C build
- name: Run tests - name: Run tests
run: ctest --test-dir build || true run: ctest --test-dir build || true
+2 -3
View File
@@ -1,4 +1,3 @@
tmp/*
bin/*
doc/*
build/* build/*
doc/*
beluga.wiki/*
-3
View File
@@ -1,3 +0,0 @@
[submodule "blisp"]
path = blisp
url = https://homelinuxserver.ddns.net/git/arthur/blisp.git
-60
View File
@@ -1,60 +0,0 @@
# Specify the minimum version of CMake required
cmake_minimum_required(VERSION 3.10)
# Define the project name and the programming language (C)
project(Beluga)
# Set the C standard (optional)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_COMPILER clang)
# Add the header files directory to the include path
include_directories(include)
include_directories(blisp/include)
# Add the source files for the project
set(SRCS
main.c
src/append_buffer.c
src/file_io.c
src/input.c
src/row_op.c
src/editor_op.c
src/init.c
src/output.c
src/terminal.c
src/builtins.c
blisp/src/config_tools.c
blisp/src/data.c
blisp/src/lexer.c
blisp/src/parser.c)
find_package(Doxygen)
if(DOXYGEN_FOUND)
# set input and output for doxygen
set(DOXYGEN_OUT ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile)
add_custom_target(
doc_doxygen ALL
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Generating documentation with Doxygen"
VERBATIM)
else(DOXYGEN_FOUND)
message("Doxygen not found")
endif(DOXYGEN_FOUND)
# we default to Release build type
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()
set(CMAKE_C_FLAGS "-Wall -Wextra")
set(CMAKE_C_FLAGS_DEBUG "-g")
# Create an executable target with the specified source files
add_executable(beluga ${SRCS})
# Optionally, you can set the output directory for the executable
set_target_properties(beluga PROPERTIES RUNTIME_OUTPUT_DIRECTORY bin)
+43
View File
@@ -0,0 +1,43 @@
**#%#*****###%**
*##+--------------------=##*
#*=----------------------------=*#*
#*------------------------------------*#
%+----------------------------------------=#*
#+---------------------------------------------##
*#-------------------------------------------------=##
*#----------------------------------------------------:-##
#----------------------------------------------------------##
#=--------------------------------------------------------------##
+--------------------------+@#-%*-----------------------------------#*
+--------------------------%@@@@#-------------------------------------** BELUGA - VERSION 1.1
*-=-------------------------#@@*---------------------------------------=%
%*#==--------------------------------------------------------------------+# ----- KEY-BINDS -----
*%%=-=--------------------------------------------------------------------=# CTRL-q leave
%=--------------------------------------------------------------------------#* CTRL-s save
%-----------------------------------------------------------------------------** CTRL-o open-file
*+--=---===----=---------------=*-----------------------------------------------**
#--=## *#%#*+==----==+**+----------------------= ***=---------------------%
*%**=-----------==== ==---------------------------------=+#+-----------------=#
*%=----------------------------------------------------------=#*---------------#
##=----------------------------------=------------------------+%=------------+#
#%+---------------------------------=*------------------------+%------------#
*#%*=-------------=-----------------#-------------------------#+----------#
**#%#*******+=======-------------#=------------------------#----------#
#===#*=======------------------#*----=-----------=--=##*-----------#
-====##=------------------------*%+------------=*#+=====----------#
--=====+#*=----------------------=-=+*#####***+=======-----------=*
%------=====*%*=-------------------------========-----------------+*
*-=--------====%%###+=--------------------------=-----------------#
#-----------=% +*##%%%%%%@@%%%%####*==---------------------**
%=-------#* #%*=-----------------+#
*%+--=## ##=-----------------=#*
** #+----=-------------------#*
%+----------------------------#*
*%-------------==----------------+#
##--------------==------------------#
*#--------------===%-----------------=%
##---------------=-##*-----------------+#
*#---------------==#+=#%-----------------%
*%---------------+# %*---------------#*
*#------------=+#* #%*=-----------#*
#****##****** *#%%##+=----%
Submodule blisp deleted from 04464ec2e7
-21
View File
@@ -1,21 +0,0 @@
// Configuration file
,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("PAGE-UP" %move-cursor-page-up)
,map-key("PAGE-DOWN" %move-cursor-page-down)
,map-key("DEL_KEY" %delete-next-char)
,map-key("BACKSPACE" %delete-previous-char)
,map-key("ENTER" %editor-insert-new-line)
,map-key("CTRL-s" %editor-save)
,map-key("CTRL-q" %editor-quit)
,map-key("CTRL-a" %move-cursor-beg-line)
,map-key("CTRL-z" %move-cursor-end-line)
,map-key("CTRL-f o" %open-file)
,map-key("CTRL-w s h" %window-split-horizontal)
,map-key("CTRL-w s v" %window-split-vertical)
,define(theme "dark")
,define(auto-save true)
+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)
+21 -29
View File
@@ -1,40 +1,32 @@
#ifndef BUILTINS_H_ #ifndef BUILTINS_H_
#define BUILTINS_H_ #define BUILTINS_H_
#include "../blisp/include/config_tools.h" #include "lisp.h"
#include "../include/editor_op.h"
#include "../include/file_io.h"
#include "../include/output.h"
#include "../include/input.h"
#include "data.h"
#include "file_io.h"
// Function pointer type for commands Lisp moveCursor(Lisp args, LispError *e, LispContext ctx);
typedef void (*command_func_t)(struct editorConfig *E);
// Structure to hold function mappings Lisp mapKey(Lisp args, LispError *e, LispContext ctx);
typedef struct {
const char *name;
command_func_t func;
} function_entry_t;
// Function registry void registerBuiltin(char * key_sequence, LispCFunc f);
void init_function_registry(void); Lisp editorQuit(Lisp args, LispError *e, LispContext ctx);
int register_function(const char *name, command_func_t func);
command_func_t find_function(const char *name);
int execute_command(const char *name, struct editorConfig *E);
void moveCursorBeginLine(struct editorConfig *E); Lisp l_editorSave(Lisp args, LispError *e, LispContext ctx);
void moveCursorEndLine(struct editorConfig *E);
void editorQuit(struct editorConfig *E);
void editorMoveCursorUp(struct editorConfig *E); Lisp l_editorInsertNewLine(Lisp args, LispError* e, LispContext ctx);
void editorMoveCursorDown(struct editorConfig *E);
void editorMoveCursorLeft(struct editorConfig *E); Lisp moveCursorBeginLine(Lisp args, LispError *e, LispContext ctx);
void editorMoveCursorRight(struct editorConfig *E);
void deleteNextChar(struct editorConfig *E); Lisp moveCursorEndLine(Lisp args, LispError *e, LispContext ctx);
void editorMoveCursorPageUp(struct editorConfig *E);
void editorMoveCursorPageDown(struct editorConfig *E); 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 #endif
+35 -9
View File
@@ -1,9 +1,11 @@
#ifndef DATA_H_ #ifndef DATA_H_
#define DATA_H_ #define DATA_H_
#include <stdio.h>
#include <termios.h> #include <termios.h>
#include <time.h> #include <time.h>
#include "../blisp/include/data.h"
#include "lisp.h"
/** /**
* \struct erow * \struct erow
@@ -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.
@@ -32,12 +51,24 @@ struct editorConfig {
int numrows; /**< Number of rows contained */ int numrows; /**< Number of rows contained */
erow *row; /**< Store all the rows printed */ erow *row; /**< Store all the rows printed */
int dirty; int dirty;
int quit_times;
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 */
config_t *config;
struct const_t constantes;
int quit_times_buffer;
FILE *fd_init_file;
Lisp env;
LispContext ctx; /** Lisp context */
Lisp ctx_data; /** Lisp data context */
LispError ctx_error; /** Lisp ctx error */
struct keyBind_t* key_binds;
int number_of_keybinds;
}; };
/** /**
@@ -50,12 +81,7 @@ struct abuf {
int len; /**< Length of the text */ int len; /**< Length of the text */
}; };
// Enhanced key sequence handling for multi-key bindings like "CTRL-f o" extern struct editorConfig E;
typedef struct {
char sequence[64];
int sequence_len;
int last_key_time; // You might want to add timing if needed
} key_sequence_t;
#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 2
#define QUIT_TIMES 1
#endif // DEFINE_H_ #endif // DEFINE_H_
+3 -3
View File
@@ -2,10 +2,10 @@
#define EDITOR_OP_H_ #define EDITOR_OP_H_
#include "data.h" #include "data.h"
void editorInsertChar(struct editorConfig *E, int c); void editorInsertChar(int c);
void editorInsertNewLine(struct editorConfig *E); void editorInsertNewLine();
void editorDelChar(struct editorConfig *E); void editorDelChar();
#endif // EDITOR_OP_H_ #endif // EDITOR_OP_H_
+6 -3
View File
@@ -8,10 +8,13 @@
#include <stdlib.h> #include <stdlib.h>
#include <sys/types.h> #include <sys/types.h>
char *editorRowsToString(struct editorConfig *E, int *buffer_len); char *editorRowsToString(int *buffer_len);
void editorOpen(struct editorConfig *E, char *filename);
void editorSave(struct editorConfig *E); void editorCloseFile(void);
void editorOpen(char *filename);
void editorSave();
#endif // FILE_IO_H_ #endif // FILE_IO_H_
+4 -6
View File
@@ -1,20 +1,18 @@
#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 "builtins.h"
#include "../blisp/include/config_tools.h"
#include <stdio.h> #include <stdio.h>
void getConfig();
/** /**
* \fn void initEditor() * \fn void initEditor()
* \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 initEditor(struct editorConfig *E); void initBuiltins();
void initEditor();
#endif // INIT_H_ #endif // INIT_H_
+5 -8
View File
@@ -6,7 +6,6 @@
#include "output.h" #include "output.h"
#include "terminal.h" #include "terminal.h"
#include "builtins.h" #include "builtins.h"
#include "../blisp/include/config_tools.h"
#include <unistd.h> #include <unistd.h>
// KEYS keycode // KEYS keycode
@@ -21,21 +20,19 @@
// END \x1b[4~ || <esc>[8~ || <esc>[F || <esc>OF // END \x1b[4~ || <esc>[8~ || <esc>[F || <esc>OF
// DELETE \x1b[3~ // DELETE \x1b[3~
char *editorPrompt(char *prompt);
char *key_to_string(int key); char *key_to_string(int key);
int execute_key_binding(config_t *config, const char *key_combo, void *context); void editorMoveCursor(int key);
int handle_key_sequence(struct editorConfig *E, int key); int executeKeyBind(char *key_sequence);
char *editorPrompt(struct editorConfig *E, char *prompt);
void editorMoveCursor(struct editorConfig *E, int key);
/** /**
* \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.
*/ */
void editorProcessKeypress(struct editorConfig *E); void editorProcessKeypress();
#endif // INPUT_H_ #endif // INPUT_H_
+3215
View File
File diff suppressed because it is too large Load Diff
+2180
View File
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -13,16 +13,16 @@
* \brief Draws left rows of the editor. * \brief Draws left rows of the editor.
*/ */
void editorDrawRows(struct editorConfig *E, struct abuf *ab); void editorDrawRows(struct abuf *ab);
void editorRefreshScreen(struct editorConfig *E); void editorRefreshScreen();
void editorScroll(struct editorConfig *E); void editorScroll();
void editorDrawStatusBar(struct editorConfig *E, struct abuf *ab); void editorDrawStatusBar(struct abuf *ab);
void editorDrawMessageBar(struct editorConfig *E, struct abuf *ab); void editorDrawMessageBar(struct abuf *ab);
void editorSetStatusMessage(struct editorConfig *E, const char *fmt, ...); void editorSetStatusMessage(const char *fmt, ...);
#endif // OUTPUT_H_ #endif // OUTPUT_H_
+5 -8
View File
@@ -12,19 +12,16 @@ int editorRowCxToRx(erow *row, int cursor_x);
void editorUpdateRow(erow *row); void editorUpdateRow(erow *row);
void editorInsertRow(struct editorConfig *E, int at, char *s, size_t len); void editorInsertRow(int at, char *s, size_t len);
void editorFreeRow(erow *row); void editorFreeRow(erow *row);
void editorDelRow(struct editorConfig *E, int at); void editorDelRow(int at);
void editorRowInsertChar(struct editorConfig *E, erow *row, int at, int c); void editorRowInsertChar(erow *row, int at, int c);
void editorRowAppendString(struct editorConfig *E, erow *row, char *s, void editorRowAppendString(erow *row, char *s, size_t len);
size_t len);
void editorRowDelchar(struct editorConfig *E, erow *row, int at); void editorRowDelchar(erow *row, int at);
void log_string(char * string);
#endif // ROW_OP_H_ #endif // ROW_OP_H_
+2 -2
View File
@@ -21,9 +21,9 @@
void die(const char *s); void die(const char *s);
void disableRawMode(struct editorConfig *E); void disableRawMode();
void enableRawMode(struct editorConfig *E); void enableRawMode();
int editorReadKey(); int editorReadKey();
+15 -7
View File
@@ -6,6 +6,7 @@
*/ */
#include <unistd.h> #include <unistd.h>
#define _DEFAULT_SOURCE #define _DEFAULT_SOURCE
#define _BSD_SOURCE #define _BSD_SOURCE
#define _GNU_SOURCE #define _GNU_SOURCE
@@ -17,18 +18,25 @@
#include "include/output.h" #include "include/output.h"
#include "include/terminal.h" #include "include/terminal.h"
struct editorConfig E;
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
static struct editorConfig E;
enableRawMode(&E); enableRawMode();
initEditor(&E); initEditor();
if (argc >= 2) { if (argc >= 2) {
editorOpen(&E, argv[1]); E.state = READ_AND_WRITE;
editorOpen(argv[1]);
} else {
editorOpen("assets/beluga.txt");
} }
editorSetStatusMessage(&E, "HELP: Ctrl-S = save | Ctrl-Q = quit");
editorSetStatusMessage("HELP: Ctrl-S = save | Ctrl-Q = quit");
while (1) { while (1) {
editorRefreshScreen(&E); editorRefreshScreen();
editorProcessKeypress(&E); editorProcessKeypress();
} }
return 0; return 0;
} }
+29
View File
@@ -0,0 +1,29 @@
project('beluga', 'c',
version : '1.1',
default_options : [
'c_std=none',
]
)
cc = meson.get_compiler('c')
m = cc.find_library('m', required: false)
# Source files
src_files = files(
'main.c',
'src/append_buffer.c',
'src/editor_op.c',
'src/file_io.c',
'src/init.c',
'src/input.c',
'src/output.c',
'src/row_op.c',
'src/terminal.c',
'src/builtins.c',
)
# Executable
executable('beluga',
src_files,
dependencies: [m]
)
+2
View File
@@ -1,5 +1,7 @@
#include "../include/append_buffer.h" #include "../include/append_buffer.h"
extern struct editorConfig E;
void abAppend(struct abuf *ab, const char *s, int len) { void abAppend(struct abuf *ab, const char *s, int len) {
char *new = realloc(ab->b, ab->len + len); char *new = realloc(ab->b, ab->len + len);
+103 -93
View File
@@ -1,131 +1,141 @@
// function_registry.c
#include "../include/builtins.h" #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 <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
// Static array to hold function mappings Lisp mapKey(Lisp args, LispError *e, LispContext ctx) {
function_entry_t function_registry[256]; const char *key_sequence = lisp_string(lisp_car(args));
int registry_count = 0; args = lisp_cdr(args);
// second argument
Lisp func = lisp_car(args);
// Initialize the function registry E.key_binds =
void init_function_registry(void) { (struct keyBind_t *)realloc(E.key_binds, ++E.number_of_keybinds * sizeof(struct keyBind_t));
register_function("editor-save", editorSave); E.key_binds[E.number_of_keybinds - 1].key_sequence = (char *) malloc(50 * sizeof(char));
register_function("move-cursor-beg-line", moveCursorBeginLine);
register_function("move-cursor-end-line", moveCursorEndLine); strncpy(E.key_binds[E.number_of_keybinds - 1].key_sequence, key_sequence, 50);
register_function("editor-quit", editorQuit);
register_function("move-cursor-up", editorMoveCursorUp); E.key_binds[E.number_of_keybinds - 1].command = func;
register_function("move-cursor-down", editorMoveCursorDown);
register_function("move-cursor-right", editorMoveCursorRight); return lisp_null();
register_function("move-cursor-left", editorMoveCursorLeft);
register_function("move-cursor-page-up", editorMoveCursorPageUp);
register_function("move-cursor-page-down", editorMoveCursorPageDown);
register_function("delete-previous-char", editorDelChar);
register_function("delete-next-char", deleteNextChar);
register_function("editor-insert-new-line", editorInsertNewLine);
} }
// Register a function with a name Lisp moveCursor(Lisp args, LispError *e, LispContext ctx) {
int register_function(const char *name, command_func_t func) { fprintf(stderr, "Cursor is moving\n");
if (registry_count >= 256) { const char *direction = lisp_string(lisp_car(args));
return -1; // Registry full 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;
} }
function_registry[registry_count].name = strdup(name);
function_registry[registry_count].func = func; return lisp_null();
registry_count++;
return 0;
} }
// Find a function by name Lisp editorQuit(Lisp args, LispError* e, LispContext ctx) {
command_func_t find_function(const char *name) { if (E.dirty && E.quit_times_buffer > 0) {
log_string("registry :"); editorSetStatusMessage("WARNING! Changes hasn't been saved. Press Ctrl-Q "
char *tmp = malloc(3 * sizeof(char));
sprintf(tmp, "%d\n", registry_count);
log_string(tmp);
for (int i = 0; i < registry_count; i++) {
if (strcmp(function_registry[i].name, name) == 0) {
return function_registry[i].func;
}
}
return NULL;
}
// Execute a command by name
int execute_command(const char *name, struct editorConfig *E) {
log_string(name);
command_func_t func = find_function(name);
if (func) {
func(E);
return 0;
}
log_string("Unknown command: \n");
return -1;
}
// Builtins tools
void moveCursorBeginLine(struct editorConfig *E) { E->cursor_x = 0; }
void moveCursorEndLine(struct editorConfig *E) {
if (E->cursor_y < E->numrows) {
E->cursor_x = E->row[E->cursor_y].size;
}
}
void editorQuit(struct editorConfig *E) {
log_string("time to quit\n");
if (E->dirty && E->quit_times > 0) {
editorSetStatusMessage(E,
"WARNING! Changes hasn't been saved. Press Ctrl-Q "
"another time to quit."); "another time to quit.");
--E->quit_times; --E.quit_times_buffer;
return; return lisp_null();
} }
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);
disableRawMode(E); disableRawMode();
exit(0); exit(0);
return lisp_null();
} }
void editorMoveCursorUp(struct editorConfig *E) { Lisp l_editorSave(Lisp args, LispError* e, LispContext ctx) {
editorMoveCursor(E, ARROW_UP);
editorSave();
return lisp_null();
} }
void editorMoveCursorDown(struct editorConfig *E) { Lisp l_editorInsertNewLine(Lisp args, LispError* e, LispContext ctx) {
editorMoveCursor(E, ARROW_DOWN);
editorInsertNewLine();
return lisp_null();
} }
void editorMoveCursorRight(struct editorConfig *E) { Lisp moveCursorBeginLine(Lisp args, LispError *e, LispContext ctx) {
editorMoveCursor(E, ARROW_RIGHT); E.cursor_x = 0;
return lisp_null();
} }
void editorMoveCursorLeft(struct editorConfig *E) { Lisp moveCursorEndLine(Lisp args, LispError* e, LispContext ctx) {
editorMoveCursor(E, ARROW_LEFT); if (E.cursor_y < E.numrows) {
E.cursor_x = E.row[E.cursor_y].size;
}
return lisp_null();
} }
void deleteNextChar(struct editorConfig *E) {
editorMoveCursorRight(E); Lisp deletePreviousChar(Lisp args, LispError* e, LispContext ctx) {
editorDelChar(E); editorDelChar();
return lisp_null();
} }
void editorMoveCursorPageUp(struct editorConfig *E) { Lisp editorMoveCursorPageUp(Lisp args, LispError* e, LispContext ctx) {
E->cursor_y = E->row_offset; E.cursor_y = E.row_offset;
int times = E->screenrows; int times = E.screenrows;
while (--times) { while (--times) {
editorMoveCursor(E, ARROW_UP); editorMoveCursor(ARROW_UP);
} }
return lisp_null();
} }
void editorMoveCursorPageDown(struct editorConfig *E) { Lisp editorMoveCursorPageDown(Lisp args, LispError* e, LispContext ctx) {
E->cursor_y = E->row_offset + E->screenrows - 1; E.cursor_y = E.row_offset + E.screenrows - 1;
if (E->cursor_y > E->numrows) { if (E.cursor_y > E.numrows) {
E->cursor_y = E->numrows; E.cursor_y = E.numrows;
} }
int times = E->screenrows; int times = E.screenrows;
while (--times) { while (--times) {
editorMoveCursor(E, ARROW_DOWN); 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();
}
+28 -25
View File
@@ -1,44 +1,47 @@
#include "../include/editor_op.h" #include "../include/editor_op.h"
#include "../include/row_op.h" #include "../include/row_op.h"
void editorInsertChar(struct editorConfig *E, int c) {
if (E->cursor_y == E->numrows) { extern struct editorConfig E;
editorInsertRow(E, E->numrows, "", 0);
void editorInsertChar(int c) {
if (E.cursor_y == E.numrows) {
editorInsertRow(E.numrows, "", 0);
} }
editorRowInsertChar(E, &E->row[E->cursor_y], E->cursor_x, c); editorRowInsertChar(&E.row[E.cursor_y], E.cursor_x, c);
E->cursor_x++; E.cursor_x++;
} }
void editorInsertNewLine(struct editorConfig *E) { void editorInsertNewLine() {
erow *row; erow *row;
if (!E->cursor_x) { if (!E.cursor_x) {
editorInsertRow(E, E->cursor_y, "", 0); editorInsertRow(E.cursor_y, "", 0);
} else { } else {
row = &E->row[E->cursor_y]; row = &E.row[E.cursor_y];
editorInsertRow(E, E->cursor_y + 1, &row->chars[E->cursor_x], editorInsertRow(E.cursor_y + 1, &row->chars[E.cursor_x],
row->size - E->cursor_x); row->size - E.cursor_x);
row = &E->row[E->cursor_y]; row = &E.row[E.cursor_y];
row->size = E->cursor_x; row->size = E.cursor_x;
row->chars[row->size] = '\0'; row->chars[row->size] = '\0';
editorUpdateRow(row); editorUpdateRow(row);
} }
++E->cursor_y; ++E.cursor_y;
E->cursor_x = 0; E.cursor_x = 0;
} }
void editorDelChar(struct editorConfig *E) { void editorDelChar() {
erow *row; erow *row;
if (E->cursor_y == E->numrows || !(E->cursor_x || E->cursor_y)) { if (E.cursor_y == E.numrows || !(E.cursor_x || E.cursor_y)) {
return; return;
} }
row = &E->row[E->cursor_y]; row = &E.row[E.cursor_y];
if (E->cursor_x > 0) { if (E.cursor_x > 0) {
editorRowDelchar(E, row, E->cursor_x - 1); editorRowDelchar(row, E.cursor_x - 1);
--E->cursor_x; --E.cursor_x;
} else { } else {
E->cursor_x = E->row[E->cursor_y - 1].size; E.cursor_x = E.row[E.cursor_y - 1].size;
editorRowAppendString(E, &E->row[E->cursor_y - 1], row->chars, row->size); editorRowAppendString(&E.row[E.cursor_y - 1], row->chars, row->size);
editorDelRow(E, E->cursor_y); editorDelRow(E.cursor_y);
--E->cursor_y; --E.cursor_y;
} }
} }
+48 -27
View File
@@ -8,21 +8,27 @@
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
char *editorRowsToString(struct editorConfig *E, int *buffer_len) { extern char *strdup(const char *);
extern ssize_t getline(char **restrict lineptr, size_t *restrict n,
FILE *restrict stream);
extern int ftruncate(int fd, off_t length);
extern struct editorConfig E;
char *editorRowsToString(int *buffer_len) {
int tot_len = 0; int tot_len = 0;
int j; int j;
char *buf; char *buf;
char *p; char *p;
for (j = 0; j < E->numrows; ++j) { for (j = 0; j < E.numrows; ++j) {
tot_len += E->row[j].size + 1; tot_len += E.row[j].size + 1;
} }
*buffer_len = tot_len; *buffer_len = tot_len;
buf = malloc(tot_len); buf = malloc(tot_len);
p = buf; p = buf;
for (j = 0; j < E->numrows; ++j) { for (j = 0; j < E.numrows; ++j) {
memcpy(p, E->row[j].chars, E->row[j].size); memcpy(p, E.row[j].chars, E.row[j].size);
p += E->row[j].size; p += E.row[j].size;
*p = '\n'; *p = '\n';
p++; p++;
} }
@@ -30,18 +36,33 @@ char *editorRowsToString(struct editorConfig *E, int *buffer_len) {
return buf; return buf;
} }
void editorOpen(struct editorConfig *E, char *filename) { void editorCloseFile(void) {
/** E.cursor_x = 0;
\function void editorOpen(struct editorConfig *E, char *filename) E.cursor_y = 0;
\brief Open filename on editor stream. Throw fopen error if file doesn't E.rx = 0;
exist. 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) {
FILE *fp; FILE *fp;
free(E->filename); // Test if a file is already open
E->filename = strdup(filename); if (E.filename != NULL) {
editorCloseFile();
E.state = READ_AND_WRITE;
}
fp = fopen(filename, "r"); free(E.filename);
E.filename = strdup(filename);
fp = fopen(filename, "a+");
if (!fp) if (!fp)
die("fopen"); die("fopen");
@@ -54,38 +75,38 @@ void editorOpen(struct editorConfig *E, char *filename) {
(line[line_len - 1] == '\n' || line[line_len - 1] == '\r')) { (line[line_len - 1] == '\n' || line[line_len - 1] == '\r')) {
--line_len; --line_len;
} }
editorInsertRow(E, E->numrows, line, line_len); editorInsertRow(E.numrows, line, line_len);
} }
free(line); free(line);
fclose(fp); fclose(fp);
E->dirty = 0; E.dirty = 0;
} }
void editorSave(struct editorConfig *E) { void editorSave() {
int len; int len;
char *buf; char *buf;
int fd; int fd;
if (E->filename == NULL) { if (E.filename == NULL) {
E->filename = editorPrompt(E, "Save as: %s (ESC to cancel)"); E.filename = editorPrompt("Save as: %s (ESC to cancel)");
if (E->filename == NULL) { if (E.filename == NULL) {
editorSetStatusMessage(E, "Save aborted"); editorSetStatusMessage("Save aborted");
return; return;
} }
} }
buf = editorRowsToString(E, &len); buf = editorRowsToString(&len);
fd = open(E->filename, O_RDWR | O_CREAT, 0644); fd = open(E.filename, O_RDWR | O_CREAT, 0644);
if (fd != -1) { if (fd != -1) {
if (ftruncate(fd, len) != -1) { if (ftruncate(fd, len) != -1) {
if (write(fd, buf, len) == len) { if (write(fd, buf, len) == len) {
close(fd); close(fd);
free(buf); free(buf);
E->dirty = 0; E.dirty = 0;
editorSetStatusMessage(E, "%d bytes written to disk", len); editorSetStatusMessage("%d bytes written to disk", len);
return; return;
} }
} }
close(fd); close(fd);
} }
free(buf); free(buf);
editorSetStatusMessage(E, "Can't save! I/O error: %s", strerror(errno)); editorSetStatusMessage("Can't save! I/O error: %s", strerror(errno));
} }
+75 -19
View File
@@ -1,27 +1,83 @@
#include "../include/init.h" #include "../include/init.h"
#include "../include/data.h"
#include "../include/terminal.h"
#include "../include/builtins.h"
#include <stdio.h>
void initEditor(struct editorConfig *E) { #define LISP_IMPLEMENTATION
E->cursor_x = 0; #include "../include/lisp.h"
E->cursor_y = 0; #include "../include/lisp_lib.h"
E->rx = 0;
E->row_offset = 0; extern struct editorConfig;
E->col_offset = 0;
E->numrows = 0;
E->row = NULL; void registerBuiltin(char *key_sequence, LispCFunc f) {
E->dirty = 0; lisp_env_define(E.ctx.p->env, lisp_make_symbol(key_sequence, E.ctx),
E->quit_times = QUIT_TIMES; lisp_make_func(f), E.ctx);
E->filename = NULL;
E->status_msg[0] = '\0'; }
E->status_msg_time = 0;
if (getWindowSize(&E->screenrows, &E->screencols) == -1) { 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() {
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.state = READ_ONLY;
E.status_msg[0] = '\0';
E.status_msg_time = 0;
if (getWindowSize(&E.screenrows, &E.screencols) == -1) {
die("getWindowSize"); die("getWindowSize");
} }
E->screenrows -= 2; E.screenrows -= 2;
E->config = config_create(); E.number_of_keybinds = 0;
config_parse_file(E->config, "../config/init.bl");
config_print_all(E->config);
init_function_registry(); E.fd_init_file = fopen("config/init.lisp", "r");
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;
} }
+83 -124
View File
@@ -1,18 +1,60 @@
#include "../include/input.h" #include "../include/input.h"
#include "../include/editor_op.h"
#include "../include/output.h"
#include "../include/define.h"
#include <ctype.h>
#include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h>
extern struct editorConfig E;
/** /**
* \fn char * editorPrompt(struct editorConfig *E, char *prompt) * \fn char * editorPrompt(struct editorConfig *E, char *prompt)
* \brief Return user input in a prompt when enter is hit. */ * \brief Return user input in a prompt when enter is hit. */
char *editorPrompt(char *prompt) {
size_t buf_size = 128;
char *buf = malloc(buf_size);
size_t buf_len = 0;
int c = 0;
buf[0] = '\0';
while (1) {
editorSetStatusMessage(prompt, buf);
editorRefreshScreen();
c = editorReadKey();
if (c == DEL_KEY || c == CTRL_KEY('h') || c == BACKSPACE) {
if (buf_len != 0) {
buf[--buf_len] = '\0';
}
} else if (c == ESCAPE) {
editorSetStatusMessage("");
free(buf);
return NULL;
} else if (c == '\r') {
if (buf_len != 0) {
editorSetStatusMessage("");
return buf;
}
} else if (!iscntrl(c) && c < 128) {
if (buf_len == buf_size - 1) {
buf_size *= 2;
buf = realloc(buf, buf_size);
}
buf[buf_len++] = c;
buf[buf_len] = '\0';
}
}
}
char *key_to_string(int key) { char *key_to_string(int key) {
static char key_str[32]; static char key_str[32];
char * tmp = malloc(10 * sizeof(char)); char tmp[10];
sprintf(tmp, "%d\n", key); sprintf(tmp, "%d", key);
log_string(tmp);
// First test enter key // First test enter key
@@ -37,12 +79,15 @@ char *key_to_string(int key) {
break; break;
case PAGE_UP: case PAGE_UP:
strcpy(key_str, "PAGE-UP"); strcpy(key_str, "PAGE-UP");
fprintf(stderr, "pagr up\n");
break; break;
case PAGE_DOWN: case PAGE_DOWN:
strcpy(key_str, "PAGE-DOWN"); strcpy(key_str, "PAGE-DOWN");
break; break;
case DEL_KEY: case DEL_KEY:
fprintf(stderr, "delete key\n");
strcpy(key_str, "DEL"); strcpy(key_str, "DEL");
break; break;
case BACKSPACE: case BACKSPACE:
strcpy(key_str, "BACKSPACE"); strcpy(key_str, "BACKSPACE");
@@ -71,154 +116,68 @@ char *key_to_string(int key) {
return key_str; return key_str;
} }
char *editorPrompt(struct editorConfig *E, char *prompt) {
size_t buf_size = 128;
char *buf = malloc(buf_size);
size_t buf_len = 0;
int c = 0;
buf[0] = '\0';
while (1) { void editorMoveCursor(int key) {
editorSetStatusMessage(E, prompt, buf); erow *row = (E.cursor_y >= E.numrows) ? NULL : &E.row[E.cursor_y];
editorRefreshScreen(E);
c = editorReadKey();
if (c == DEL_KEY || c == CTRL_KEY('h') || c == BACKSPACE) {
if (buf_len != 0) {
buf[--buf_len] = '\0';
}
} else if (c == ESCAPE) {
fprintf(stderr, "escape");
editorSetStatusMessage(E, "");
free(buf);
return NULL;
} else if (c == '\r') {
if (buf_len != 0) {
editorSetStatusMessage(E, "");
return buf;
}
} else if (!iscntrl(c) && c < 128) {
if (buf_len == buf_size - 1) {
buf_size *= 2;
buf = realloc(buf, buf_size);
}
buf[buf_len++] = c;
buf[buf_len] = '\0';
}
}
}
void editorMoveCursor(struct editorConfig *E, int key) {
erow *row = (E->cursor_y >= E->numrows) ? NULL : &E->row[E->cursor_y];
int row_len; int row_len;
char *sequence = key_to_string(key);
switch (key) { switch (key) {
case ARROW_RIGHT: case ARROW_RIGHT:
if (row && E->cursor_x < row->size) { if (row && E.cursor_x < row->size) {
++E->cursor_x; ++E.cursor_x;
} else if (row && E->cursor_x == row->size) { } else if (row && E.cursor_x == row->size) {
E->cursor_y++; E.cursor_y++;
E->cursor_x = 0; E.cursor_x = 0;
} }
break; break;
case ARROW_DOWN: case ARROW_DOWN:
if (E->cursor_y < E->numrows) { if (E.cursor_y < E.numrows) {
++E->cursor_y; ++E.cursor_y;
} }
break; break;
case ARROW_UP: case ARROW_UP:
if (E->cursor_y != 0) { if (E.cursor_y != 0) {
--E->cursor_y; --E.cursor_y;
} }
break; break;
case ARROW_LEFT: case ARROW_LEFT:
if (E->cursor_x != 0) { if (E.cursor_x != 0) {
--E->cursor_x; --E.cursor_x;
} else if (E->cursor_y > 0) { } else if (E.cursor_y > 0) {
--E->cursor_y; --E.cursor_y;
E->cursor_x = E->row[E->cursor_y].size; E.cursor_x = E.row[E.cursor_y].size;
} }
break; break;
} }
row = (E->cursor_y >= E->numrows) ? NULL : &E->row[E->cursor_y]; row = (E.cursor_y >= E.numrows) ? NULL : &E.row[E.cursor_y];
row_len = row ? row->size : 0; row_len = row ? row->size : 0;
if (E->cursor_x > row_len) { if (E.cursor_x > row_len) {
E->cursor_x = row_len; E.cursor_x = row_len;
} }
} }
key_sequence_t current_sequence = {0}; 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)) {
int handle_key_sequence(struct editorConfig *E, int key) { fprintf(stderr, "lisp function %s\n", key_sequence);
char *key_str = key_to_string(key); // It's a symbol, create a function call
lisp_eval(lisp_cons(E.key_binds[i].command, lisp_null(), E.ctx),
log_string(key_str); &E.ctx_error, E.ctx);
return 1;
// Add current key to sequence
if (current_sequence.sequence_len > 0) {
strcat(current_sequence.sequence, " ");
} }
strcat(current_sequence.sequence, key_str); }
current_sequence.sequence_len++; return 0;
// Check if this sequence matches any binding
const char *command =
config_get_key_mapping(E->config, current_sequence.sequence);
if (command) {
log_string("Command found\n");
// Found a complete binding - execute it
execute_key_binding(E->config, current_sequence.sequence, E);
// Reset sequence
memset(&current_sequence, 0, sizeof(current_sequence));
return 1; // Handled
} }
// Check if this could be the start of a longer sequence void editorProcessKeypress() {
// (This is a simple check - you might want to make it more sophisticated)
int potential_match = 0;
// You'd implement a function to check for partial matches here
if (!potential_match) {
// No potential matches, reset sequence and handle as single key
memset(&current_sequence, 0, sizeof(current_sequence));
return 0; // Not handled
}
return 1; // Waiting for more keys in sequence
}
int execute_key_binding(config_t *config, const char *key_combo,
void *context) {
const char *command = config_get_key_mapping(config, key_combo);
if (!command) {
log_string("No mapping found for key combination: ");
log_string(key_combo);
log_string("\n");
return -1;
}
// Remove the '%' prefix if present
const char *func_name = command;
if (command[0] == '%') {
func_name = command + 1;
}
return execute_command(func_name, context);
}
void editorProcessKeypress(struct editorConfig *E) {
static int quit_times = QUIT_TIMES;
int c = editorReadKey(); int c = editorReadKey();
if (E->config) { if (executeKeyBind(key_to_string(c))) {
if (handle_key_sequence(E, c)) { return;
quit_times = QUIT_TIMES;
return; // Key was handled by config system
}
} }
editorInsertChar(c);
E.quit_times_buffer = E.constantes.QUIT_TIMES;
editorInsertChar(E, c);
// reset quit times
E->quit_times = QUIT_TIMES;
} }
+50 -48
View File
@@ -4,24 +4,26 @@
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
void editorDrawRows(struct editorConfig *E, struct abuf *ab) { extern struct editorConfig E;
void editorDrawRows(struct abuf *ab) {
int y; int y;
char welcome[80]; char welcome[80];
int welcome_len; int welcome_len;
int padding; int padding;
int len; int len;
int file_row; int file_row;
for (y = 0; y < E->screenrows; ++y) { for (y = 0; y < E.screenrows; ++y) {
file_row = y + E->row_offset; file_row = y + E.row_offset;
if (file_row >= E->numrows) { if (file_row >= E.numrows) {
if (E->numrows == 0 && y == E->screenrows / 3) { if (E.numrows == 0 && y == E.screenrows / 3) {
welcome_len = welcome_len =
snprintf(welcome, sizeof(welcome), snprintf(welcome, sizeof(welcome),
"Beluga text editor -- version %s", BELUGA_VERSION); "Beluga text editor -- version %s", BELUGA_VERSION);
if (welcome_len > E->screencols) { if (welcome_len > E.screencols) {
welcome_len = E->screencols; welcome_len = E.screencols;
} }
padding = (E->screencols - welcome_len) / 2; padding = (E.screencols - welcome_len) / 2;
if (padding) { if (padding) {
abAppend(ab, "~", 1); abAppend(ab, "~", 1);
--padding; --padding;
@@ -34,54 +36,54 @@ void editorDrawRows(struct editorConfig *E, struct abuf *ab) {
abAppend(ab, "~", 1); abAppend(ab, "~", 1);
} }
} else { } else {
len = E->row[file_row].rsize - E->col_offset; len = E.row[file_row].rsize - E.col_offset;
if (len < 0) if (len < 0)
len = 0; len = 0;
if (len > E->screencols) if (len > E.screencols)
len = E->screencols; len = E.screencols;
abAppend(ab, &E->row[file_row].render[E->col_offset], len); abAppend(ab, &E.row[file_row].render[E.col_offset], len);
} }
abAppend(ab, ERASE_END_LINE, 3); abAppend(ab, ERASE_END_LINE, 3);
abAppend(ab, "\r\n", 2); abAppend(ab, "\r\n", 2);
} }
} }
void editorScroll(struct editorConfig *E) { void editorScroll() {
E->rx = E->cursor_x; E.rx = E.cursor_x;
if (E->cursor_y < E->numrows) { if (E.cursor_y < E.numrows) {
E->rx = editorRowCxToRx(&E->row[E->cursor_y], E->cursor_x); E.rx = editorRowCxToRx(&E.row[E.cursor_y], E.cursor_x);
} }
if (E->cursor_y < E->row_offset) { if (E.cursor_y < E.row_offset) {
E->row_offset = E->cursor_y; E.row_offset = E.cursor_y;
} }
if (E->cursor_y >= E->row_offset + E->screenrows) { if (E.cursor_y >= E.row_offset + E.screenrows) {
E->row_offset = E->cursor_y - E->screenrows + 1; E.row_offset = E.cursor_y - E.screenrows + 1;
} }
if (E->rx < E->col_offset) { if (E.rx < E.col_offset) {
E->col_offset = E->rx; E.col_offset = E.rx;
} }
if (E->rx >= E->col_offset + E->screencols) { if (E.rx >= E.col_offset + E.screencols) {
E->col_offset = E->rx - E->screencols + 1; E.col_offset = E.rx - E.screencols + 1;
} }
} }
void editorDrawStatusBar(struct editorConfig *E, struct abuf *ab) { void editorDrawStatusBar(struct abuf *ab) {
int len, render_len; int len, render_len;
char status[80], render_status[80]; char status[80], render_status[80];
abAppend(ab, "\x1b[7m", 4); // inverting colors abAppend(ab, "\x1b[7m", 4); // inverting colors
len = snprintf(status, sizeof(status), "%.20s - %d lines%s", len = snprintf(status, sizeof(status), "%.20s - %d lines%s",
E->filename ? E->filename : "[No Name]", E->numrows, E.filename ? E.filename : "[No Name]", E.numrows,
E->dirty ? "*" : ""); E.dirty ? "*" : "");
render_len = snprintf(render_status, sizeof(render_status), "%d/%d", render_len = snprintf(render_status, sizeof(render_status), "%d/%d",
E->cursor_y + 1, E->numrows); E.cursor_y + 1, E.numrows);
if (len > E->screencols) { if (len > E.screencols) {
len = E->screencols; len = E.screencols;
} }
abAppend(ab, status, len); abAppend(ab, status, len);
while (len < E->screencols) { while (len < E.screencols) {
if (E->screencols - len == render_len) { if (E.screencols - len == render_len) {
abAppend(ab, render_status, render_len); abAppend(ab, render_status, render_len);
break; break;
} else { } else {
@@ -93,31 +95,31 @@ void editorDrawStatusBar(struct editorConfig *E, struct abuf *ab) {
abAppend(ab, "\r\n", 2); abAppend(ab, "\r\n", 2);
} }
void editorDrawMessageBar(struct editorConfig *E, struct abuf *ab) { void editorDrawMessageBar(struct abuf *ab) {
int msg_len = strlen(E->status_msg); int msg_len = strlen(E.status_msg);
abAppend(ab, ERASE_END_LINE, 3); abAppend(ab, ERASE_END_LINE, 3);
if (msg_len > E->screencols) { if (msg_len > E.screencols) {
msg_len = E->screencols; msg_len = E.screencols;
} }
if (msg_len && time(NULL) - E->status_msg_time < 5) { if (msg_len && time(NULL) - E.status_msg_time < 5) {
abAppend(ab, E->status_msg, msg_len); abAppend(ab, E.status_msg, msg_len);
} }
} }
void editorRefreshScreen(struct editorConfig *E) { void editorRefreshScreen() {
editorScroll(E); editorScroll();
struct abuf ab = ABUF_INIT; struct abuf ab = ABUF_INIT;
char buf[32]; char buf[32];
abAppend(&ab, HIDE_CURSOR, 6); abAppend(&ab, HIDE_CURSOR, 6);
abAppend(&ab, CURSOR_TOP_LEFT, 3); abAppend(&ab, CURSOR_TOP_LEFT, 3);
editorDrawRows(E, &ab); editorDrawRows(&ab);
editorDrawStatusBar(E, &ab); editorDrawStatusBar(&ab);
editorDrawMessageBar(E, &ab); editorDrawMessageBar(&ab);
snprintf(buf, sizeof(buf), "\x1b[%d;%dH", (E->cursor_y - E->row_offset) + 1, snprintf(buf, sizeof(buf), "\x1b[%d;%dH", (E.cursor_y - E.row_offset) + 1,
(E->rx - E->col_offset) + 1); (E.rx - E.col_offset) + 1);
abAppend(&ab, buf, strlen(buf)); abAppend(&ab, buf, strlen(buf));
abAppend(&ab, SHOW_CURSOR, 6); abAppend(&ab, SHOW_CURSOR, 6);
@@ -126,10 +128,10 @@ void editorRefreshScreen(struct editorConfig *E) {
abFree(&ab); abFree(&ab);
} }
void editorSetStatusMessage(struct editorConfig *E, const char *fmt, ...) { void editorSetStatusMessage(const char *fmt, ...) {
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
vsnprintf(E->status_msg, sizeof(E->status_msg), fmt, ap); vsnprintf(E.status_msg, sizeof(E.status_msg), fmt, ap);
va_end(ap); va_end(ap);
E->status_msg_time = time(NULL); E.status_msg_time = time(NULL);
} }
+38 -38
View File
@@ -4,12 +4,14 @@
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
extern struct editorConfig E;
int editorRowCxToRx(erow *row, int cursor_x) { int editorRowCxToRx(erow *row, int cursor_x) {
int render_x = 0; int render_x = 0;
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++;
} }
@@ -33,8 +35,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
@@ -42,7 +44,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 */
} }
@@ -54,25 +56,29 @@ void editorUpdateRow(erow *row) {
row->rsize = i_render; row->rsize = i_render;
} }
void editorInsertRow(struct editorConfig *E, 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));
if (!tmp) {
return;
}
E.row = tmp;
memmove(&E.row[at + 1], &E.row[at], sizeof(erow) * (E.numrows - at));
E->row = realloc(E->row, sizeof(erow) * (E->numrows + 1)); E.row[at].size = len;
memmove(&E->row[at + 1], &E->row[at], sizeof(erow) * (E->numrows - at)); E.row[at].chars = malloc(len + 1);
memcpy(E.row[at].chars, s, len);
E.row[at].chars[len] = '\0';
E->row[at].size = len; E.row[at].rsize = 0;
E->row[at].chars = malloc(len + 1); E.row[at].render = NULL;
memcpy(E->row[at].chars, s, len); editorUpdateRow(&E.row[at]);
E->row[at].chars[len] = '\0';
E->row[at].rsize = 0; ++E.numrows;
E->row[at].render = NULL; ++E.dirty;
editorUpdateRow(&E->row[at]);
++E->numrows;
++E->dirty;
} }
void editorFreeRow(erow *row) { void editorFreeRow(erow *row) {
@@ -80,21 +86,23 @@ void editorFreeRow(erow *row) {
free(row->chars); free(row->chars);
} }
void editorDelRow(struct editorConfig *E, int at) { void editorDelRow(int at) {
if (at < 0 || at >= E->numrows) { if (at < 0 || at >= E.numrows) {
return; return;
} }
editorFreeRow(&E->row[at]); editorFreeRow(&E.row[at]);
memmove(&E->row[at], &E->row[at + 1], sizeof(erow) * (E->numrows - at - 1)); memmove(&E.row[at], &E.row[at + 1], sizeof(erow) * (E.numrows - at - 1));
--E->numrows; --E.numrows;
++E->dirty; ++E.dirty;
} }
/** /**
* \fn editorRowInsertChar(erow *row, int at, int c) * \fn editorRowInsertChar(erow *row, int at, int c)
* \param at Index of where we want to insert the char */ * \param at Index of where we want to insert the char */
void editorRowInsertChar(struct editorConfig *E, 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;
} }
@@ -103,17 +111,16 @@ void editorRowInsertChar(struct editorConfig *E, erow *row, int at, int c) {
++row->size; ++row->size;
row->chars[at] = c; row->chars[at] = c;
editorUpdateRow(row); editorUpdateRow(row);
++E->dirty; ++E.dirty;
} }
void editorRowAppendString(struct editorConfig *E, erow *row, char *s, void editorRowAppendString(erow *row, char *s, size_t len) {
size_t len) {
row->chars = realloc(row->chars, row->size + len + 1); row->chars = realloc(row->chars, row->size + len + 1);
memcpy(&row->chars[row->size], s, len); memcpy(&row->chars[row->size], s, len);
row->size += len; row->size += len;
row->chars[row->size] = '\0'; row->chars[row->size] = '\0';
editorUpdateRow(row); editorUpdateRow(row);
++E->dirty; ++E.dirty;
} }
/** /**
@@ -121,19 +128,12 @@ void editorRowAppendString(struct editorConfig *E, erow *row, char *s,
* \brief Delete the a char at the chosen position on the given row * \brief Delete the a char at the chosen position on the given row
* \param at Index of the char to delete * \param at Index of the char to delete
* \param row Row on operation is made */ * \param row Row on operation is made */
void editorRowDelchar(struct editorConfig *E, erow *row, int at) { void editorRowDelchar(erow *row, int at) {
if (at < 0 || at >= row->size) { if (at < 0 || at >= row->size) {
return; return;
} }
memmove(&row->chars[at], &row->chars[at + 1], row->size - at); memmove(&row->chars[at], &row->chars[at + 1], row->size - at);
--row->size; --row->size;
editorUpdateRow(row); editorUpdateRow(row);
++E->dirty; ++E.dirty;
} }
void log_string(char * string){
FILE * fd = fopen("tmp/log.txt", "a");
fprintf(fd, "%s\n", string);
fclose(fd);
}
+9 -10
View File
@@ -1,28 +1,28 @@
#include "../include/terminal.h" #include "../include/terminal.h"
#include "../include/data.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
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);
} }
void disableRawMode(struct editorConfig *E) { void disableRawMode() {
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &E->orig_termios) == -1) { if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &E.orig_termios) == -1) {
free(E);
die("tcsetattr"); die("tcsetattr");
} }
} }
void enableRawMode(struct editorConfig *E) { void enableRawMode() {
if (tcgetattr(STDIN_FILENO, &E->orig_termios) == -1) { if (tcgetattr(STDIN_FILENO, &E.orig_termios) == -1) {
die("tcgetattr"); die("tcgetattr");
} }
struct termios raw = E->orig_termios; struct termios raw = E.orig_termios;
raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
raw.c_oflag &= ~(OPOST); raw.c_oflag &= ~(OPOST);
raw.c_cflag |= (CS8); raw.c_cflag |= (CS8);
@@ -31,7 +31,7 @@ void enableRawMode(struct editorConfig *E) {
raw.c_cc[VTIME] = 1; raw.c_cc[VTIME] = 1;
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1) { if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1) {
die("tcsetattr"); die("tcgetattr");
} }
} }
@@ -45,7 +45,6 @@ int editorReadKey() {
} }
} }
fprintf(stderr, "%X (%c)\n", c, c);
if (c == '\x1b') { if (c == '\x1b') {
if (read(STDIN_FILENO, &seq[0], 1) != 1 || if (read(STDIN_FILENO, &seq[0], 1) != 1 ||
read(STDIN_FILENO, &seq[1], 1) != 1) { read(STDIN_FILENO, &seq[1], 1) != 1) {