dst/source/patch/keyboardselect.d

192 lines
5.6 KiB
D
Raw Normal View History

2025-06-26 18:47:07 +00:00
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;
}
}