70 Commits

Author SHA1 Message Date
2c3b2ae0f0 bump version
Some checks failed
Release / Bump Homebrew formula (push) Has been cancelled
2025-11-26 15:25:37 -08:00
a605e47458 kbhit makes it go a lot faster 2025-11-26 15:25:32 -08:00
40ee1e8d7b kill unused declaration. 2025-11-26 13:46:48 -08:00
4464159301 remove all undo stuff to start over 2025-11-26 13:45:44 -08:00
dc9fb58a41 remove all undo stuff to start over 2025-11-26 13:40:08 -08:00
bbd682cec7 Remove and start over with some of the undo stuff. 2025-11-26 08:25:41 -08:00
ace25c5c65 more undo work 2025-11-26 03:00:49 -08:00
09881706f2 bump version
Some checks failed
Release / Bump Homebrew formula (push) Has been cancelled
2025-11-26 02:25:29 -08:00
2579bb01c8 fix C-e bug 2025-11-26 02:24:56 -08:00
a528b3fc3e universal args, more work on undo. 2025-11-26 02:12:37 -08:00
faa70af9b7 Working on undo system. 2025-11-26 01:45:56 -08:00
e1abaae6aa unindent, formatting fixups, and fix memleak
I think clion royally wrecked my formatting. Going to keep
fixing it up as I find stuff.
2025-11-26 00:26:07 -08:00
329b92f382 bump version
Some checks failed
Release / Bump Homebrew formula (push) Has been cancelled
2025-11-25 22:33:50 -08:00
12553f301b delete region works. 2025-11-25 22:31:03 -08:00
75b19042b9 add support for reloading the current file 2025-11-25 21:20:13 -08:00
1a184b1a08 minor fixups 2025-11-25 16:32:07 -08:00
acde895fb7 bump version
Some checks failed
Release / Bump Homebrew formula (push) Has been cancelled
2025-11-25 15:50:35 -08:00
78d522ba98 quality of life improvements 2025-11-25 15:50:05 -08:00
feb6667a24 add missing function declarations 2025-11-25 15:32:17 -08:00
Jeremy O'Brien
66c79e0762 fix manpage install with cmake 2025-11-25 13:51:28 -08:00
a51b98c31f switch nix build to cmake 2025-11-25 09:21:03 -08:00
707362574c fixups for nixos 2025-11-25 09:18:26 -08:00
56db8bd8d2 Indent region, version bump.
Some checks failed
Release / Bump Homebrew formula (push) Has been cancelled
2025-11-25 00:47:06 -08:00
a32ef2ff53 move to first non-whitespace on next line
Some checks failed
Release / Bump Homebrew formula (push) Has been cancelled
2025-11-25 00:20:32 -08:00
0c0c3d9ce5 fix arrows in search 2025-11-25 00:12:44 -08:00
7245003769 cleanups 2025-11-24 23:05:40 -08:00
542b1d90a0 bump version
Some checks failed
Release / Bump Homebrew formula (push) Has been cancelled
2025-11-24 22:59:40 -08:00
a359f4e6c4 fix Makefile CFLAGS for nix 2025-11-24 22:59:09 -08:00
a03dd0c433 bump version
Some checks failed
Release / Bump Homebrew formula (push) Has been cancelled
2025-11-24 22:52:25 -08:00
561faf537c Updating docs. 2025-11-24 22:51:10 -08:00
3a36b35c1f support running cloc over the file 2025-11-24 22:51:10 -08:00
Jeremy O'Brien
b1cb2532f6 add flake + default.nix 2025-11-24 22:43:40 -08:00
9f33cdc0e4 bump version
Some checks failed
Release / Bump Homebrew formula (push) Has been cancelled
2025-11-24 22:15:11 -08:00
afcc33329f add C-k l to get lines of code 2025-11-24 22:14:51 -08:00
128235283c bump version
Some checks failed
Release / Bump Homebrew formula (push) Has been cancelled
1.3.0: mark/region
2025-11-24 21:41:04 -08:00
af3c0eddc4 set editor position 2025-11-24 21:38:04 -08:00
f8f01f7dd6 don't clear mark in kill/delete_region 2025-11-24 21:32:23 -08:00
8206ab0a40 fixed counting, I think 2025-11-24 21:21:37 -08:00
af8dcb847e working on delete-region 2025-11-24 21:14:56 -08:00
9434a34116 kill_region appears to work 2025-11-24 20:49:55 -08:00
3b2b60466c continuing region work 2025-11-24 20:27:30 -08:00
52e1f2dd8b Cleaning up; start mark/region work. 2025-11-24 20:07:15 -08:00
8bb9228339 clean asan logs 2025-11-24 19:17:06 -08:00
e937e3398c Dumb typo.
Some checks failed
Release / Bump Homebrew formula (push) Has been cancelled
2025-11-24 14:41:11 -08:00
f147c866ab v1.2.0 with basic killring.
Some checks failed
Release / Bump Homebrew formula (push) Has been cancelled
2025-11-24 14:37:33 -08:00
1227d0abf4 Support basic killing/yanking. 2025-11-24 14:35:44 -08:00
d3591331a5 Update man page with yank. 2025-11-24 14:03:12 -08:00
5eafc1a34b local install in Makefile 2025-11-24 13:57:10 -08:00
a0103dd5aa Start killring work. 2025-11-24 13:46:00 -08:00
3782880062 UTF-8 support. 2025-11-24 13:11:24 -08:00
e345b55595 Fix version number
Some checks failed
Release / Bump Homebrew formula (push) Has been cancelled
2025-11-24 11:05:51 -08:00
d1978a3b98 Code cleanups and editor fixups.
Some checks failed
Release / Bump Homebrew formula (push) Has been cancelled
2025-11-24 10:54:48 -08:00
5ee8234ab7 Update the manpage.
Print the core dump k-command correctly.
2025-11-24 10:23:39 -08:00
f82d1f8831 move nix to nixos config 2025-11-24 10:22:48 -08:00
2019ec10ce local testing updates 2025-11-23 19:15:19 -08:00
0110f82705 bump version
Some checks failed
Release / Bump Homebrew formula (push) Has been cancelled
2025-11-23 14:26:17 -08:00
a62a8e50fa find_prev_word and delete_prev_word work. 2025-11-23 14:24:49 -08:00
33e19e7d76 add Makefile for basic build 2025-11-23 11:48:46 -08:00
fd01e3593f delete next word complete, delete prev in progress. 2025-11-23 11:48:35 -08:00
47bbc5339c forward/backward word. 2025-11-23 00:19:25 -08:00
2962a6c92e start word nav 2025-11-22 23:31:49 -08:00
7fa887273b move nix to nixos config 2025-11-22 23:31:49 -08:00
fb02f37512 make ASan a compile time option 2025-11-22 23:27:34 -08:00
1722dbee0b Fix check for render realloc. 2025-11-22 12:50:22 -08:00
14199afeb5 bump version
Some checks failed
Release / Bump Homebrew formula (push) Has been cancelled
2025-11-22 12:36:41 -08:00
9f3558c430 put it in build, not build/bin
Some checks failed
Release / Bump Homebrew formula (push) Has been cancelled
2025-11-22 12:27:02 -08:00
ce64e4637d clean up 2025-11-22 12:15:53 -08:00
36013e42e4 version bump
Some checks failed
Release / Bump Homebrew formula (push) Has been cancelled
2025-11-22 12:13:56 -08:00
dd667c1ef5 revert back to older version with some previous fixes
the ai was getting wild
2025-11-22 12:13:03 -08:00
c9977b0fc0 checkpoint
Some checks failed
Release / Bump Homebrew formula (push) Has been cancelled
2025-11-22 12:00:50 -08:00
12 changed files with 2323 additions and 510 deletions

