# 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
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 */
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 {
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);
#include <stdc.h>
#include <utf.h>
#include <edit.h>
+#include <ctype.h>
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);
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;
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));
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;
}
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;
}
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;
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) {
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);
}
}
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;
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);
echo "Usage: $0 <dir>"
exit 1
fi
-find $1 -not -path '*/\.*' -type f | ./xpick
+find $1 -not -path '*/\.*' -type f | xpick
break;
default:
ChoiceIdx = 0;
- buf_ins(&Query, Pos++, key);
+ buf_ins(&Query, false, Pos++, key);
break;
}
score();