From 6499322ebac740a35968bc4252d30e96ec887e76 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Fri, 2 Dec 2016 12:10:33 -0500 Subject: [PATCH] Implemented copyindent and fixed right-click find bug. Also fixed a path issue in xfilepick --- TODO.md | 2 +- inc/edit.h | 5 +++-- libedit/buf.c | 23 ++++++++++++++++++----- libedit/charset.c | 2 +- libedit/utf8.c | 2 +- libedit/view.c | 4 ++-- xfilepick | 2 +- xpick.c | 2 +- 8 files changed, 28 insertions(+), 14 deletions(-) diff --git a/TODO.md b/TODO.md index 89d3c46..0f82b23 100644 --- a/TODO.md +++ b/TODO.md @@ -1,6 +1,6 @@ # Implementation Tweaks and Bug Fixes -* Auto indent mode +* Use select to check for error strings in exec.c * Should not be able to undo initial tag line text insertion * Disallow scrolling past end of buffer * track down double click bug for selecting whole line diff --git a/inc/edit.h b/inc/edit.h index d71a61d..7177c62 100644 --- a/inc/edit.h +++ b/inc/edit.h @@ -37,7 +37,6 @@ typedef struct buf { char* path; /* the path to the open file */ int charset; /* the character set of the buffer */ int crlf; /* tracks whether the file uses dos style line endings */ - bool modified; /* tracks whether the buffer has been modified */ size_t bufsize; /* size of the buffer in runes */ Rune* bufstart; /* start of the data buffer */ Rune* bufend; /* end of the data buffer */ @@ -45,7 +44,9 @@ typedef struct buf { Rune* gapend; /* end of the gap */ Log* undo; /* undo list */ Log* redo; /* redo list */ + bool modified; /* tracks whether the buffer has been modified */ bool expand_tabs; /* tracks current mode */ + bool copy_indent; /* copy the indent level from the previous line on new lines */ } Buf; typedef struct { @@ -57,7 +58,7 @@ typedef struct { void buf_load(Buf* buf, char* path); void buf_save(Buf* buf); void buf_init(Buf* buf); -unsigned buf_ins(Buf* buf, unsigned pos, Rune); +unsigned buf_ins(Buf* buf, bool indent, unsigned off, Rune rune); void buf_del(Buf* buf, unsigned pos); unsigned buf_undo(Buf* buf, unsigned pos); unsigned buf_redo(Buf* buf, unsigned pos); diff --git a/libedit/buf.c b/libedit/buf.c index e4179cb..3a8573c 100644 --- a/libedit/buf.c +++ b/libedit/buf.c @@ -1,13 +1,14 @@ #include #include #include +#include void buf_load(Buf* buf, char* path) { if (!strcmp(path,"-")) { buf->charset = UTF_8; Rune r; while (RUNE_EOF != (r = fgetrune(stdin))) - buf_ins(buf, buf_end(buf), r); + buf_ins(buf, false, buf_end(buf), r); } else { FMap file = fmap(path); buf->path = stringdup(path); @@ -76,6 +77,7 @@ static void syncgap(Buf* buf, unsigned off) { void buf_init(Buf* buf) { buf->modified = false; buf->expand_tabs = true; + buf->copy_indent = true; buf->charset = DEFAULT_CHARSET; buf->crlf = DEFAULT_CRLF; buf->bufsize = BufSize; @@ -152,7 +154,13 @@ static void clear_redo(Buf* buf) { buf->redo = NULL; } -unsigned buf_ins(Buf* buf, unsigned off, Rune rune) { +static unsigned getindent(Buf* buf, unsigned off) { + off = buf_bol(buf, off); + for (; off < buf_end(buf) && isspace(buf_get(buf, off)); off++); + return buf_getcol(buf, off) / TabWidth; +} + +unsigned buf_ins(Buf* buf, bool indent, unsigned off, Rune rune) { buf->modified = true; if (buf->expand_tabs && rune == '\t') { size_t n = (TabWidth - ((off - buf_bol(buf, off)) % TabWidth)); @@ -162,6 +170,11 @@ unsigned buf_ins(Buf* buf, unsigned off, Rune rune) { log_insert(&(buf->undo), off, off+1); insert(buf, off++, rune); } + if (indent && buf->copy_indent && (rune == '\n' || rune == RUNE_CRLF)) { + unsigned indent = getindent(buf, off-1); + for (; indent > 0; indent--) + off = buf_ins(buf, indent, off, '\t'); + } clear_redo(buf); return off; } @@ -270,7 +283,7 @@ unsigned buf_rscan(Buf* buf, unsigned pos, Rune r) { static int range_match(Buf* buf, unsigned dbeg, unsigned dend, unsigned mbeg, unsigned mend) { unsigned n1 = dend-dbeg, n2 = mend-mbeg; if (n1 != n2) return n1-n2; - for (; n1; n1--, dbeg++, mbeg++) { + for (; n1 > 0; n1--, dbeg++, mbeg++) { int cmp = buf_get(buf, dbeg) - buf_get(buf, mbeg); if (cmp != 0) return cmp; } @@ -281,8 +294,8 @@ void buf_find(Buf* buf, size_t* beg, size_t* end) { unsigned dbeg = *beg, dend = *end; unsigned mbeg = dend+1, mend = mbeg + (dend-dbeg); while (mend != dbeg) { - if ((buf_get(buf, mbeg) == buf_get(buf, dbeg)) && - (buf_get(buf, mend) == buf_get(buf, dend)) && + if ((buf_get(buf, mbeg) == buf_get(buf, dbeg)) && + (buf_get(buf, mend-1) == buf_get(buf, dend-1)) && (0 == range_match(buf,dbeg,dend,mbeg,mend))) { *beg = mbeg; diff --git a/libedit/charset.c b/libedit/charset.c index 336e317..87f9b06 100644 --- a/libedit/charset.c +++ b/libedit/charset.c @@ -49,7 +49,7 @@ int charset(const uint8_t* buf, size_t len, int* crlf) { void binload(Buf* buf, FMap file) { for (size_t i = 0; i < file.len; i++) - buf_ins(buf, buf_end(buf), file.buf[i]); + buf_ins(buf, false, buf_end(buf), file.buf[i]); } void binsave(Buf* buf, FILE* file) { diff --git a/libedit/utf8.c b/libedit/utf8.c index 78325dc..986505e 100644 --- a/libedit/utf8.c +++ b/libedit/utf8.c @@ -91,7 +91,7 @@ void utf8load(Buf* buf, FMap file) { Rune r = 0; size_t len = 0; while (!utf8decode(&r, &len, file.buf[i++])); - buf_ins(buf, buf_end(buf), r); + buf_ins(buf, false, buf_end(buf), r); } } diff --git a/libedit/view.c b/libedit/view.c index 8908f8e..1f45d43 100644 --- a/libedit/view.c +++ b/libedit/view.c @@ -372,7 +372,7 @@ void view_insert(View* view, Rune rune) { return; if (num_selected(view->selection)) view_delete(view, RIGHT, false); - view->selection.end = buf_ins(&(view->buffer), view->selection.end, rune); + view->selection.end = buf_ins(&(view->buffer), true, view->selection.end, rune); view->selection.beg = view->selection.end; view->selection.col = buf_getcol(&(view->buffer), view->selection.end); view->sync_needed = true; @@ -457,7 +457,7 @@ void view_append(View* view, char* str) { if (view->selection.end != end) view->selection = (Sel){ .beg = end, .end = end }; if (!num_selected(view->selection) && !buf_iseol(&(view->buffer), view->selection.end-1)) { - buf_ins(&(view->buffer), view->selection.end++, '\n'); + buf_ins(&(view->buffer), false, view->selection.end++, '\n'); view->selection.beg++; } view_putstr(view, str); diff --git a/xfilepick b/xfilepick index 9467b55..503b9e0 100755 --- a/xfilepick +++ b/xfilepick @@ -3,4 +3,4 @@ if [ "$#" -ne 1 ]; then echo "Usage: $0 " exit 1 fi -find $1 -not -path '*/\.*' -type f | ./xpick +find $1 -not -path '*/\.*' -type f | xpick diff --git a/xpick.c b/xpick.c index 30980ab..1008c5d 100644 --- a/xpick.c +++ b/xpick.c @@ -187,7 +187,7 @@ static void keyboard_input(int mods, uint32_t key) { break; default: ChoiceIdx = 0; - buf_ins(&Query, Pos++, key); + buf_ins(&Query, false, Pos++, key); break; } score(); -- 2.52.0