2
.gitignore vendored
View File

@@ -1,2 +1,4 @@
*.log
build
ke
*.txt

View File

@@ -2,20 +2,29 @@ cmake_minimum_required(VERSION 3.15)
project(ke C) # Specify C language explicitly
set(CMAKE_C_STANDARD 99)
set(KE_VERSION "1.0.4")
set(KE_VERSION "1.5.1")
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")
# Optionally enable AddressSanitizer (ASan)
option(ENABLE_ASAN "Enable AddressSanitizer for builds" OFF)
if (ENABLE_ASAN)
message(STATUS "ASan enabled")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
# Ensure the sanitizer is linked too (especially important on some platforms)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
endif()
include(GNUInstallDirs)
# Add executable
add_executable(ke main.c)
# Define KE_VERSION for use in C code (e.g., #define KE_VERSION)
target_compile_definitions(ke PRIVATE KE_VERSION="ke version ${KE_VERSION}")
install(TARGETS ke RUNTIME DESTINATION bin)
install(FILES ke.1 TYPE MAN)
install(TARGETS ke RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES ke.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
# Set output properties
set_target_properties(ke PROPERTIES
FOLDER bin
RUNTIME_OUTPUT_DIRECTORY bin
)

33
Makefile Normal file
View File

@@ -0,0 +1,33 @@
TARGET := ke
KE_VERSION := devel
DEST := $(HOME)/.local/bin/$(TARGET)
CFLAGS := -Wall -Wextra -pedantic -Wshadow -Werror -std=c99 -g
CFLAGS += -Wno-unused-result
CFLAGS += -D_DEFAULT_SOURCE -D_XOPEN_SOURCE
CFLAGS += -fsanitize=address -fno-omit-frame-pointer
LDFLAGS := -fsanitize=address
all: $(TARGET) test.txt
$(TARGET): main.c
$(CC) $(CFLAGS) -o $(TARGET) $(LDFLAGS) main.c
.PHONY: install
#install: $(TARGET)
install:
cp $(TARGET) $(DEST)
clean:
rm -f $(TARGET)
rm -f asan.log*
.PHONY: test.txt
test.txt:
cp test.txt.bak $@
.PHONY: gdb
gdb:
@test -f $(TARGET).pid || (echo "error: $(TARGET).pid not found" >&2; exit 1)
@gdb -p $$(cat $(TARGET).pid | tr -d ' \t\n\r') ./$(TARGET)

View File

@@ -11,4 +11,11 @@ It should be available via homebrew, even:
brew tap kisom/homebrew-tap
brew install ke
Released under an ISC license.
To get verbose ASAN messages:
export LSAN_OPTIONS=verbosity=1:log_threads=1
Released under an ISC license.
Started by following along with kilo:
https://viewsourcecode.org/snaptoken/kilo/

17
TODO
View File

@@ -1,15 +1,18 @@
[X] goto-line
[X] text-corruption bug
[ ] alt-modifiers
[ ] refresh-screen
[ ] functions -> keymapping?
[x] refresh-screen
[ ] functions -> keymapping? (what did this even mean)
[X] rendering: need to skip over control characters like we do with tabs
[X] control-d -> delete
[ ] control-g -> exit buf prompt
[ ] load-file prompt on dirty buffer
[x] control-g -> exit buf prompt
[x] load-file prompt on dirty buffer
[ ] multiple files
[x] utf-8
[x] kill ring
[x] mark/region
What would it take for ke to be your daily drives?
+ C-u
+ Alt nav (backspace, delete, f, b, etc)
[x] C-u (repeat actions)
[x] Alt nav (backspace, delete, f, b, etc)
[-] undo tree (C-k u/U)

34
default.nix Normal file
View File

@@ -0,0 +1,34 @@
{
lib,
stdenv,
cmake,
installShellFiles,
...
}:
stdenv.mkDerivation {
pname = "ke";
version = "1.5.1";
src = lib.cleanSource ./.;
nativeBuildInputs = [
cmake
installShellFiles
];
cmakeFlags = [
"-DENABLE_ASAN=on"
"-DCMAKE_BUILD_TYPE=Debug"
];
installPhase = ''
runHook preInstall
mkdir -p $out/bin
cp ke $out/bin/
installManPage ../ke.1
runHook postInstall
'';
}

27
flake.lock generated Normal file
View File

@@ -0,0 +1,27 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1763835633,
"narHash": "sha256-HzxeGVID5MChuCPESuC0dlQL1/scDKu+MmzoVBJxulM=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "050e09e091117c3d7328c7b2b7b577492c43c134",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

18
flake.nix Normal file
View File

@@ -0,0 +1,18 @@
{
description = "Kyle's Text Editor";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
};
outputs =
{ self, nixpkgs }:
let
pkgs = import nixpkgs { system = "x86_64-linux"; };
in
{
packages.x86_64-linux = {
default = pkgs.callPackage ./default.nix { };
};
};
}

