* block selection should handle brace-balancing
* context sensitive selection of words, commands, line numbers, or filenames.
* ctrl+alt+f should find next occurence of previous search term
-* shift should change direction of search for ctrl+f and right mouse button
* check for file changes on save
* check for file changes when window regains focus
unsigned buf_byword(Buf* buf, unsigned pos, int count);
unsigned buf_byline(Buf* buf, unsigned pos, int count);
-void buf_find(Buf* buf, size_t* beg, size_t* end);
-void buf_findstr(Buf* buf, char* str, size_t* beg, size_t* end);
+void buf_find(Buf* buf, int dir, size_t* beg, size_t* end);
+void buf_findstr(Buf* buf, int dir, char* str, size_t* beg, size_t* end);
unsigned buf_setln(Buf* buf, unsigned line);
unsigned buf_getcol(Buf* buf, unsigned pos);
void view_byline(View* view, int move, bool extsel);
char* view_fetch(View* view, size_t row, size_t col);
-void view_find(View* view, size_t row, size_t col);
-void view_findstr(View* view, char* str);
+void view_find(View* view, int dir, size_t row, size_t col);
+void view_findstr(View* view, int dir, char* str);
void view_insert(View* view, bool indent, Rune rune);
void view_delete(View* view, int dir, bool byword);
void view_bol(View* view, bool extsel);
/*****************************************************************************/
-void buf_find(Buf* buf, size_t* beg, size_t* end) {
+int dir = +1;
+
+void buf_find(Buf* buf, int dir, size_t* beg, size_t* end) {
unsigned dbeg = *beg, dend = *end;
- unsigned mbeg = dbeg+1, mend = dend+1;
+ unsigned mbeg = dbeg+dir, mend = dend+dir;
+ unsigned mlen = dend - dbeg;
while (true) {
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)))
+ (0 == range_match(buf, dbeg, dend, mbeg, mend)))
{
*beg = mbeg;
*end = mend;
break;
}
- mbeg++, mend++;
- if (mend > buf_end(buf)) {
- unsigned n = mend-mbeg;
- mbeg = 0, mend = n;
- }
+ mbeg += dir, mend += dir;
+ if (mend > buf_end(buf))
+ mbeg = (dir < 0 ? buf_end(buf)-mlen : 0), mend = mbeg+mlen;
}
}
-void buf_findstr(Buf* buf, char* str, size_t* beg, size_t* end) {
+void buf_findstr(Buf* buf, int dir, char* str, size_t* beg, size_t* end) {
if (!str) return;
Rune* runes = charstorunes(str);
size_t rlen = rstrlen(runes);
- unsigned start = *beg, mbeg = start+1, mend = mbeg + rlen;
+ unsigned start = *beg, mbeg = start+dir, mend = mbeg + rlen;
while (mbeg != start) {
if ((buf_get(buf, mbeg) == runes[0]) &&
(buf_get(buf, mend-1) == runes[rlen-1]) &&
*end = mend;
break;
}
- mbeg++, mend++;
+ mbeg += dir, mend += dir;
if (mend > buf_end(buf))
- mbeg = 0, mend = rlen;
+ mbeg = (dir < 0 ? buf_end(buf)-rlen : 0), mend = mbeg+rlen;
}
free(runes);
}
return str;
}
-void view_find(View* view, size_t row, size_t col) {
+void view_find(View* view, int dir, size_t row, size_t col) {
size_t off = getoffset(view, row, col);
if (off != SIZE_MAX) {
Sel sel = view->selection;
view_setcursor(view, row, col);
sel = view->selection;
selcontext(view, &sel);
- buf_find(&(view->buffer), &sel.beg, &sel.end);
+ buf_find(&(view->buffer), dir, &sel.beg, &sel.end);
sel.end++;
} else {
- buf_find(&(view->buffer), &sel.beg, &sel.end);
+ buf_find(&(view->buffer), dir, &sel.beg, &sel.end);
}
view->selection = sel;
view->sync_needed = true;
}
}
-void view_findstr(View* view, char* str) {
+void view_findstr(View* view, int dir, char* str) {
Sel sel = view->selection;
- buf_findstr(&(view->buffer), str, &sel.beg, &sel.end);
+ buf_findstr(&(view->buffer), dir, str, &sel.beg, &sel.end);
view->selection = sel;
view->sync_needed = true;
view->sync_center = true;
/* Global Data
*****************************************************************************/
+static int SearchDir = DOWN;
static enum RegionId Focused = EDIT;
static Region Regions[NREGIONS] = { 0 };
static ButtonState MouseBtns[MOUSE_BTN_COUNT] = { 0 };
{ ModAny, KEY_BACKSPACE, backspace },
/* Implementation Specific */
- { ModNone, KEY_ESCAPE, select_prev },
- { ModCtrl, KEY_ESCAPE, debug_dump },
- { ModCtrl, 't', change_focus },
- { ModCtrl, 'q', quit },
- { ModCtrl, 'f', search },
- { ModCtrl, 'd', execute },
- { ModCtrl, 'o', open_file },
- { ModCtrl, 'p', pick_ctag },
- { ModCtrl, 'g', goto_ctag },
- { ModCtrl, 'n', new_win },
+ { ModNone, KEY_ESCAPE, select_prev },
+ { ModCtrl, KEY_ESCAPE, debug_dump },
+ { ModCtrl, 't', change_focus },
+ { ModCtrl, 'q', quit },
+ { ModCtrl, 'f', search },
+ { ModCtrl|ModShift, 'f', search },
+ { ModCtrl, 'd', execute },
+ { ModCtrl, 'o', open_file },
+ { ModCtrl, 'p', pick_ctag },
+ { ModCtrl, 'g', goto_ctag },
+ { ModCtrl, 'n', new_win },
};
/* External Commands
}
static void search(void) {
+ SearchDir *= (x11_keymodsset(ModShift) ? -1 : +1);
char* str = view_getctx(currview());
- view_findstr(getview(EDIT), str);
+ view_findstr(getview(EDIT), SearchDir, str);
free(str);
Regions[EDIT].warp_ptr = true;
}
}
static void find(char* arg) {
- view_findstr(getview(EDIT), arg);
+ SearchDir *= (x11_keymodsset(ModShift) ? -1 : +1);
+ view_findstr(getview(EDIT), SearchDir, arg);
}
static void open_file(void) {
if (MouseBtns[MOUSE_BTN_LEFT].pressed) {
paste();
} else {
- view_find(getview(id), row, col);
+ SearchDir *= (x11_keymodsset(ModShift) ? -1 : +1);
+ view_find(getview(id), SearchDir, row, col);
Regions[id].warp_ptr = true;
}
}