3 Commits

Author SHA1 Message Date
c9977b0fc0 checkpoint
Some checks are pending
Release / Bump Homebrew formula (push) Waiting to run
2025-11-22 12:00:50 -08:00
dd2c888766 update man page
Some checks are pending
Release / Bump Homebrew formula (push) Waiting to run
2025-11-22 01:48:31 -08:00
2967998893 Update README
Some checks are pending
Release / Bump Homebrew formula (push) Waiting to run
2025-11-22 01:45:59 -08:00
4 changed files with 63 additions and 38 deletions

View File

@@ -6,6 +6,7 @@ set(KE_VERSION "1.0.4")
set(CMAKE_C_FLAGS "-Wall -Wextra -pedantic -Wshadow -Werror -std=c99 -g") set(CMAKE_C_FLAGS "-Wall -Wextra -pedantic -Wshadow -Werror -std=c99 -g")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_DEFAULT_SOURCE -D_XOPEN_SOURCE") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_DEFAULT_SOURCE -D_XOPEN_SOURCE")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
# Add executable # Add executable

View File

@@ -6,6 +6,9 @@ used fairly often.
See the man page for more info. See the man page for more info.
It should be available via homebrew, even. It should be available via homebrew, even:
brew tap kisom/homebrew-tap
brew install ke
Released under an ISC license. Released under an ISC license.

2
ke.1
View File

@@ -24,8 +24,6 @@ saving a file can be done with either C-k s or C-k C-s.
.Bl -tag -width xxxxxxxxxxxx -offset indent .Bl -tag -width xxxxxxxxxxxx -offset indent
.It C-k BACKSPACE .It C-k BACKSPACE
Delete from the cursor to the beginning of the line. Delete from the cursor to the beginning of the line.
.It C-k C-d
Delete the current row.
.It C-k d .It C-k d
Delete from the cursor to the end of the line. Delete from the cursor to the end of the line.
.It C-k e .It C-k e

93
main.c
View File