66
ke.1
View File

@@ -19,30 +19,84 @@ is
K-command mode is entered using C-k. This is taken from Wordstar and just
so happens to be blessed with starting with a most excellent letter of
grandeur. Many commands work with and without control; for example,
saving a file can be done with either C-k s or C-k C-s.
.Pp
saving a file can be done with either C-k s or C-k C-s. Other commands work
with ESC or CTRL.
.Sh K-COMMANDS
k-command mode can be exited with ESC or C-g.
.Bl -tag -width xxxxxxxxxxxx -offset indent
.It C-k BACKSPACE
Delete from the cursor to the beginning of the line.
.It C-k SPACE
Toggle the mark.
.It C-k -
If the mark is set, unindent the region.
.It C-k =
If the mark is set, indent the region.
.It C-k c
Clear (flush) the kill ring.
.It C-k d
Delete from the cursor to the end of the line.
.It C-k C-d
Delete the entire line.
.It C-k e
Edit a new file. Also C-k C-e.
.It C-k f
Incremental find.
.It C-k g
Go to a specific line. Also C-k C-g.
Go to a specific line.
.It C-k j
Jump to the mark.
.It C-k l
List the number of lines of code in a saved file.
.It C-k m
Run make(1).
.It C-k q
exit the editor. Also C-k C-q.
Exit the editor. If the file has unsaved changes,
a warning will be printed; a second C-k q will exit.
.It C-k C-q
Immediately exit the editor.
.It C-k C-r
Reload the current buffer from disk.
.It C-k s
save the file, prompting for a filename if needed. Also C-k C-s.
Save the file, prompting for a filename if needed. Also C-k C-s.
.It C-k u
Undo changes.
.It C-k U
Redo changes.
.It C-k x
save the file and exit. Also C-k C-x.
.It C-k \
.It C-k y
Yank the kill ring.
.It C-k \[char92]
Dump core.
.El
.Sh OTHER KEYBINDINGS
.Bl -tag -width xxxxxxxxxxxx -offset indent
.It C-g
In general, C-g cancels an operation.
.It C-l
Refresh the display.
.It C-s
Incremental find.
.It C-u
Universal argument. C-u followed by numbers will repeat an
operation n times.
.It C-w
Kill the region if the mark is set.
.It C-y
Yank the kill ring.
.It ESC BACKSPACE
Delete the previous word.
.It ESC b
Move to the previous word.
.It ESC d
Delete the next word.
.It ESC f
Move to the next word.
.It ESC w
Save the region (if the mark is set) to the kill ring.
.It
.El
.Sh FIND
The find operation is an incremental search. The up or left arrow keys will
go to the previous result, while the down or right arrow keys will go to

