Files
beluga/src/editor_op.c
T
2026-05-22 13:40:03 +02:00

121 lines
3.5 KiB
C

#include "../include/editor_op.h"
#include <stdarg.h>
#include "../include/row_op.h"
#include "../include/buffer.h"
#include "../include/data.h"
#include "../include/split_screen.h"
#include "../include/terminal.h"
#include "../include/utf8.h"
extern struct editorConfig E;
/**
* @brief Sets a temporary status message for display
* @details Formats and stores a message that will be displayed in the message
* bar for 5 seconds. Uses printf-style variable argument formatting.
* @param fmt Printf-style format string
* @param ... Variable arguments for format string
* @note Updates global editor state E (status_msg, status_msg_time)
* @see editorDrawMessageBar()
*/
void editorSetStatusMessage(const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vsnprintf(E.status_msg, E.screencols, fmt, ap);
va_end(ap);
E.status_msg_time = time(NULL);
}
void bufferInsertBytes(char* src, int n)
{
appDebug("bufferInsertBytes \r\n");
EditorPane* active = splitScreenGetActivePane();
struct buffer_t* buf = bufferFindById(active->buffer_id);
if (buf->y == buf->numrows)
{
bufferInsertRow(buf, buf->numrows, "", 0);
}
bufferRowInsertBytes(buf, &buf->row[buf->y], buf->x, src, n);
buf->x += n;
}
void bufferDelBytes(void)
{
EditorPane* active = splitScreenGetActivePane();
struct buffer_t* buf = bufferFindById(active->buffer_id);
/* Nothing to delete */
if (buf->numrows == 0) return;
if (buf->x == 0 && buf->y == 0) return;
/* Use row_offset, not col_offset, for row indexing */
row_t* r = &buf->row[buf->y];
if (buf->x > 0)
{
int byte_end = editorRowCxToByte(r, buf->x);
int byte_start = editorRowCxToByte(r, buf->x - 1);
int char_width = byte_end - byte_start; /* byte width of the character */
bufferRowDelByte(buf, r, byte_start, char_width);
E.dirty = 1;
}
else
{
/* Merge current row into the previous one */
row_t* prev = &buf->row[buf->y - 1]; // FIX: was buf->y (same as r)
int prev_char_count = editorRowCharCount(prev, prev->size);
bufferRowInsertBytes(buf, prev, prev->size, r->chars, r->size);
free(r->chars);
r->chars = NULL;
memmove(&buf->row[buf->y],
&buf->row[buf->y + 1],
sizeof(row_t) * (buf->numrows - buf->y - 1));
buf->numrows--;
active->cursor_x = prev_char_count;
buf->x = prev_char_count;
active->cursor_y--;
buf->y--;
E.dirty = 1;
}
}
void bufferInsertNewLine(void) {
appDebug("Inserting new line\n");
EditorPane *active = splitScreenGetActivePane();
struct buffer_t *buf = bufferFindById(active->buffer_id);
appDebug("buf x %d\n", buf->x);
if (buf->y >= buf->numrows) {
/* Cursor is past the last row: just append a blank line */
bufferInsertRow(buf, buf->numrows, "", 0);
} else {
row_t *row = &buf->row[buf->y];
/* Insert the tail (from cursor to end) as a new row below */
bufferInsertRow(buf, buf->y + 1, &row->chars[buf->x], row->size - buf->x);
/* Re-fetch: realloc inside bufferInsertRow may have moved the array */
row = &buf->row[buf->y];
/* Truncate the current row at the cursor */
row->size = buf->x;
row->chars[row->size] = '\0';
/* Do NOT touch row->cap — the allocation is still valid */
}
buf->y++;
buf->x = 0;
appDebug("Insert new line done\n");
}