backslash input
This commit is contained in:
parent
9018051ce3
commit
1f5be9e69e
93
src/main.c
93
src/main.c
@ -33,6 +33,9 @@ static NOINLINE void repl_init() {
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "utils/calls.h"
|
#include "utils/calls.h"
|
||||||
#include "utils/cstr.h"
|
#include "utils/cstr.h"
|
||||||
|
static Replxx* global_replxx;
|
||||||
|
static char* global_histfile;
|
||||||
|
|
||||||
i8 theme0[12][3] = { // {-1,-1,-1} for default/unchanged color, {-1,-1,n} for grayscale 0…23, else RGB 0…5
|
i8 theme0[12][3] = { // {-1,-1,-1} for default/unchanged color, {-1,-1,n} for grayscale 0…23, else RGB 0…5
|
||||||
[ 0] = {-1,-1,-1}, // default
|
[ 0] = {-1,-1,-1}, // default
|
||||||
[ 1] = {-1,-1,11}, // comments
|
[ 1] = {-1,-1,11}, // comments
|
||||||
@ -145,8 +148,8 @@ static NOINLINE void repl_init() {
|
|||||||
*upper = !hasLower && hasUpper;
|
*upper = !hasLower && hasUpper;
|
||||||
return norm;
|
return norm;
|
||||||
}
|
}
|
||||||
NOINLINE B vec_slice(B x, usz s, usz e) {
|
NOINLINE B vec_slice(B x, usz s, usz len) {
|
||||||
return taga(arr_shVec(TI(x,slice)(incG(x), s, e)));
|
return taga(arr_shVec(TI(x,slice)(incG(x), s, len)));
|
||||||
}
|
}
|
||||||
NOINLINE u32* rskip_name(u32* start, u32* c) {
|
NOINLINE u32* rskip_name(u32* start, u32* c) {
|
||||||
while (c>start && chr_nameM(*(c-1))) c--;
|
while (c>start && chr_nameM(*(c-1))) c--;
|
||||||
@ -226,9 +229,83 @@ static NOINLINE void repl_init() {
|
|||||||
void hint_replxx(const char* inp, replxx_hints* res, int* dist, ReplxxColor* c, void* data) {
|
void hint_replxx(const char* inp, replxx_hints* res, int* dist, ReplxxColor* c, void* data) {
|
||||||
completion_impl(inp, res, true, dist);
|
completion_impl(inp, res, true, dist);
|
||||||
}
|
}
|
||||||
|
static NOINLINE char* malloc_B(B x) {
|
||||||
|
u64 len1 = utf8lenB(x);
|
||||||
|
char* s1 = malloc(len1+1);
|
||||||
|
toUTF8(x, s1);
|
||||||
|
s1[len1] = '\0';
|
||||||
|
return s1;
|
||||||
|
}
|
||||||
|
static NOINLINE void getState(B* s, u64* pos) {
|
||||||
|
ReplxxState st;
|
||||||
|
replxx_get_state(global_replxx, &st);
|
||||||
|
*s = utf8Decode0(st.text);
|
||||||
|
*pos = st.cursorPosition;
|
||||||
|
}
|
||||||
|
static NOINLINE ReplxxState insertChar(u32 p, bool replace) { // free with free(result.text); not using TALLOC because modify callback wants to free() the result :|
|
||||||
|
B s0; u64 pos;
|
||||||
|
getState(&s0, &pos);
|
||||||
|
if (pos==0) replace = false;
|
||||||
|
|
||||||
|
B s = vec_slice(s0, 0, pos-(replace? 1 : 0));
|
||||||
|
ACHR(p);
|
||||||
|
AJOIN(vec_slice(s0, pos, IA(s0)-pos));
|
||||||
|
decG(s0);
|
||||||
|
char* s1 = malloc_B(s);
|
||||||
|
decG(s);
|
||||||
|
|
||||||
|
return (ReplxxState){.text = s1, .cursorPosition = replace? pos : pos+1};
|
||||||
|
}
|
||||||
|
static B b_pv;
|
||||||
|
static int b_pp;
|
||||||
|
static bool inBackslash() { return b_pv.u!=0; }
|
||||||
|
static void stopBackslash() { decG(b_pv); b_pv.u = 0; }
|
||||||
|
ReplxxActionResult backslash_replxx(int code, void* data) {
|
||||||
|
if (inBackslash()) {
|
||||||
|
ReplxxState st = insertChar('\\', false);
|
||||||
|
replxx_set_state(global_replxx, &st);
|
||||||
|
free((char*) st.text);
|
||||||
|
stopBackslash();
|
||||||
|
} else {
|
||||||
|
ReplxxState st;
|
||||||
|
replxx_get_state(global_replxx, &st);
|
||||||
|
b_pv = utf8Decode0(st.text);
|
||||||
|
b_pp = st.cursorPosition;
|
||||||
|
}
|
||||||
|
return REPLXX_ACTION_RESULT_CONTINUE;
|
||||||
|
}
|
||||||
|
static NOINLINE bool slice_equal(B a, usz as, B b, usz bs, usz l) {
|
||||||
|
B ac = vec_slice(a, as, l);
|
||||||
|
B bc = vec_slice(b, bs, l);
|
||||||
|
bool r = equal(ac, bc);
|
||||||
|
decG(ac); decG(bc);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
B indexOf_c2(B, B, B);
|
||||||
|
B pick_c1(B, B);
|
||||||
|
|
||||||
|
static B b_key, b_val;
|
||||||
|
void modified_replxx(char** s_res, int* p_res, void* userData) {
|
||||||
|
if (!inBackslash()) return;
|
||||||
|
|
||||||
|
B s; u64 pos;
|
||||||
|
getState(&s, &pos);
|
||||||
|
if (IA(b_pv)+1 != IA(s) || b_pp+1 != pos) goto stop;
|
||||||
|
if (!slice_equal(b_pv, 0, s, 0, pos-1)) goto stop;
|
||||||
|
if (!slice_equal(b_pv, b_pp, s, pos, IA(s)-pos)) goto stop;
|
||||||
|
usz mapPos = o2i(pick_c1(m_f64(0), indexOf_c2(m_f64(0), incG(b_key), IGet(s,pos-1))));
|
||||||
|
if (mapPos==IA(b_key)) goto stop;
|
||||||
|
|
||||||
|
ReplxxState st = insertChar(o2c(IGetU(b_val, mapPos)), true); // st.text will be free()'d by replxx
|
||||||
|
*s_res = (char*) st.text;
|
||||||
|
*p_res = st.cursorPosition;
|
||||||
|
|
||||||
|
stop: decG(s);
|
||||||
|
stopBackslash();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static Replxx* global_replxx;
|
|
||||||
static char* global_histfile;
|
|
||||||
void before_exit() {
|
void before_exit() {
|
||||||
if (global_replxx!=NULL && global_histfile!=NULL) {
|
if (global_replxx!=NULL && global_histfile!=NULL) {
|
||||||
replxx_history_save(global_replxx, global_histfile);
|
replxx_history_save(global_replxx, global_histfile);
|
||||||
@ -237,8 +314,13 @@ static NOINLINE void repl_init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void replxx_gcFn() {
|
||||||
|
mm_visit(b_pv);
|
||||||
|
}
|
||||||
static void cbqn_init_replxx() {
|
static void cbqn_init_replxx() {
|
||||||
build_theme(theme0_built, theme0);
|
build_theme(theme0_built, theme0);
|
||||||
|
gc_add(b_key = m_c32vec_0(U"\"`1234567890-=~!@#$%^&*()_+qwertyuiop[]QWERTYUIOP{}asdfghjkl;'ASDFGHJKL:|zxcvbnm,./ZXCVBNM<>? "));
|
||||||
|
gc_add(b_val = m_c32vec_0( U"˙˜˘¨⁼⌜´˝7∞¯•÷׬⎉⚇⍟◶⊘⎊⍎⍕⟨⟩√⋆⌽𝕨∊↑∧y⊔⊏⊐π←→↙𝕎⍷𝕣⍋YU⊑⊒⍳⊣⊢⍉𝕤↕𝕗𝕘⊸∘○⟜⋄↩↖𝕊D𝔽𝔾«J⌾»·|⥊𝕩↓∨⌊n≡∾≍≠⋈𝕏C⍒⌈N≢≤≥⇐‿"));
|
||||||
sysvalNames = emptyHVec();
|
sysvalNames = emptyHVec();
|
||||||
sysvalNamesNorm = emptyHVec();
|
sysvalNamesNorm = emptyHVec();
|
||||||
u32** c = dsv_text;
|
u32** c = dsv_text;
|
||||||
@ -249,6 +331,7 @@ static NOINLINE void repl_init() {
|
|||||||
}
|
}
|
||||||
gc_add(sysvalNames);
|
gc_add(sysvalNames);
|
||||||
gc_add(sysvalNamesNorm);
|
gc_add(sysvalNamesNorm);
|
||||||
|
gc_addFn(replxx_gcFn);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void before_exit() { }
|
void before_exit() { }
|
||||||
@ -677,6 +760,8 @@ int main(int argc, char* argv[]) {
|
|||||||
replxx_set_hint_callback(replxx, hint_replxx, NULL);
|
replxx_set_hint_callback(replxx, hint_replxx, NULL);
|
||||||
replxx_set_completion_callback(replxx, complete_replxx, NULL);
|
replxx_set_completion_callback(replxx, complete_replxx, NULL);
|
||||||
replxx_enable_bracketed_paste(replxx);
|
replxx_enable_bracketed_paste(replxx);
|
||||||
|
replxx_bind_key(replxx, '\\', backslash_replxx, NULL);
|
||||||
|
replxx_set_modify_callback(replxx, modified_replxx, NULL);
|
||||||
|
|
||||||
while(true) {
|
while(true) {
|
||||||
const char* ln = replxx_input(replxx, " ");
|
const char* ln = replxx_input(replxx, " ");
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user