[qwaq] Implement word left and right

The word boundaries are currently vary simple, just transitions from
alnum_ (as it was in my old editor and in Borland's editors), but the
basic logic is working.
This commit is contained in:
Bill Currie 2021-06-11 10:14:07 +09:00
parent 75ce07a14c
commit 3cd0d68774
6 changed files with 126 additions and 22 deletions

View file

@ -162,7 +162,10 @@ prevWord (txtbuffer_t *buffer, unsigned ptr)
if (ptr > 0) {
while (ptr > 0) {
char c = getChar (buffer, ptr - 1);
if (!isword (c)) {
if (c == '\n') {
return ptr;
}
if (isword (c)) {
break;
}
ptr--;
@ -172,7 +175,7 @@ prevWord (txtbuffer_t *buffer, unsigned ptr)
if (c == '\n') {
return ptr;
}
if (isword (c)) {
if (!isword (c)) {
break;
}
ptr--;
@ -619,6 +622,17 @@ bi_i_EditBuffer__prevNonSpace_ (progs_t *pr)
R_INT (pr) = prevNonSpace (buffer->txtbuffer, ptr);
}
static void
bi_i_EditBuffer__isWord_ (progs_t *pr)
{
qwaq_ebresources_t *res = PR_Resources_Find (pr, "qwaq-editbuffer");
int buffer_id = P_STRUCT (pr, qwaq_editbuffer_t, 0).buffer;
editbuffer_t *buffer = get_editbuffer (res, __FUNCTION__, buffer_id);
unsigned ptr = P_UINT (pr, 2);
R_INT (pr) = isword (getChar (buffer->txtbuffer, ptr));
}
static void
bi_i_EditBuffer__nextWord_ (progs_t *pr)
{
@ -968,6 +982,7 @@ static builtin_t builtins[] = {
{"_i_EditBuffer__prevChar_", bi_i_EditBuffer__prevChar_, -1},
{"_i_EditBuffer__nextNonSpace_", bi_i_EditBuffer__nextNonSpace_, -1},
{"_i_EditBuffer__prevNonSpace_", bi_i_EditBuffer__prevNonSpace_, -1},
{"_i_EditBuffer__isWord_", bi_i_EditBuffer__isWord_, -1},
{"_i_EditBuffer__nextWord_", bi_i_EditBuffer__nextWord_, -1},
{"_i_EditBuffer__prevWord_", bi_i_EditBuffer__prevWord_, -1},
{"_i_EditBuffer__nextLine_", bi_i_EditBuffer__nextLine_, -1},

View file

@ -34,6 +34,7 @@ typedef struct eb_color_s {
- (unsigned) prevChar: (unsigned) charPtr;
- (unsigned) nextNonSpace: (unsigned) charPtr;
- (unsigned) prevNonSpace: (unsigned) charPtr;
- (int) isWord: (unsigned) charPtr;
- (unsigned) nextWord: (unsigned) wordPtr;
- (unsigned) prevWord: (unsigned) wordPtr;
- (unsigned) nextLine: (unsigned) linePtr;

View file

@ -18,6 +18,7 @@
- (unsigned) prevChar: (unsigned) charPtr = #0;
- (unsigned) nextNonSpace: (unsigned) charPtr = #0;
- (unsigned) prevNonSpace: (unsigned) charPtr = #0;
- (int) isWord: (unsigned) charPtr = #0;
- (unsigned) nextWord: (unsigned) wordPtr = #0;
- (unsigned) prevWord: (unsigned) wordPtr = #0;
- (unsigned) nextLine: (unsigned) linePtr = #0;

View file

@ -47,6 +47,8 @@
-charDown;
-charLeft;
-charRight;
-wordLeft;
-wordRight;
-moveBOL;
-moveEOL;

View file

@ -7,6 +7,23 @@
@implementation Editor
static int
center (unsigned v, int len)
{
return v > len / 2 ? v / 2 : 0;
}
static void
trackCursor (Editor *self)
{
unsigned cx = [self.buffer charPos:self.line_index at:self.char_index];
if (self.cursor.x != cx) {
if (self.char_index < [self.buffer getEOT]) {
int c = [self.buffer getChar:self.char_index];
}
}
}
-initWithRect:(Rect) rect file:(string) filename path:(string) filepath
{
if (!(self = [super initWithRect: rect])) {
@ -168,10 +185,18 @@ handleEvent (Editor *self, qwaq_event_t *event)
[self charDown];
return 1;
case QFK_LEFT:
[self charLeft];
if (event.key.shift & qe_control) {
[self wordLeft];
} else {
[self charLeft];
}
return 1;
case QFK_RIGHT:
[self charRight];
if (event.key.shift & qe_control) {
[self wordRight];
} else {
[self charRight];
}
return 1;
case QFK_HOME:
[self moveBOL];
@ -376,6 +401,78 @@ handleEvent (Editor *self, qwaq_event_t *event)
return self;
}
-wordLeft
{
[self recenter:0];
//unsigned oc = char_index;
Point b = base;
do {
if (char_index && char_index == line_index) {
line_index = [buffer prevLine: line_index];
char_index = [buffer getEOL: line_index];
if (--cursor.y < b.y) {
b.y = cursor.y;
}
}
char_index = [buffer prevWord:char_index];
} while (char_index && char_index < [buffer getEOT]
&& ![buffer isWord:char_index]);
cursor.x = [buffer charPos:line_index at:char_index];
if (cursor.x < b.x) {
b.x = cursor.x;
} else if (cursor.x >= b.x) {
b.x = center (b.x, xlen);
}
base.x = b.x;
[vScrollBar setIndex:b.y];
trackCursor (self);
[self moveCursor: {cursor.x - base.x, cursor.y - base.y}];
return self;
}
-wordRight
{
[self recenter:0];
//unsigned oc = char_index;
Point b = base;
if (char_index >= [buffer getEOT]) {
return self;
}
if ([buffer getChar:char_index] == '\n') {
while ([buffer getChar:char_index] == '\n') {
char_index = line_index = [buffer nextLine:line_index];
if (++cursor.y >= b.y + ylen) {
b.y = cursor.y + 1 - ylen;
}
if (char_index >= [buffer getEOT]) {
break;
}
if (![buffer isWord:char_index]) {
char_index = [buffer nextWord: char_index];
}
}
} else {
char_index = [buffer nextWord: char_index];
}
cursor.x = [buffer charPos:line_index at:char_index];
if (cursor.x < b.x) {
b.x = cursor.x;
} else if (cursor.x >= b.x) {
b.x = center (b.x, xlen);
}
base.x = b.x;
[vScrollBar setIndex:b.y];
trackCursor (self);
[self moveCursor: {cursor.x - base.x, cursor.y - base.y}];
return self;
}
-moveBOL
{
char_index = line_index;
@ -414,28 +511,11 @@ handleEvent (Editor *self, qwaq_event_t *event)
-recenter:(int) force
{
if (force || cursor.y < base.y || cursor.y - base.y >= ylen) {
unsigned target;
if (cursor.y < ylen / 2) {
target = 0;
} else {
target = cursor.y - ylen / 2;
}
[self scrollTo:target];
[self scrollTo: center (cursor.y, ylen)];
}
return self;
}
static void
trackCursor (Editor *self)
{
unsigned cx = [self.buffer charPos:self.line_index at:self.char_index];
if (self.cursor.x != cx) {
if (self.char_index < [self.buffer getEOT]) {
int c = [self.buffer getChar:self.char_index];
}
}
}
-gotoLine:(unsigned) line
{
if (line > cursor.y) {

View file

@ -13,6 +13,11 @@ typedef enum {
qe_keydown = 0x0020,
} qwaq_key_event;
typedef enum {
qe_shift = 1,
qe_control = 4,
} qwaq_key_shift;
typedef enum {
qe_command = 0x0200, // application level command
qe_broadcast = 0x0400,