temp commit

This commit is contained in:
2026-05-22 13:40:03 +02:00
parent bc66e673fa
commit edb5384f0e
23 changed files with 848 additions and 621 deletions
+282 -205
View File
@@ -13,6 +13,7 @@
#include "../include/row_op.h"
#include "../include/split_screen.h"
#include "../include/syntax_highlighter.h"
#include "../include/terminal.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -23,127 +24,135 @@ extern struct editorConfig E;
/**
* @brief Renders a single pane with its buffer content
*/
static void editorDrawPane(struct abuf *ab, EditorPane *pane) {
if (pane == NULL || pane->buffer_id < 0)
return;
struct buffer_t *buf = bufferFindById(pane->buffer_id);
if (buf == NULL)
return;
// Draw content for this pane
for (int y = 0; y < pane->height; y++) {
int file_row = y + pane->row_offset;
// Position cursor at start of pane row
static void editorDrawPane(struct abuf* ab, EditorPane* pane)
{
int file_row;
char pos_buf[32];
int pos_len = snprintf(pos_buf, sizeof(pos_buf), "\x1b[%d;%dH",
pane->start_row + y + 1, pane->start_col + 1);
abAppend(ab, pos_buf, pos_len);
int pos_len;
int chars_printed;
int start_offset;
int byte_len_to_print;
int bytes_to_print;
char* highlighted;
char welcome[80];
int welcome_len;
int padding;
// Apply background color (6 bytes for RGB format)
abAppend(ab, E.theme.BACKGROUND_COLOR, strlen(E.theme.BACKGROUND_COLOR));
if (pane == NULL || pane->buffer_id < 0)
return;
int chars_printed = 0;
const struct buffer_t* buf = bufferFindById(pane->buffer_id);
if (buf == NULL)
return;
if (file_row >= buf->numrows) {
// Empty line - show tilde
if (buf->numrows == 0 && y == pane->height / 3) {
char welcome[80];
int welcome_len =
snprintf(welcome, sizeof(welcome), "Buffer %d", pane->buffer_id);
if (welcome_len > pane->width)
welcome_len = pane->width;
// Draw all pane
for (int y = 0; y < pane->height; y++)
{
file_row = y + pane->y_offset;
int padding = (pane->width - welcome_len) / 2;
if (padding) {
abAppend(ab, "~", 1);
chars_printed++;
padding--;
// Set cursor at start of pane row
pos_len = snprintf(pos_buf, sizeof(pos_buf), "\x1b[%d;%dH",
pane->origin_y + y + 1, pane->origin_x + 1);
abAppend(ab, pos_buf, pos_len);
// Apply background color (6 bytes for RGB format)
abAppend(ab, E.theme.BACKGROUND_COLOR, strlen(E.theme.BACKGROUND_COLOR));
chars_printed = 0;
// pane line is out of buffer
if (file_row >= buf->numrows)
{
// Empty line - show tilde
abAppend(ab, "~", 1);
for (int i = 0;
i < pane->width - 1;
++i)
{
abAppend(ab, " ", 1);
}
}
while (padding-- && chars_printed < pane->width) {
abAppend(ab, " ", 1);
chars_printed++;
else
{
start_offset = pane->x_offset;
if (buf->filename[strlen(buf->filename) - 1] == 'c')
{
// Render line with syntax highlighting, constrain to pane width
highlighted = highlight_line(
&buf->row[file_row].chars[pane->x_offset], &byte_len_to_print);
// Print only up to pane width
abAppend(ab, highlighted, byte_len_to_print);
free(highlighted);
}
else
{
// Render basic line
bytes_to_print =
buf->row[file_row].size - pane->x_offset < pane->width
? buf->row[file_row].size - pane->x_offset
: pane->width;
abAppend(ab, &buf->row[file_row].chars[pane->x_offset], bytes_to_print);
}
// Fill remaining space with background color to pane width
for (int i = 0;
i < pane->width - editorRowCharCount(&buf->row[file_row], pane->width) + pane->x_offset;
++i)
{
abAppend(ab, " ", 1);
}
}
abAppend(ab, welcome, welcome_len);
chars_printed += welcome_len;
} else {
abAppend(ab, "~", 1);
chars_printed++;
}
} else {
// Render line with syntax highlighting, constrain to pane width
int start_offset = pane->col_offset;
int visible_len = buf->row[file_row].rsize - start_offset;
if (visible_len < 0)
visible_len = 0;
if (visible_len > pane->width)
visible_len = pane->width;
if (buf->filename[strlen(buf->filename) - 1] == 'c') {
int byte_len_to_print;
char *highlighted = highlight_line(
&buf->row[file_row].render[start_offset], &byte_len_to_print);
// Print only up to pane width
abAppend(ab, highlighted, byte_len_to_print);
free(highlighted);
} else {
abAppend(ab, &buf->row[file_row].render[start_offset], buf->row[file_row].rsize);
}
chars_printed = visible_len;
}
// Fill remaining space with background color to pane width
abAppend(ab, E.theme.BACKGROUND_COLOR, strlen(E.theme.BACKGROUND_COLOR));
while (chars_printed < pane->width) {
abAppend(ab, " ", 1);
chars_printed++;
}
// Restore background color at end of line
}
}
/**
* @brief Renders all panes based on current split configuration
*/
static void editorDrawAllPanes(struct abuf *ab) {
ScreenLayout *layout = splitScreenGetLayout();
static void editorDrawAllPanes(struct abuf* ab)
{
const ScreenLayout* layout = splitScreenGetLayout();
if (layout->num_panes == 1) {
// Single pane fullscreen
editorDrawPane(ab, &layout->panes[0]);
} else if (layout->num_panes == 2) {
// Draw both panes
for (int i = 0; i < 2; i++) {
editorDrawPane(ab, &layout->panes[i]);
// Draw pane border/divider if not the last pane
if (layout->mode == SPLIT_VERTICAL && i == 0) {
// Draw vertical divider
int divider_col = layout->panes[0].width;
for (int y = 0; y < layout->panes[0].height; y++) {
char pos_buf[32];
snprintf(pos_buf, sizeof(pos_buf), "\x1b[%d;%dH", y + 1, divider_col);
abAppend(ab, pos_buf, strlen(pos_buf));
abAppend(ab, "\x1b[1m|\x1b[0m", 9); // Bold pipe divider
}
} else if (layout->mode == SPLIT_HORIZONTAL && i == 0) {
// Draw horizontal divider
int divider_row = layout->panes[0].height;
char pos_buf[32];
snprintf(pos_buf, sizeof(pos_buf), "\x1b[%d;%dH", divider_row + 1, 1);
abAppend(ab, pos_buf, strlen(pos_buf));
for (int x = 0; x < E.screencols; x++) {
abAppend(ab, "\x1b[1m-\x1b[0m", 9); // Bold dash divider
}
}
if (layout->num_panes == 1)
{
// Single pane fullscreen
editorDrawPane(ab, &layout->panes[0]);
}
else if (layout->num_panes == 2)
{
// Draw both panes
for (int i = 0; i < 2; i++)
{
editorDrawPane(ab, &layout->panes[i]);
// Draw pane border/divider if not the last pane
if (layout->mode == SPLIT_VERTICAL && i == 0)
{
// Draw vertical divider
int divider_col = layout->panes[0].width;
for (int y = 0; y < layout->panes[0].height; y++)
{
char pos_buf[32];
snprintf(pos_buf, sizeof(pos_buf), "\x1b[%d;%dH", y + 1, divider_col);
abAppend(ab, pos_buf, strlen(pos_buf));
abAppend(ab, "\x1b[1m|\x1b[0m", 9); // Bold pipe divider
}
}
else if (layout->mode == SPLIT_HORIZONTAL && i == 0)
{
// Draw horizontal divider
int divider_row = layout->panes[0].height;
char pos_buf[32];
snprintf(pos_buf, sizeof(pos_buf), "\x1b[%d;%dH", divider_row + 1, 1);
abAppend(ab, pos_buf, strlen(pos_buf));
for (int x = 0; x < E.screencols; x++)
{
abAppend(ab, "\x1b[1m-\x1b[0m", 9); // Bold dash divider
}
}
}
}
}
}
/**
@@ -153,35 +162,89 @@ static void editorDrawAllPanes(struct abuf *ab) {
* @note Updates global editor state E
* @see editorRowCxToRx()
*/
void editorScroll() {
EditorPane *active = splitScreenGetActivePane();
struct buffer_t *buf = bufferFindById(active->buffer_id);
active->rx = active->cursor_x;
void editorScroll()
{
EditorPane* active = splitScreenGetActivePane();
struct buffer_t* buf = bufferFindById(active->buffer_id);
int rel_x, rel_y;
fprintf(stderr, "%d %d / %d %d\n", active->cursor_x, active->col_offset,
active->cursor_y, active->row_offset);
// compute relative coordinates
rel_x = editorRowCharCount(&buf->row[buf->y], buf->x);
appDebug("counting %d\n", rel_x);
rel_y = buf->y;
if (active->cursor_x < 0) {
active->cursor_x = 0;
active->col_offset = active->col_offset == 0 ? 0 : --active->col_offset;
}
appDebug("%d %d / %d %d\n", active->cursor_x, active->x_offset,
active->cursor_y, active->y_offset);
if (active->cursor_y < 0) {
active->cursor_y = 0;
active->row_offset = active->row_offset == 0 ? 0 : --active->row_offset;
}
while (rel_x != active->cursor_x + active->x_offset ||
rel_y != active->cursor_y + active->y_offset)
{
if (rel_x < active->cursor_x + active->x_offset)
{
// LEFT
if (active->cursor_x == 0 && active->x_offset)
{
active->x_offset--;
} else
{
active->cursor_x--;
}
} else
{
// RIGHT
if (rel_x > active->cursor_x + active->x_offset)
{
if (active->cursor_x == active->width - 1)
{
active->x_offset++;
} else
{
active->cursor_x++;
}
}
}
if (active->cursor_x == active->width) {
if (rel_y < active->cursor_y + active->y_offset)
{
if (active->cursor_y == 0 && active->y_offset)
{
active->y_offset--;
} else
{
active->cursor_y--;
}
}
active->cursor_x--;
active->col_offset++;
}
if (rel_y > active->cursor_y + active->y_offset)
{
if (active->cursor_y == active->height - 1)
{
active->y_offset++;
} else
{
active->cursor_y++;
}
}
if (active->cursor_y == active->height) {
}
}
active->cursor_y--;
active->row_offset++;
}
char * basename(char *path)
{
int len = strlen(path);
int flag=0;
for(int i=len-1; i>0; i--)
{
if(path[i]=='/' )
{
flag=1;
path = path+i+1;
break;
}
}
return path;
}
/**
@@ -192,55 +255,63 @@ void editorScroll() {
* @param ab Pointer to append buffer structure for accumulating output
* @note Uses ANSI escape codes for color inversion
*/
void editorDrawStatusBar(struct abuf *ab) {
int len, render_len;
char status[80], render_status[80];
EditorPane *active = splitScreenGetActivePane();
struct buffer_t *buf = bufferFindById(active->buffer_id);
void editorDrawStatusBar(struct abuf* ab)
{
// TO MODIFY
int len, render_len;
char status[E.screencols], render_status[E.screencols * 4];
EditorPane* active = splitScreenGetActivePane();
struct buffer_t* buf = bufferFindById(active->buffer_id);
abAppend(ab, "\x1b[7m", 4); // inverting colors
abAppend(ab, "\x1b[7m", 4); // inverting colors
const char *mode_str = "";
ScreenLayout *layout = splitScreenGetLayout();
if (layout->mode == SPLIT_VERTICAL)
mode_str = " [V-SPLIT]";
else if (layout->mode == SPLIT_HORIZONTAL)
mode_str = " [H-SPLIT]";
const char* mode_str = "";
ScreenLayout* layout = splitScreenGetLayout();
if (layout->mode == SPLIT_VERTICAL)
mode_str = " [V-SPLIT]";
else if (layout->mode == SPLIT_HORIZONTAL)
mode_str = " [H-SPLIT]";
// Build buffer status showing all buffers with dirty indicators
char buf_status[200] = "";
int offset = 0;
for (int i = 0; i < E.number_of_buffer; i++) {
struct buffer_t *b = &E.buffers[i];
char marker = (b->buffer_id == active->buffer_id) ? '>' : ' ';
char dirty_marker = b->dirty ? '*' : ' ';
offset += snprintf(&buf_status[offset], sizeof(buf_status) - offset,
"%c%d:%s%c ", marker, b->buffer_id,
b->filename ? b->filename : "[No Name]", dirty_marker);
}
len = snprintf(status, sizeof(status), "%s%s", buf_status, mode_str);
render_len = snprintf(render_status, sizeof(render_status), "%d/%d",
active->cursor_y + 1, buf->numrows);
if (len > E.screencols) {
len = E.screencols;
}
abAppend(ab, status, len);
while (len < E.screencols) {
if (E.screencols - len == render_len) {
abAppend(ab, render_status, render_len);
break;
} else {
abAppend(ab, " ", 1);
++len;
// Build buffer status showing all buffers with dirty indicators
char buf_status[1024] = "";
int offset = 0;
for (int i = 0; i < E.number_of_buffer; i++)
{
struct buffer_t* b = &E.buffers[i];
char marker = (b->buffer_id == active->buffer_id) ? '>' : ' ';
char dirty_marker = b->dirty ? '*' : ' ';
offset += snprintf(&buf_status[offset], sizeof(buf_status) - offset,
"%c%d:%s%c ", marker, b->buffer_id,
b->filename ? basename(b->filename) : "[No Name]", dirty_marker);
}
}
abAppend(ab, "\x1b[m", 3); // normal text mode
abAppend(ab, "\r\n", 2);
len = snprintf(status, sizeof(status), "%s%s", buf_status, mode_str);
render_len = snprintf(render_status, sizeof(render_status), "%d/%d",
active->cursor_y + 1, buf->numrows);
if (len > E.screencols)
{
len = E.screencols;
}
abAppend(ab, status, len);
while (len < E.screencols)
{
if (E.screencols - len == render_len + 1)
{
abAppend(ab, render_status, render_len);
break;
}
else
{
abAppend(ab, " ", 1);
++len;
}
}
abAppend(ab, "\x1b[m", 3); // normal text mode
abAppend(ab, "\r\n", 2);
}
/**
@@ -250,15 +321,18 @@ void editorDrawStatusBar(struct abuf *ab) {
* @param ab Pointer to append buffer structure for accumulating output
* @note Messages are set by editorSetStatusMessage()
*/
void editorDrawMessageBar(struct abuf *ab) {
int msg_len = strlen(E.status_msg);
abAppend(ab, ERASE_END_LINE, 3);
if (msg_len > E.screencols) {
msg_len = E.screencols;
}
if (msg_len && time(NULL) - E.status_msg_time < 5) {
abAppend(ab, E.status_msg, msg_len);
}
void editorDrawMessageBar(struct abuf* ab)
{
int msg_len = strlen(E.status_msg);
abAppend(ab, ERASE_END_LINE, 3);
if (msg_len > E.screencols)
{
msg_len = E.screencols;
}
if (msg_len && time(NULL) - E.status_msg_time < 5)
{
abAppend(ab, E.status_msg, msg_len);
}
}
/**
@@ -272,33 +346,36 @@ void editorDrawMessageBar(struct abuf *ab) {
* @see editorDrawMessageBar()
*/
void editorRefreshScreen() {
struct abuf ab = ABUF_INIT;
char buf[32];
void editorRefreshScreen()
{
struct abuf ab = ABUF_INIT;
char buf[32];
abAppend(&ab, HIDE_CURSOR, 6);
abAppend(&ab, CURSOR_TOP_LEFT, 3);
abAppend(&ab, E.theme.BACKGROUND_COLOR,
strlen(E.theme.BACKGROUND_COLOR)); // RGB background is 12 bytes
abAppend(&ab, HIDE_CURSOR, 6);
abAppend(&ab, CURSOR_TOP_LEFT, 3);
abAppend(&ab, E.theme.BACKGROUND_COLOR,
strlen(E.theme.BACKGROUND_COLOR)); // RGB background is 12 bytes
// Draw all panes
editorScroll();
editorDrawAllPanes(&ab);
// Draw all panes
editorScroll();
editorDrawAllPanes(&ab);
// Draw status bar and message bar
editorDrawStatusBar(&ab);
editorDrawMessageBar(&ab);
// Draw status bar and message bar
editorDrawStatusBar(&ab);
editorDrawMessageBar(&ab);
// Position cursor in active pane
EditorPane *active = splitScreenGetActivePane();
if (active != NULL) {
snprintf(buf, sizeof(buf), "\x1b[%d;%dH",
active->cursor_y + active->start_row + 1,
active->cursor_x + active->start_col + 1);
abAppend(&ab, buf, strlen(buf));
}
// Position cursor in active pane
EditorPane* active = splitScreenGetActivePane();
struct buffer_t* buffer = bufferGetCurrent();
if (active != NULL)
{
snprintf(buf, sizeof(buf), "\x1b[%d;%dH",
active->cursor_y + active->origin_y + 1,
active->cursor_x + active->origin_x + 1);
abAppend(&ab, buf, strlen(buf));
}
abAppend(&ab, SHOW_CURSOR, 6);
write(STDOUT_FILENO, ab.b, ab.len);
abFree(&ab);
abAppend(&ab, SHOW_CURSOR, 6);
write(STDOUT_FILENO, ab.b, ab.len);
abFree(&ab);
}