From: Michael D. Lowis Date: Wed, 11 Jan 2017 21:22:42 +0000 (-0500) Subject: tweaked escpae key handling for highlighting previous selection. Still not 100% corre... X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=5107ed527b284343e63d05013dc856d333f351eb;p=projs%2Ftide.git tweaked escpae key handling for highlighting previous selection. Still not 100% correct but it is better --- diff --git a/TODO.md b/TODO.md index 401162c..69d2bc5 100644 --- a/TODO.md +++ b/TODO.md @@ -10,29 +10,20 @@ Up Next: * check for file changes on save * check for file changes when window regains focus -The Rest: +The Rest: * add a distinct state for pointer move versus drag * Add a SaveAs tag that takes an argument for the filename to save as * Add a GoTo tag for ctags lookup and line number jump -* Add a tools dir to namespace utility scripts only useful inside the editor * implement command diffing logic to optimize the undo/redo log * add command line flags to toggle options (Tabs, Indent, etc..) * Add a ctrl+space shortcut to autocomplete ctag * off by one error on scrolling up with wrapped lines +* 100% coverage with unit and unit-integration tests +* shortcut to repeat previous operation # Auxillary Programs * Acme-like window manager * Win-like terminal emulator * File browser -* Webkit-based web browser - -# Graphical User Interface - -* Display line location and num lines in status - -# Maybe Someday Features - -* Implement fuse file-system backend? -* Spell checker integration diff --git a/config.mk b/config.mk index 85d96ed..d1c8dd3 100644 --- a/config.mk +++ b/config.mk @@ -7,6 +7,10 @@ PREFIX = $(HOME) CC = c99 CFLAGS = -g -O0 $(INCS) +#CC = gcc +#CFLAGS = --std=c99 -Wall -Wextra -Werror $(INCS) +#CFLAGS += -Wno-sign-compare -Wno-unused-variable -Wno-unused-parameter -Wno-missing-field-initializers + # Linker Setup LD = $(CC) LDFLAGS = $(LIBS) -lX11 -lXft -lfontconfig diff --git a/lib/buf.c b/lib/buf.c index 555f0a8..35d9929 100644 --- a/lib/buf.c +++ b/lib/buf.c @@ -174,7 +174,7 @@ void buf_init(Buf* buf) { /* cleanup old data if there is any */ if (buf->bufstart) free(buf->bufstart); buf_logclear(buf); - + /* reset the state to defaults */ buf->modified = false; buf->expand_tabs = true; @@ -198,13 +198,13 @@ unsigned buf_load(Buf* buf, char* path) { buf->path = stringdup(path); char* addr = strrchr(buf->path, ':'); if (addr) *addr = '\0', addr++; - + /* load the file and determine the character set */ FMap file = mmap_readonly(buf->path); filetype(buf, file); if (buf->charset > UTF_8) die("Unsupported character set"); - + /* read the file contents into the buffer */ for (size_t i = 0; i < file.len;) { Rune r; @@ -216,7 +216,7 @@ unsigned buf_load(Buf* buf, char* path) { } buf_insert(buf, false, buf_end(buf), r); } - + /* reset buffer state */ buf->modified = false; buf_logclear(buf); @@ -299,10 +299,10 @@ unsigned buf_delete(Buf* buf, unsigned beg, unsigned end) { unsigned buf_change(Buf* buf, unsigned beg, unsigned end) { /* delete the range first */ unsigned off = buf_delete(buf, beg, end); - /* now create a new insert item of length 0 witht he same transaction id as - the delete. This will cause subsequent inserts to be coalesced into the + /* now create a new insert item of length 0 witht he same transaction id as + the delete. This will cause subsequent inserts to be coalesced into the same transaction */ - Log* dellog = buf->undo; + Log* dellog = buf->undo; Log* inslog = (Log*)calloc(sizeof(Log), 1); inslog->transid = dellog->transid; inslog->insert = true; @@ -383,7 +383,7 @@ unsigned buf_rscan(Buf* buf, unsigned pos, Rune r) { void buf_getblock(Buf* buf, Rune first, Rune last, Sel* sel) { int balance = 0, dir; unsigned beg = sel->end, end = sel->end, off; - + /* figure out which end of the block we're starting at */ if (buf_get(buf, end) == first) dir = +1, balance++, beg = end++; @@ -391,23 +391,23 @@ void buf_getblock(Buf* buf, Rune first, Rune last, Sel* sel) { dir = -1, balance--, beg = end--; else return; - + /* scan for a blanced set of braces */ while (true) { if (buf_get(buf, end) == first) balance++; else if (buf_get(buf, end) == last) balance--; - + if (balance == 0 || end >= buf_end(buf) || end == 0) break; else end += dir; } - + /* bail if we failed to find a block */ if (balance != 0) return; - + /* update the passed in selection */ if (end > beg) beg++, end--; sel->beg = beg, sel->end = end; @@ -540,8 +540,27 @@ unsigned buf_setcol(Buf* buf, unsigned pos, unsigned col) { void buf_lastins(Buf* buf, size_t* beg, size_t* end) { Log* log = buf->undo; - if (log && log->insert) { - *beg = log->data.ins.beg; - *end = log->data.ins.end; + unsigned opbeg = *end, opend = *end; + if (log && log->insert) + opbeg = log->data.ins.end, opend = log->data.ins.end; + + unsigned delsize = 0; + //printf("start: %u-%u\n", opbeg, opend); + for (; log; log = log->next) { + if (log->insert) { + unsigned ibeg = log->data.ins.beg, + iend = log->data.ins.end - delsize; + //printf("ins: %u-%u\n", ibeg, iend); + if (iend < ibeg || ibeg > opbeg || iend < opbeg) break; + if (ibeg < opbeg && iend > opend) break; + opbeg = ibeg, delsize = 0; + } else { + //printf("del: %u-%u\n", log->data.del.off, log->data.del.off+log->data.del.len); + /* bail if the delete doesnt overlap */ + if(log->data.del.off != opbeg) break; + delsize = log->data.del.len; + } } + //printf("finish: %u-%u\n\n", opbeg, opend); + *beg = opbeg, *end = opend; } diff --git a/lib/view.c b/lib/view.c index b4ba8bc..ac4aab7 100644 --- a/lib/view.c +++ b/lib/view.c @@ -510,8 +510,9 @@ void view_append(View* view, char* str) { buf_insert(&(view->buffer), false, view->selection.end++, '\n'); view->selection.beg++; } + unsigned beg = view->selection.beg; view_putstr(view, str); - view_selprev(view); + view->selection.beg = beg; } char* view_getstr(View* view, Sel* range) { @@ -582,7 +583,7 @@ void view_indent(View* view, int dir) { view->selection.end = buf_eol(buf, view->selection.end); unsigned off = buf_bol(buf, view->selection.end); if (num_selected(view->selection) == 0) return; - + do { if (dir == RIGHT) { buf_insert(buf, true, off, '\t'); @@ -603,6 +604,6 @@ void view_indent(View* view, int dir) { } } off = buf_byline(buf, off, UP); - + } while (off && off >= view->selection.beg); } diff --git a/tests/xedit.c b/tests/xedit.c index 6e18753..d73bd82 100644 --- a/tests/xedit.c +++ b/tests/xedit.c @@ -99,7 +99,7 @@ TEST_SUITE(XeditTests) { CHECK(getsel(EDIT)->end == 1); CHECK('\n' == buf_get(getbuf(EDIT), 0)); } - + /* Key Handling - Cursor Movement - Basic *************************************************************************/ TEST(left should do nothing for empty buffer) { @@ -304,7 +304,7 @@ TEST_SUITE(XeditTests) { CHECK(getsel(EDIT)->beg == 2); CHECK(getsel(EDIT)->end == 2); } - + /* Key Handling - Unix Editing Shortcuts *************************************************************************/ TEST(ctrl+u should do nothing for empty buffer) { @@ -441,11 +441,11 @@ TEST_SUITE(XeditTests) { CHECK(getsel(EDIT)->end == 3); } - TEST(esc should select nothing if no previous insert) { + TEST(esc should select previously edited text) { setup_view(EDIT, "foob", CRLF, 4); send_keys(ModNone, KEY_BACKSPACE); send_keys(ModNone, KEY_ESCAPE); - CHECK(getsel(EDIT)->beg == 3); + CHECK(getsel(EDIT)->beg == 0); CHECK(getsel(EDIT)->end == 3); } @@ -716,7 +716,7 @@ TEST_SUITE(XeditTests) { CHECK(ExitCode == 0); CHECK(verify_text(TAGS, "File is modified. Repeat action twice in < 250ms to quit.")); } - + TEST(Save should save changes to disk with crlf line endings) { setup_view(TAGS, "", CRLF, 0); view_init(getview(EDIT), "docs/crlf.txt"); @@ -734,7 +734,7 @@ TEST_SUITE(XeditTests) { view_init(getview(EDIT), "docs/lf.txt"); CHECK(verify_text(EDIT, "this file\nuses\nunix\nline\nendings\n")); } - + TEST(Cut and Paste tags should move selection to new location) { setup_view(EDIT, "foo\nbar\nbaz\n", CRLF, 0); getview(EDIT)->selection = (Sel){ 0, 8, 0 }; @@ -839,7 +839,7 @@ TEST_SUITE(XeditTests) { send_keys(ModCtrl, 'f'); } #endif - + TEST(Tabs should set indent style to tabs) { setup_view(TAGS, "Tabs", CRLF, 0); getview(TAGS)->selection = (Sel){ 0, 4, 0 };