2425
main.c

File diff suppressed because it is too large Load Diff

162
scratch.c Normal file
View File

@@ -0,0 +1,162 @@
/*
* scratch.c - ideas in progress
*/
#define REFLOW_MARGIN 72
void
reflow_region(void)
{
int start_row, end_row, i, col, wlen, this_len;
struct erow *row;
struct abuf buf = ABUF_INIT;
struct abuf out = ABUF_INIT;
int in_paragraph = 0;
int indent_len = 0;
char indent[REFLOW_MARGIN + 1];
char word[REFLOW_MARGIN + 1];
char *e = NULL;
char *p = NULL;
char *s = NULL;
if (editor.mark_set) {
if (editor.mark_cury < editor.cury ||
(editor.mark_cury == editor.cury &&
editor.mark_curx < editor.curx)) {
start_row = editor.mark_cury;
end_row = editor.cury;
} else {
start_row = editor.cury;
end_row = editor.mark_cury;
}
} else {
start_row = end_row = editor.cury;
while (start_row > 0 && editor.row[start_row - 1].size > 0) {
start_row--;
}
while (end_row < editor.nrows - 1 &&
editor.row[end_row + 1].size > 0) {
end_row++;
}
}
if (start_row >= editor.nrows) {
return;
}
if (end_row >= editor.nrows) {
end_row = editor.nrows - 1;
}
for (i = start_row; i <= end_row; i++) {
row = &editor.row[i];
if (row->size == 0) {
if (in_paragraph) {
ab_append(&buf, "\n", 1);
in_paragraph = 0;
}
ab_append(&buf, "\n", 1);
continue;
}
if (!in_paragraph) {
indent_len = 0;
while (indent_len < row->size &&
(row->line[indent_len] == ' ' ||
row->line[indent_len] == '\t')) {
indent[indent_len] = row->line[indent_len], indent_len++;
}
indent[indent_len] = '\0';
in_paragraph = 1;
}
ab_append(&buf, row->line + indent_len, row->size - indent_len);
ab_append(&buf, " ", 1);
}
if (in_paragraph) {
ab_append(&buf, "\n", 1);
}
p = buf.b;
col = 0;
while (p != NULL && *p != '\0') {
while (*p && isspace((unsigned char)*p) &&
*p != '\n') {
p++;
}
if (*p == '\0') {
break;
}
wlen = 0;
while (*p && !isspace((unsigned char)*p)) {
if (wlen < REFLOW_MARGIN)
word[wlen++] = *p;
p++;
}
word[wlen] = '\0';
if (*p == '\n' && (p[1] == '\n' || p[1] == '\0')) {
ab_append(&out, "\n", 1); /* flush */
col = 0;
p++; /* consume the extra \n */
continue;
}
this_len = wlen;
if (col > 0) {
this_len++; /* space before word */
}
if (col == 0) {
ab_append(&out, indent, indent_len);
col = indent_len;
}
if (col + this_len > REFLOW_MARGIN && col > 0) {
ab_append(&out, "\n", 1);
ab_append(&out, indent, indent_len);
col = indent_len;
}
if (col > 0) {
ab_append(&out, " ", 1);
col++;
}
ab_append(&out, word, wlen);
col += wlen;
}
if (col > 0) {
ab_append(&out, "\n", 1);
}
/* the old switcharoo */
buf = out;
ab_free(&out);
for (i = end_row; i >= start_row; i--) {
delete_row(i);
}
s = buf.b;
while ((e = strchr(s, '\n'))) {
erow_insert(start_row++, s, e - s);
s = e + 1;
}
ab_free(&buf);
editor.dirty++;
editor_set_status("Region reflowed to %d columns", REFLOW_MARGIN);
}

15
test.txt.bak Normal file
View File

@@ -0,0 +1,15 @@
hello
world it is me
but I am not me