From 3915c8ab68184795831f1f43d199c52bbe93e1fe Mon Sep 17 00:00:00 2001 From: sloumdrone Date: Wed, 1 Jan 2020 22:51:00 -0800 Subject: [PATCH] Got most of a paste buffer working --- LICENSE | 27 +++++++ hermes | Bin 38176 -> 42312 bytes hermes.1 | 6 +- hermes.c | 203 +++++++++++++++++++++++++++++------------------------ syntaxhl.h | 78 ++++++++++++++++++++ test.txt | 7 ++ 6 files changed, 228 insertions(+), 93 deletions(-) create mode 100644 LICENSE create mode 100644 syntaxhl.h create mode 100644 test.txt diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..2ff7cbe --- /dev/null +++ b/LICENSE @@ -0,0 +1,27 @@ +This software (c) 2020, Brian Evans +based on/extending "kilo" by Salvatore Sanfilippo: + +Copyright (c) 2016, Salvatore Sanfilippo + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/hermes b/hermes index c5ffdc50912b1fab4fe84af47e6dde08eb91aa8a..66c9355bb3ed18ff5878d09be6c0fe14945d1d4e 100755 GIT binary patch literal 42312 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%0AuV%iFWJR3DiRn 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 diff --git a/hermes.1 b/hermes.1 index cef2e3e..36af307 100644 --- a/hermes.1 +++ b/hermes.1 @@ -10,7 +10,7 @@ .SH DESCRIPTION \fBhermes\fP is a minimalist modal text editor with support for some vi-like key commands. \fBhermes\fP supports basic syntax highlighting and filetype detection. .SH USAGE -Most of the key bindings that follow are only available in command mode (the exceptions being any Ctrl based key combinations, the arrow keys, home,a nd end). In addition to the listed keys, while in command mode you may enter numbers that will modify the following action keys in some way. For example 10w would move the cursor forward 10 words. 10 would move the cursor to the 10th row of the file. The d key is also special, as it does not do anything on its own, but modifies a key that follows it. For example 10dw would delete the next ten words. +Most of the key bindings that follow are only available in command mode (the exceptions being any Ctrl based key combinations, the arrow keys, home, and end). In addition to the listed keys, while in command mode you may enter numbers that will modify the following action keys in some way. For example 10w would move the cursor forward 10 words. 10 would move the cursor to the 10th row of the file. The d key is also special, as it modifies a key that follows it. For example 10dw would delete the next ten words. .TP .B a @@ -46,11 +46,11 @@ Go from input mode to command mode. .TP .B g -Move cursor to the top left of the document. +Move cursor to the beginning of the document. .TP .B G -Move cursor to the bottom right of the document. +Move cursor to the end of the document. .TP .B h or left arrow diff --git a/hermes.c b/hermes.c index a49ced4..41af244 100644 --- a/hermes.c +++ b/hermes.c @@ -24,8 +24,6 @@ // ----------- #define HERMES_VERSION "0.5" #define CTRL_KEY(k) ((k) & 0x1f) -#define HL_HIGHLIGHT_NUMBERS (1<<0) -#define HL_HIGHLIGHT_STRINGS (1<<1) // // definitions for config file @@ -56,10 +54,13 @@ enum editorKey { END_KEY }; + // // data // ---- +#include "syntaxhl.h" + typedef struct erow { int idx; int size; @@ -79,7 +80,9 @@ struct editorConfig { int screenCols; int numRows; int unsaved; + int pastelen; erow *row; + char *paste; char *filename; char statusmsg[80]; time_t statusmsg_time; @@ -87,82 +90,10 @@ struct editorConfig { struct editorSyntax *syntax; }; -struct editorSyntax { - char *filetype; - char **filematch; - char *singleline_comment_start; - char *multiline_comment_start; - char *multiline_comment_end; - char **keywords; - int flags; -}; struct editorConfig E; -// -// filetypes -// --------- -char *C_HL_extensions[] = {".c", ".h", ".cpp", NULL}; -char *C_HL_keywords[] = { - "switch", "if", "while", "for", "break", "return", "else", "continue", - "struct|", "union", "typedef", "static", "enum|", "class", "case|", - "int|", "long|", "double|", "float|", "char|", "unsigned|", "signed|", - "void|", "NULL", NULL -}; - -char *PY_HL_extensions[] = {".py", ".pyc", NULL}; -char *PY_HL_keywords[] = { - "if", "elif", "for", "break", "return", "else", - "def", "", "static", "enum", "class", "with", "assert", - "except", "continue", "while", "finally", "try", "global", - "False|", "True|", "None|", "not|", "and|", "as|", "yield|", - "void|", "or|", "import|", "is|", "in|", "lambda|", "pass|", - "raise|", "del|", NULL -}; - -char *GO_HL_extensions[] = {".go", NULL}; -char *GO_HL_keywords[] = { - "break", "switch", "continue", "func", "interface", "select", - "case", "defer", "go", "map", "struct", "chan", "else", "goto", - "package", "const", "fallthrough|", "if", "range|", "type", - "for", "import", "return", "var", "uint8|", "uint16|", "uint32|", - "uint64", "int|", "uint|", "int8|", "int16|", "int32|", "int64|", - "float32|", "float", "float64|", "complex64|", "complex128|", - "byte|", "rune|", "uintptr|", "string|", "bool|", NULL -}; - -struct editorSyntax HLDB[] = { - { - "c", - C_HL_extensions, - "//", - "/*", - "*/", - C_HL_keywords, - HL_HIGHLIGHT_NUMBERS | HL_HIGHLIGHT_STRINGS - }, - { - "python", - PY_HL_extensions, - "#", - "'''", - "'''", - PY_HL_keywords, - HL_HIGHLIGHT_NUMBERS | HL_HIGHLIGHT_STRINGS - }, - { - "go", - GO_HL_extensions, - "//", - "/*", - "*/", - GO_HL_keywords, - HL_HIGHLIGHT_NUMBERS | HL_HIGHLIGHT_STRINGS - } -}; - -#define HLDB_ENTRIES (sizeof(HLDB) / sizeof(HLDB[0])) // // prototypes @@ -594,6 +525,12 @@ void editorInsertNewline() { E.cx = 0; } +void editorUpdatePaste(char *str, int len) { + E.paste = realloc(E.paste, len); + memcpy(E.paste, str, len); + E.pastelen = len; +} + // // file io // ------- @@ -1053,7 +990,7 @@ void editorInputKp(int c) { switch (c) { case '\033': case CTRL_KEY('l'): - if (E.cx == E.row[E.cy].size) editorMoveCursor(ARROW_LEFT); + editorMoveCursor(ARROW_LEFT); E.mode = CommandMode; break; case '\r': @@ -1087,18 +1024,66 @@ void editorCommandKp(int c) { } break; case 'g': - E.cy = 0; - E.cx = 0; + if (deleting) { + int totlen = 0; + int j; + for (j = 0; j <= E.cy; j++) + totlen += E.row[j].size + 1; + + char *buf = malloc(totlen); + char *p = buf; + + int count = E.cy; + E.cy = 0; + while (count >= 0) { + memcpy(p, E.row[E.cy].chars, E.row[E.cy].size); + p += E.row[E.cy].size; + *p = '\r'; + p++; + + deleting = 1; + editorCommandKp('d'); + count--; + } + editorUpdatePaste(buf, totlen); + } else { + E.cy = 0; + E.cx = 0; + } break; case 'G': - if (E.numRows > E.screenRows) { - E.cy = E.numRows - 1; - E.rowoff = E.numRows - E.screenRows - 1; + if (deleting) { + int totlen = 0; + int j; + for (j = E.cy; j <= E.numRows; j++) + totlen += E.row[j].size + 1; + + char *buf = malloc(totlen); + char *p = buf; + + int count = E.numRows - E.cy - 1; + if (count < 0) count = 0; + while (count >= 0) { + memcpy(p, E.row[E.cy].chars, E.row[E.cy].size); + p += E.row[E.cy].size; + *p = '\r'; + p++; + + deleting = 1; + editorCommandKp('d'); + count--; + } + editorUpdatePaste(buf, totlen); } else { - E.cy = E.numRows - 1; + if (E.numRows > E.screenRows) { + E.cy = E.numRows - 1; + E.rowoff = E.numRows - E.screenRows - 1; + } else { + E.cy = E.numRows - 1; + } + E.cx = E.row[E.cy].size - 1; + if (E.cx < 0) E.cx = 0; } - E.cx = E.row[E.cy].size - 1; - if (E.cx < 0) E.cx = 0; break; case '\r': if (counting) { @@ -1113,23 +1098,25 @@ void editorCommandKp(int c) { } break; case 'o': - editorCommandKp('$'); - editorCommandKp('i'); + deleting = 0; + E.cx = E.row[E.cy].size; + E.mode = InputMode; editorMoveCursor(ARROW_RIGHT); editorInsertNewline(); break; case 'O': - editorCommandKp('^'); + E.cx = 0; editorInsertNewline(); editorMoveCursor(ARROW_UP); - editorCommandKp('i'); + E.mode = InputMode; break; case 'x': while (counter > 0) { + editorUpdatePaste(&E.row[E.cy].chars[E.cx], 1); E.mode = InputMode; editorMoveCursor(ARROW_RIGHT); - E.mode = CommandMode; editorDeleteChar(); + E.mode = CommandMode; if (E.cx == E.row[E.cy].size) editorMoveCursor(ARROW_LEFT); counter--; } @@ -1144,6 +1131,12 @@ void editorCommandKp(int c) { deleting++; return; } else { + // TODO fix this. There are issues.... :( + char *buf = malloc(E.row[E.cy].size + 1); + int len = snprintf(buf, E.row[E.cy].size, "%s", E.row[E.cy].chars); + buf[len] = '\r'; + editorUpdatePaste(buf, len); + free(buf); while (counter > 0) { editorDelRow(E.cy); if (E.cy == E.numRows) E.cy--; @@ -1155,13 +1148,14 @@ void editorCommandKp(int c) { case '$': if (deleting) { int diff = E.row[E.cy].size - E.cx; + editorUpdatePaste(&E.row[E.cy].chars[E.cx], diff); E.cx = E.row[E.cy].size - 1; if (E.cx < 0) E.cx = 0; while (diff > 0) { E.mode = InputMode; editorMoveCursor(ARROW_RIGHT); - E.mode = CommandMode; editorDeleteChar(); + E.mode = CommandMode; if (E.cx == E.row[E.cy].size) editorMoveCursor(ARROW_LEFT); diff--; } @@ -1176,6 +1170,7 @@ void editorCommandKp(int c) { int start_x = E.cx; int start_y = E.cy; editorNextWord(); + editorUpdatePaste(&E.row[E.cy].chars[start_x], E.cx - start_x); while (E.cy != start_y || E.cx != start_x) { editorDeleteChar(); } @@ -1185,6 +1180,30 @@ void editorCommandKp(int c) { counter--; } break; + case 'P': + case 'p': + { + char open = c == 'p' ? 'o' : 'O'; + int startx = E.cx; + int multiline = 0; + if (E.paste && E.paste[E.pastelen-1] == '\r') multiline = 1; + if (multiline) { + editorCommandKp(open); + } else { + E.mode = InputMode; + if (open == 'o') editorMoveCursor(ARROW_RIGHT); + } + + for (int i = 0; i < E.pastelen; i++) { + editorInputKp(E.paste[i]); + } + if (multiline) { + editorInputKp(DEL_KEY); + E.cx = startx <= E.row[E.cy].size ? startx : E.row[E.cy].size; + } + E.mode = CommandMode; + break; + } case 'b': while (counter > 0) { if (deleting) { @@ -1195,6 +1214,7 @@ void editorCommandKp(int c) { int end_y = E.cy; E.cx = start_x; E.cy = start_y; + editorUpdatePaste(&E.row[E.cy].chars[end_x], start_x - end_x); while (E.cy != end_y || E.cx != end_x) { editorDeleteChar(); } @@ -1210,13 +1230,14 @@ void editorCommandKp(int c) { int start_x = E.cx; int start_y = E.cy; editorEndOfWord(); + editorUpdatePaste(&E.row[E.cy].chars[start_x], E.cx - start_x); while (E.cy != start_y || E.cx != start_x) { editorDeleteChar(); } E.mode = InputMode; editorMoveCursor(ARROW_RIGHT); - E.mode = CommandMode; editorDeleteChar(); + E.mode = CommandMode; if (E.cx == E.row[E.cy].size) editorMoveCursor(ARROW_LEFT); } else { editorEndOfWord(); @@ -1226,6 +1247,7 @@ void editorCommandKp(int c) { break; case '^': if (deleting) { + editorUpdatePaste(&E.row[E.cy].chars[0], E.cx); while (E.cx > 0) { editorDeleteChar(); } @@ -1327,6 +1349,7 @@ void initEditor() { E.cx = 0; E.cy = 0; E.rx = 0; + E.paste = NULL; E.row = NULL; E.filename = NULL; E.syntax = NULL; diff --git a/syntaxhl.h b/syntaxhl.h new file mode 100644 index 0000000..ebf61d6 --- /dev/null +++ b/syntaxhl.h @@ -0,0 +1,78 @@ +#include + +#define HL_HIGHLIGHT_NUMBERS (1<<0) +#define HL_HIGHLIGHT_STRINGS (1<<1) + +struct editorSyntax { + char *filetype; + char **filematch; + char *singleline_comment_start; + char *multiline_comment_start; + char *multiline_comment_end; + char **keywords; + int flags; +}; + +// +// filetypes +// --------- +char *C_HL_extensions[] = {".c", ".h", ".cpp", NULL}; +char *C_HL_keywords[] = { + "switch", "if", "while", "for", "break", "return", "else", "continue", + "struct|", "union", "typedef", "static", "enum|", "class", "case|", + "int|", "long|", "double|", "float|", "char|", "unsigned|", "signed|", + "void|", "NULL", NULL +}; + +char *PY_HL_extensions[] = {".py", ".pyc", NULL}; +char *PY_HL_keywords[] = { + "if", "elif", "for", "break", "return", "else", + "def", "", "static", "enum", "class", "with", "assert", + "except", "continue", "while", "finally", "try", "global", + "False|", "True|", "None|", "not|", "and|", "as|", "yield|", + "void|", "or|", "import|", "is|", "in|", "lambda|", "pass|", + "raise|", "del|", NULL +}; + +char *GO_HL_extensions[] = {".go", NULL}; +char *GO_HL_keywords[] = { + "break", "switch", "continue", "func", "interface", "select", + "case", "defer", "go", "map", "struct", "chan", "else", "goto", + "package", "const", "fallthrough|", "if", "range|", "type", + "for", "import", "return", "var", "uint8|", "uint16|", "uint32|", + "uint64", "int|", "uint|", "int8|", "int16|", "int32|", "int64|", + "float32|", "float", "float64|", "complex64|", "complex128|", + "byte|", "rune|", "uintptr|", "string|", "bool|", NULL +}; + +static struct editorSyntax HLDB[] = { + { + "c", + C_HL_extensions, + "//", + "/*", + "*/", + C_HL_keywords, + HL_HIGHLIGHT_NUMBERS | HL_HIGHLIGHT_STRINGS + }, + { + "python", + PY_HL_extensions, + "#", + "'''", + "'''", + PY_HL_keywords, + HL_HIGHLIGHT_NUMBERS | HL_HIGHLIGHT_STRINGS + }, + { + "go", + GO_HL_extensions, + "//", + "/*", + "*/", + GO_HL_keywords, + HL_HIGHLIGHT_NUMBERS | HL_HIGHLIGHT_STRINGS + } +}; + +#define HLDB_ENTRIES (sizeof(HLDB) / sizeof(HLDB[0])) diff --git a/test.txt b/test.txt new file mode 100644 index 0000000..1d59b38 --- /dev/null +++ b/test.txt @@ -0,0 +1,7 @@ +This is a test +to see if this +will work out +if I keep doing +this same thing +over and over +and over again.