Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 542b1d90a0 | |||
| a359f4e6c4 | |||
| a03dd0c433 | |||
| 561faf537c | |||
| 3a36b35c1f | |||
|
|
b1cb2532f6 | ||
| 9f33cdc0e4 | |||
| afcc33329f |
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.15)
|
|||||||
project(ke C) # Specify C language explicitly
|
project(ke C) # Specify C language explicitly
|
||||||
|
|
||||||
set(CMAKE_C_STANDARD 99)
|
set(CMAKE_C_STANDARD 99)
|
||||||
set(KE_VERSION "1.3.0")
|
set(KE_VERSION "1.3.3")
|
||||||
|
|
||||||
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")
|
||||||
|
|||||||
3
Makefile
3
Makefile
@@ -3,8 +3,9 @@ KE_VERSION := devel
|
|||||||
DEST := $(HOME)/.local/bin/$(TARGET)
|
DEST := $(HOME)/.local/bin/$(TARGET)
|
||||||
|
|
||||||
CFLAGS := -Wall -Wextra -pedantic -Wshadow -Werror -std=c99 -g
|
CFLAGS := -Wall -Wextra -pedantic -Wshadow -Werror -std=c99 -g
|
||||||
|
CFLAGS += -Wno-unused-result
|
||||||
CFLAGS += -D_DEFAULT_SOURCE -D_XOPEN_SOURCE
|
CFLAGS += -D_DEFAULT_SOURCE -D_XOPEN_SOURCE
|
||||||
CFLAGS += -fsanitize=address -fno-omit-frame-pointer
|
CFLAGS += -fsanitize=address -fno-omit-frame-pointer
|
||||||
|
|
||||||
LDFLAGS := -fsanitize=address
|
LDFLAGS := -fsanitize=address
|
||||||
|
|
||||||
|
|||||||
27
default.nix
Normal file
27
default.nix
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
installShellFiles,
|
||||||
|
stdenv,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
pname = "ke";
|
||||||
|
version = "1.3.3";
|
||||||
|
|
||||||
|
src = lib.cleanSource ./.;
|
||||||
|
|
||||||
|
nativeBuildInputs = [ installShellFiles ];
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
runHook preInstall
|
||||||
|
|
||||||
|
mkdir -p $out/bin
|
||||||
|
cp ke $out/bin/
|
||||||
|
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
|
||||||
|
postInstall = ''
|
||||||
|
installManPage ke.1
|
||||||
|
'';
|
||||||
|
}
|
||||||
27
flake.lock
generated
Normal file
27
flake.lock
generated
Normal 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
18
flake.nix
Normal 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 { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
33
ke.1
33
ke.1
@@ -19,21 +19,26 @@ is
|
|||||||
K-command mode is entered using C-k. This is taken from Wordstar and just
|
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
|
so happens to be blessed with starting with a most excellent letter of
|
||||||
grandeur. Many commands work with and without control; for example,
|
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.
|
saving a file can be done with either C-k s or C-k C-s. Other commands work
|
||||||
.Pp
|
with ESC or CTRL.
|
||||||
|
.Sh K-COMMANDS
|
||||||
.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 SPACE
|
||||||
|
Toggle the mark.
|
||||||
.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 C-d
|
.It C-k C-d
|
||||||
Delete the entire link.
|
Delete the entire line.
|
||||||
.It C-k e
|
.It C-k e
|
||||||
Edit a new file. Also C-k C-e.
|
Edit a new file. Also C-k C-e.
|
||||||
.It C-k f
|
.It C-k f
|
||||||
Incremental find.
|
Incremental find.
|
||||||
.It C-k g
|
.It C-k g
|
||||||
Go to a specific line. Also C-k C-g.
|
Go to a specific line. Also C-k C-g.
|
||||||
|
.It C-k l
|
||||||
|
List the number of lines of code in a saved file.
|
||||||
.It C-k m
|
.It C-k m
|
||||||
Run make(1).
|
Run make(1).
|
||||||
.It C-k q
|
.It C-k q
|
||||||
@@ -47,6 +52,28 @@ Yank the killring.
|
|||||||
.It C-k \[char92]
|
.It C-k \[char92]
|
||||||
Dump core.
|
Dump core.
|
||||||
.El
|
.El
|
||||||
|
.Sh OTHER KEYBINDINGS
|
||||||
|
.Bl -tag -width xxxxxxxxxxxx -offset indent
|
||||||
|
.It C-l
|
||||||
|
Refresh the display.
|
||||||
|
.It C-s
|
||||||
|
Incremental find.
|
||||||
|
.It C-w
|
||||||
|
Kill the region if the mark is set.
|
||||||
|
.It C-y
|
||||||
|
Yank the killring.
|
||||||
|
.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 killring.
|
||||||
|
.It
|
||||||
|
.El
|
||||||
.Sh FIND
|
.Sh FIND
|
||||||
The find operation is an incremental search. The up or left arrow keys will
|
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
|
go to the previous result, while the down or right arrow keys will go to
|
||||||
|
|||||||
90
main.c
90
main.c
@@ -24,6 +24,7 @@
|
|||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
|
||||||
#ifndef KE_VERSION
|
#ifndef KE_VERSION
|
||||||
@@ -480,7 +481,7 @@ erow_init(struct erow *row, int len)
|
|||||||
row->rsize = 0;
|
row->rsize = 0;
|
||||||
row->render = NULL;
|
row->render = NULL;
|
||||||
row->line = NULL;
|
row->line = NULL;
|
||||||
row->cap = cap_growth(0, len);
|
row->cap = cap_growth(0, len)+1; /* extra byte for NUL end */
|
||||||
|
|
||||||
row->line = malloc(row->cap);
|
row->line = malloc(row->cap);
|
||||||
assert(row->line != NULL);
|
assert(row->line != NULL);
|
||||||
@@ -818,14 +819,17 @@ delete_region(void)
|
|||||||
deletech(KILLRING_NO_OP);
|
deletech(KILLRING_NO_OP);
|
||||||
killed++;
|
killed++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
editor.kill = 1;
|
||||||
|
editor_set_status("Region killed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
die(const char *s)
|
die(const char *s)
|
||||||
{
|
{
|
||||||
write(STDOUT_FILENO, "\x1b[2J", 4);
|
(void)write(STDOUT_FILENO, "\x1b[2J", 4);
|
||||||
write(STDOUT_FILENO, "\x1b[H", 3);
|
(void)write(STDOUT_FILENO, "\x1b[H", 3);
|
||||||
|
|
||||||
perror(s);
|
perror(s);
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -1708,9 +1712,77 @@ newline(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *
|
||||||
|
get_cloc_code_lines(const char* filename)
|
||||||
|
{
|
||||||
|
char command[512];
|
||||||
|
char buffer[256];
|
||||||
|
char *result = NULL;
|
||||||
|
FILE *pipe = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
if (editor.filename == NULL) {
|
||||||
|
snprintf(command, sizeof(command),
|
||||||
|
"buffer has no associated file.");
|
||||||
|
result = malloc((strnlen(command, sizeof(command))) + 1);
|
||||||
|
assert(result != NULL);
|
||||||
|
strcpy(result, command);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (editor.dirty) {
|
||||||
|
snprintf(command, sizeof(command),
|
||||||
|
"buffer must be saved first.");
|
||||||
|
result = malloc((strnlen(command, sizeof(command))) + 1);
|
||||||
|
assert(result != NULL);
|
||||||
|
strcpy(result, command);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(command,
|
||||||
|
sizeof(command),
|
||||||
|
"cloc --quiet %s | tail -2 | head -1 | awk '{print $5}'",
|
||||||
|
filename);
|
||||||
|
|
||||||
|
pipe = popen(command, "r");
|
||||||
|
if (!pipe) {
|
||||||
|
snprintf(command, sizeof(command), "Error getting LOC: %s", strerror(errno));
|
||||||
|
result = (char *)malloc(sizeof(buffer) + 1);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fgets(buffer, sizeof(buffer), pipe) != NULL) {
|
||||||
|
// Remove trailing newline
|
||||||
|
len = strlen(buffer);
|
||||||
|
if (len > 0 && buffer[len - 1] == '\n') {
|
||||||
|
buffer[len - 1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate and copy the string
|
||||||
|
result = malloc(strlen(buffer) + 1);
|
||||||
|
assert(result != NULL);
|
||||||
|
if (result) {
|
||||||
|
strcpy(result, buffer);
|
||||||
|
pclose(pipe);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pclose(pipe);
|
||||||
|
char *zero = malloc(2);
|
||||||
|
if (zero) {
|
||||||
|
strcpy(zero, "0");
|
||||||
|
return zero;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
process_kcommand(int16_t c)
|
process_kcommand(int16_t c)
|
||||||
{
|
{
|
||||||
|
char *buf = NULL;
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case ' ':
|
case ' ':
|
||||||
toggle_markset();
|
toggle_markset();
|
||||||
@@ -1773,6 +1845,12 @@ process_kcommand(int16_t c)
|
|||||||
case 'f':
|
case 'f':
|
||||||
editor_find();
|
editor_find();
|
||||||
break;
|
break;
|
||||||
|
case 'l':
|
||||||
|
buf = get_cloc_code_lines(editor.filename);
|
||||||
|
|
||||||
|
editor_set_status("Lines of code: %s", buf);
|
||||||
|
free(buf);
|
||||||
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
if (system("make") != 0) {
|
if (system("make") != 0) {
|
||||||
editor_set_status(
|
editor_set_status(
|
||||||
@@ -1976,8 +2054,8 @@ void
|
|||||||
display_clear(struct abuf *ab)
|
display_clear(struct abuf *ab)
|
||||||
{
|
{
|
||||||
if (ab == NULL) {
|
if (ab == NULL) {
|
||||||
write(STDOUT_FILENO, ESCSEQ "2J", 4);
|
(void)write(STDOUT_FILENO, ESCSEQ "2J", 4);
|
||||||
write(STDOUT_FILENO, ESCSEQ "H", 3);
|
(void)write(STDOUT_FILENO, ESCSEQ "H", 3);
|
||||||
} else {
|
} else {
|
||||||
ab_append(ab, ESCSEQ "2J", 4);
|
ab_append(ab, ESCSEQ "2J", 4);
|
||||||
ab_append(ab, ESCSEQ "H", 3);
|
ab_append(ab, ESCSEQ "H", 3);
|
||||||
@@ -2191,7 +2269,7 @@ display_refresh(void)
|
|||||||
/* ab_append(&ab, ESCSEQ "1;2H", 7); */
|
/* ab_append(&ab, ESCSEQ "1;2H", 7); */
|
||||||
ab_append(&ab, ESCSEQ "?25h", 6);
|
ab_append(&ab, ESCSEQ "?25h", 6);
|
||||||
|
|
||||||
write(STDOUT_FILENO, ab.b, ab.len);
|
(void)write(STDOUT_FILENO, ab.b, ab.len);
|
||||||
ab_free(&ab);
|
ab_free(&ab);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user