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 locked; /* tracks current mode */
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 */
unsigned buf_undo(Buf* buf, unsigned pos);
unsigned buf_redo(Buf* buf, unsigned pos);
Rune buf_get(Buf* buf, unsigned pos);
-void buf_setlocked(Buf* buf, bool locked);
-bool buf_locked(Buf* buf);
bool buf_iseol(Buf* buf, unsigned pos);
unsigned buf_bol(Buf* buf, unsigned pos);
unsigned buf_eol(Buf* buf, unsigned pos);
enum {
- UTF_MAX = 6u, /* maximum number of bytes that make up a rune */
- RUNE_SELF = 0x80, /* byte values larger than this are *not* ascii */
- RUNE_ERR = 0xFFFD, /* rune value representing an error */
- RUNE_MAX = 0x10FFFF, /* Maximum decodable rune value */
- RUNE_EOF = UINT32_MAX, /* rune value representing end of file */
- RUNE_CRLF = UINT32_MAX-1, /* rune value representing a \r\n sequence */
+ UTF_MAX = 6u, /* maximum number of bytes that make up a rune */
+ RUNE_SELF = 0x80, /* byte values larger than this are *not* ascii */
+ RUNE_ERR = 0xFFFD, /* rune value representing an error */
+ RUNE_MAX = 0x10FFFF, /* Maximum decodable rune value */
+ RUNE_EOF = -1, /* rune value representing end of file */
+ RUNE_CRLF = -2, /* rune value representing a \r\n sequence */
};
/* Represents a unicode code point */
#include <edit.h>
void buf_load(Buf* buf, char* path) {
- buf_setlocked(buf, false);
if (!strcmp(path,"-")) {
buf->charset = UTF_8;
Rune r;
}
funmap(file);
}
- buf_setlocked(buf, true);
buf->modified = false;
+ free(buf->undo);
+ buf->undo = NULL;
}
void buf_save(Buf* buf) {
}
void buf_init(Buf* buf) {
- buf->locked = true;
buf->modified = false;
buf->charset = DEFAULT_CHARSET;
buf->crlf = DEFAULT_CRLF;
static void log_insert(Log** list, unsigned beg, unsigned end) {
Log* log = *list;
- if (!log || log->locked || !log->insert ||
- (log->data.ins.beg && beg < log->data.ins.beg-1) ||
- (end > log->data.ins.end+1)) {
+ if (!log || log->locked || !log->insert || (end != log->data.ins.end+1)) {
Log* newlog = (Log*)calloc(sizeof(Log), 1);
newlog->insert = true;
newlog->data.ins.beg = beg;
}
void buf_ins(Buf* buf, unsigned off, Rune rune) {
- if (buf->locked) { return; }
buf->modified = true;
log_insert(&(buf->undo), off, off+1);
insert(buf, off, rune);
}
void buf_del(Buf* buf, unsigned off) {
- if (buf->locked) { return; }
buf->modified = true;
Rune r = buf_get(buf, off);
log_delete(&(buf->undo), off, &r, 1);
return *(buf->gapend + (off - bsz));
}
-void buf_setlocked(Buf* buf, bool locked) {
- if (locked && buf->undo)
- buf->undo->locked = true;
- buf->locked = locked;
-}
-
-bool buf_locked(Buf* buf) {
- return buf->locked;
-}
-
bool buf_iseol(Buf* buf, unsigned off) {
Rune r = buf_get(buf, off);
return (r == '\n' || r == RUNE_CRLF);
}
unsigned buf_putstr(Buf* buf, unsigned beg, unsigned end, char* str) {
- bool locked = buf_locked(buf);
- buf_setlocked(buf, false);
/* delete the selected text first */
for (unsigned i = beg; ((end-beg) > 1) && (i <= end); i++)
buf_del(buf, beg);
while (!utf8decode(&rune, &length, *str++));
buf_ins(buf, beg++, rune);
}
- buf_setlocked(buf, locked);
return beg;
}
} else if (risword(r)) {
SelBeg = buf_bow(&Buffer, SelEnd);
SelEnd = buf_eow(&Buffer, SelEnd);
- if (!buf_locked(&Buffer)) SelEnd++;
+ SelEnd++;
} else if (r == '(' || r == ')') {
SelBeg = buf_lscan(&Buffer, SelEnd, '(');
SelEnd = buf_rscan(&Buffer, SelEnd, ')');
- if (!buf_locked(&Buffer)) SelEnd++;
+ SelEnd++;
} else if (r == '[' || r == ']') {
SelBeg = buf_lscan(&Buffer, SelEnd, '[');
SelEnd = buf_rscan(&Buffer, SelEnd, ']');
- if (!buf_locked(&Buffer)) SelEnd++;
+ SelEnd++;
} else if (r == '{' || r == '}') {
SelBeg = buf_lscan(&Buffer, SelEnd, '{');
SelEnd = buf_rscan(&Buffer, SelEnd, '}');
- if (!buf_locked(&Buffer)) SelEnd++;
+ SelEnd++;
} else {
bigword(mevnt);
}
TestBuf.crlf = 1;
for (Rune* curr = TestBuf.bufstart; curr < TestBuf.bufend; curr++)
*curr = '-';
- TestBuf.locked = false;
while (*str)
buf_ins(&TestBuf, i++, (Rune)*str++);
}
*************************************************************************/
/* Undo/Redo
*************************************************************************/
- /* Locking
- *************************************************************************/
- TEST(buf_setlocked should lock the buffer to prevent changes) {
- TestBuf.locked = false;
- if (TestBuf.undo) { free(TestBuf.undo); TestBuf.undo = NULL; }
- buf_setlocked(&TestBuf, true);
- CHECK(TestBuf.locked);
- }
-
- TEST(buf_setlocked should lock the buffer to prevent changes and lock the last undo op) {
- Log log;
- TestBuf.locked = false;
- TestBuf.undo = &log;
- buf_setlocked(&TestBuf, true);
- CHECK(TestBuf.locked);
- CHECK(TestBuf.undo->locked);
- }
-
- TEST(buf_setlocked should unlock the buffer) {
- Log log;
- TestBuf.locked = true;
- TestBuf.undo = &log;
- buf_setlocked(&TestBuf, false);
- CHECK(!TestBuf.locked);
- }
-
- TEST(buf_islocked should return true if locked) {
- TestBuf.locked = true;
- CHECK(buf_locked(&TestBuf));
- }
-
- TEST(buf_islocked should return false if locked) {
- TestBuf.locked = false;
- CHECK(!buf_locked(&TestBuf));
- }
-
/* Accessors
*************************************************************************/
// buf_get
buf_init(&Buffer);
if (argc > 1)
buf_load(&Buffer, argv[1]);
- buf_setlocked(&Buffer, false);
/* initialize the display engine */
x11_init(&Config);
x11_window("edit", Width, Height);
load_choices();
/* initialize the filter edit buffer */
buf_init(&Query);
- buf_setlocked(&Query, false);
/* initialize the display engine */
x11_init(&Config);
x11_dialog("pick", Width, Height);