@@ -30,6 +30,14 @@
#define TAB_STOP 8 #define TAB_STOP 8
#define MSG_TIMEO 3 #define MSG_TIMEO 3
/*
* Provide a sensiblerdefault version string if not supplied by the
* build system
*/
#ifndef KE_VERSION
#define KE_VERSION "ke devel"
#endif
/* /*
* define the keyboard input modes * define the keyboard input modes
* normal: no special mode * normal: no special mode
@@ -50,13 +58,18 @@
int int
next_power_of_2(int n) next_power_of_2(int n)
{ {
if (n < 2) {
n = 2;
}
n--; n--;
n |= n >> 1; n |= n >> 1;
n |= n >> 2; n |= n >> 2;
n |= n >> 4; n |= n >> 4;
n |= n >> 8; n |= n >> 8;
n |= n >> 16; n |= n >> 16;
return n+1;
return n + 1;
} }
/* /*
@@ -65,15 +78,15 @@ next_power_of_2(int n)
int int
cap_growth(int cap, int sz) cap_growth(int cap, int sz)
{ {
if (cap == 0) { if (cap == 0) {
return INITIAL_BUFSIZE; cap = INITIAL_BUFSIZE;
} }
while (sz < cap) { while (cap <= sz) {
cap = next_power_of_2(cap); cap = next_power_of_2(cap + 1);
} }
return cap; return cap;
} }
@@ -272,7 +285,11 @@ ab_append(struct abuf *buf, const char *s, int len)
buf->cap = 64; buf->cap = 64;
} }
while (sz < buf->cap) { /*
* grow until capacity is at least the required
* size
*/
while (sz > buf->cap) {
if (buf->cap > INT_MAX/2) { if (buf->cap > INT_MAX/2) {
buf->cap = INT_MAX; buf->cap = INT_MAX;
break; break;
@@ -367,9 +384,10 @@ erow_update(struct erow *row)
* TODO(kyle): I'm not thrilled with this double-render. * TODO(kyle): I'm not thrilled with this double-render.
*/ */
for (j = 0; j < row->size; j++) { for (j = 0; j < row->size; j++) {
if (row->line[j] == '\t') { unsigned char ch = (unsigned char)row->line[j];
if (ch == '\t') {
tabs++; tabs++;
} else if (!isprint(row->line[j])) { } else if (!isprint(ch)) {
ctrl++; ctrl++;
} }
} }
@@ -379,20 +397,21 @@ erow_update(struct erow *row)
row->rsize = 0; row->rsize = 0;
} }
row->render = NULL; row->render = NULL;
row->render = malloc(row->size + (tabs * (TAB_STOP-1)) + (ctrl * 3) + 1); row->render = malloc(row->size + (tabs*(TAB_STOP-1)) + (ctrl*3) + 1);
assert(row->render != NULL); assert(row->render != NULL);
for (j = 0; j < row->size; j++) { for (j = 0; j < row->size; j++) {
if (row->line[j] == '\t') { unsigned char ch = (unsigned char)row->line[j];
if (ch == '\t') {
do { do {
row->render[i++] = ' '; row->render[i++] = ' ';
} while ((i % TAB_STOP) != 0); } while ((i % TAB_STOP) != 0);
} else if (!isprint(row->line[j])) { } else if (!isprint(ch)) {
row->render[i++] = '\\'; row->render[i++] = '\\';
row->render[i++] = nibble_to_hex(row->line[j] >> 4); row->render[i++] = nibble_to_hex((char)(ch >> 4));
row->render[i++] = nibble_to_hex(row->line[j] & 0x0f); row->render[i++] = nibble_to_hex((char)(ch & 0x0f));
} else { } else {
row->render[i++] = row->line[j]; row->render[i++] = (char)ch;
} }
} }
@@ -540,6 +559,8 @@ row_append_row(struct erow *row, char *s, int len)
assert(row->line != NULL); assert(row->line != NULL);
memcpy(&row->line[row->size], s, len); memcpy(&row->line[row->size], s, len);
row->size += len; row->size += len;
row->cap = row->size + 1;
row->line[row->size] = '\0'; row->line[row->size] = '\0';
erow_update(row); erow_update(row);
editor.dirty++; editor.dirty++;
@@ -549,8 +570,8 @@ row_append_row(struct erow *row, char *s, int len)
void void
row_insert_ch(struct erow *row, int at, int16_t c) row_insert_ch(struct erow *row, int at, int16_t c)
{ {
int ncap = 0; int ncap = 0;
char *nline = NULL; char *nline = NULL;
/* /*
* row_insert_ch just concerns itself with how to update a row. * row_insert_ch just concerns itself with how to update a row.
@@ -560,26 +581,27 @@ row_insert_ch(struct erow *row, int at, int16_t c)
} }
assert(c > 0); assert(c > 0);
if (row->size == row->cap) { /* We will move existing bytes including the current NUL, so we need
ncap = cap_growth(row->cap, row->size+1); * at least row->size + 2 bytes of storage (new char + NUL). Ensure
nline = realloc(row->line, ncap); * capacity exceeds index row->size + 1. */
if (row->size + 1 >= row->cap) {
ncap = cap_growth(row->cap, row->size + 1);
nline = realloc(row->line, ncap);
assert(nline != NULL); assert(nline != NULL);
if (nline == NULL) { if (nline == NULL) {
return; return;
} }
row->cap = ncap; row->cap = ncap;
row->line = nline; row->line = nline;
} }
row->line = realloc(row->line, row->size+2); memmove(&row->line[at+1], &row->line[at], row->size - at + 1);
assert(row->line != NULL); row->size++;
memmove(&row->line[at+1], &row->line[at], row->size - at + 1); row->line[at] = c & 0xff;
row->size++;
row->line[at] = c & 0xff;
erow_update(row); erow_update(row);
} }
@@ -1141,6 +1163,7 @@ process_kcommand(int16_t c)
case 'x': case 'x':
exit(save_file()); exit(save_file());
case CTRL_KEY('d'): case CTRL_KEY('d'):
case CTRL_KEY('y'):
delete_row(editor.cury); delete_row(editor.cury);
break; break;
case 'd': case 'd':