192 lines
5.6 KiB
D
192 lines
5.6 KiB
D
module patch.keyboardselect;
|
|
|
|
import st;
|
|
import x;
|
|
import config;
|
|
import patches;
|
|
import core.stdc.stdio;
|
|
import core.stdc.stdlib;
|
|
import core.stdc.string;
|
|
import deimos.X11.keysym;
|
|
import deimos.X11.X : KeySym, CurrentTime;
|
|
|
|
static if (isPatchEnabled!"KEYBOARDSELECT_PATCH") {
|
|
__gshared {
|
|
static int selectsearch_mode = 0;
|
|
static TCursor cursor_state;
|
|
static Glyph* saved_line = null;
|
|
static int saved_col = 0;
|
|
static int saved_bot = 0;
|
|
}
|
|
|
|
void set_notifmode(int type, KeySym ksym) {
|
|
static immutable char*[2] lib = [" MOVE ".ptr, " SEL ".ptr];
|
|
static Glyph* g = null;
|
|
static int col, bot;
|
|
|
|
if (ksym == cast(KeySym)(-1)) {
|
|
if (g) free(g);
|
|
col = term.col;
|
|
bot = term.bot;
|
|
g = cast(Glyph*)xmalloc(col * Glyph.sizeof);
|
|
memcpy(g, term.line[bot], col * Glyph.sizeof);
|
|
} else if (ksym == cast(KeySym)(-2)) {
|
|
if (g) memcpy(term.line[bot], g, col * Glyph.sizeof);
|
|
}
|
|
|
|
if (type < 2) {
|
|
const(char)* z = lib[type];
|
|
for (int i = col - 6; i < col && *z; i++, z++) {
|
|
term.line[bot][i].mode = GlyphAttribute.REVERSE;
|
|
term.line[bot][i].u = *z;
|
|
term.line[bot][i].fg = config.defaultfg;
|
|
term.line[bot][i].bg = config.defaultbg;
|
|
}
|
|
} else if (type < 5) {
|
|
if (g) memcpy(term.line[bot], g, col * Glyph.sizeof);
|
|
} else {
|
|
for (int i = 0; i < col; i++) {
|
|
term.line[bot][i].mode = GlyphAttribute.REVERSE;
|
|
term.line[bot][i].u = ' ';
|
|
term.line[bot][i].fg = config.defaultfg;
|
|
term.line[bot][i].bg = config.defaultbg;
|
|
}
|
|
term.line[bot][0].u = cast(Rune)ksym;
|
|
}
|
|
|
|
term.dirty[bot] = 1;
|
|
drawregion(0, bot, col, bot + 1);
|
|
}
|
|
|
|
Glyph getglyph(int y, int x) {
|
|
static if (isPatchEnabled!"SCROLLBACK_PATCH") {
|
|
int realy = y - term.scr;
|
|
if (realy >= 0) {
|
|
return term.line[realy][x];
|
|
} else {
|
|
realy = term.histi - term.scr + y + 1;
|
|
return term.hist[realy][x];
|
|
}
|
|
} else {
|
|
return term.line[y][x];
|
|
}
|
|
}
|
|
|
|
void select_or_drawcursor(int selectsearch_mode, int type) {
|
|
int done = 0;
|
|
|
|
if (selectsearch_mode & 1) {
|
|
selextend(term.c.x, term.c.y, type, done);
|
|
setsel(getsel(), CurrentTime);
|
|
} else {
|
|
xdrawcursor(term.c.x, term.c.y, getglyph(term.c.y, term.c.x),
|
|
term.ocx, term.ocy, getglyph(term.ocy, term.ocx));
|
|
}
|
|
}
|
|
|
|
extern(C) void keyboard_select(const(Arg)* dummy) {
|
|
selectsearch_mode ^= 1;
|
|
set_notifmode(selectsearch_mode, cast(KeySym)(-1));
|
|
if (selectsearch_mode == 0) {
|
|
set_notifmode(4, cast(KeySym)(-2));
|
|
}
|
|
select_or_drawcursor(selectsearch_mode, SelType.REGULAR);
|
|
}
|
|
|
|
int trt_kbdselect(KeySym ksym, char* buf, int len) {
|
|
static TCursor cu;
|
|
int i, bound;
|
|
|
|
if (selectsearch_mode == 0) return 0;
|
|
|
|
switch (ksym) {
|
|
case XK_Escape:
|
|
selectsearch_mode = 0;
|
|
set_notifmode(4, cast(KeySym)(-2));
|
|
return 0;
|
|
|
|
case XK_Return:
|
|
selectsearch_mode ^= 1;
|
|
set_notifmode(selectsearch_mode, cast(KeySym)(-1));
|
|
select_or_drawcursor(selectsearch_mode, SelType.REGULAR);
|
|
return 0;
|
|
|
|
case XK_h:
|
|
case XK_Left:
|
|
if (term.c.x > 0) {
|
|
term.c.x--;
|
|
select_or_drawcursor(selectsearch_mode, SelType.REGULAR);
|
|
}
|
|
return 0;
|
|
|
|
case XK_l:
|
|
case XK_Right:
|
|
if (term.c.x < term.col - 1) {
|
|
term.c.x++;
|
|
select_or_drawcursor(selectsearch_mode, SelType.REGULAR);
|
|
}
|
|
return 0;
|
|
|
|
case XK_j:
|
|
case XK_Down:
|
|
if (term.c.y < term.bot) {
|
|
term.c.y++;
|
|
select_or_drawcursor(selectsearch_mode, SelType.REGULAR);
|
|
}
|
|
return 0;
|
|
|
|
case XK_k:
|
|
case XK_Up:
|
|
if (term.c.y > term.top) {
|
|
term.c.y--;
|
|
select_or_drawcursor(selectsearch_mode, SelType.REGULAR);
|
|
}
|
|
return 0;
|
|
|
|
case XK_w:
|
|
// Word forward
|
|
while (term.c.x < term.col - 1 &&
|
|
getglyph(term.c.y, term.c.x).u == ' ') {
|
|
term.c.x++;
|
|
}
|
|
while (term.c.x < term.col - 1 &&
|
|
getglyph(term.c.y, term.c.x).u != ' ') {
|
|
term.c.x++;
|
|
}
|
|
select_or_drawcursor(selectsearch_mode, SelType.REGULAR);
|
|
return 0;
|
|
|
|
case XK_b:
|
|
// Word backward
|
|
while (term.c.x > 0 &&
|
|
getglyph(term.c.y, term.c.x).u == ' ') {
|
|
term.c.x--;
|
|
}
|
|
while (term.c.x > 0 &&
|
|
getglyph(term.c.y, term.c.x).u != ' ') {
|
|
term.c.x--;
|
|
}
|
|
select_or_drawcursor(selectsearch_mode, SelType.REGULAR);
|
|
return 0;
|
|
|
|
case XK_0:
|
|
case XK_Home:
|
|
term.c.x = 0;
|
|
select_or_drawcursor(selectsearch_mode, SelType.REGULAR);
|
|
return 0;
|
|
|
|
case XK_dollar:
|
|
case XK_End:
|
|
term.c.x = term.col - 1;
|
|
select_or_drawcursor(selectsearch_mode, SelType.REGULAR);
|
|
return 0;
|
|
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void toggle_winmode(int flag) {
|
|
term.mode ^= flag;
|
|
}
|
|
} |