mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-07 17:43:53 +02:00
Unicode input: When searching by name search for prefix matches as well as whole word matches
So now hori matches both "hori" and "horizontal". Switched to a prefix-trie internally.
This commit is contained in:
@@ -56,7 +56,7 @@ def name(cp):
|
||||
@lru_cache(maxsize=256)
|
||||
def codepoints_matching_search(parts):
|
||||
ans = []
|
||||
if parts and parts[0]:
|
||||
if parts and parts[0] and len(parts[0]) > 1:
|
||||
codepoints = points_for_word(parts[0])
|
||||
for word in parts[1:]:
|
||||
pts = points_for_word(word)
|
||||
|
||||
63099
kittens/unicode_input/names.h
generated
63099
kittens/unicode_input/names.h
generated
File diff suppressed because one or more lines are too long
@@ -9,32 +9,61 @@
|
||||
|
||||
static PyObject*
|
||||
all_words(PYNOARG) {
|
||||
PyObject *ans = PyTuple_New(arraysz(idx_to_word));
|
||||
PyObject *ans = PyTuple_New(arraysz(all_words_map));
|
||||
if (!ans) return NULL;
|
||||
for (size_t i = 0; i < arraysz(idx_to_word); i++) {
|
||||
PyObject *w = PyUnicode_FromString(idx_to_word[i]);
|
||||
for (size_t i = 0; i < arraysz(all_words_map); i++) {
|
||||
PyObject *w = PyUnicode_FromString(all_words_map[i]);
|
||||
if (w == NULL) { Py_DECREF(ans); return NULL; }
|
||||
PyTuple_SET_ITEM(ans, i, w);
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
static inline void
|
||||
add_matches(const word_trie *wt, char_type *codepoints, size_t *pos, const size_t sz) {
|
||||
size_t num = mark_groups[wt->match_offset];
|
||||
for (size_t i = wt->match_offset + 1; i < wt->match_offset + 1 + num && *pos < sz; i++, (*pos)++) {
|
||||
codepoints[*pos] = mark_to_cp[mark_groups[i]];
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
process_trie_node(const word_trie *wt, char_type *codepoints, size_t *pos, const size_t sz) {
|
||||
if (wt->match_offset) add_matches(wt, codepoints, pos, sz);
|
||||
size_t num_children = children_array[wt->children_offset];
|
||||
if (!num_children) return;
|
||||
for (size_t c = wt->children_offset + 1; c < wt->children_offset + 1 + num_children; c++) {
|
||||
if (*pos > sz) return;
|
||||
uint32_t x = children_array[c];
|
||||
process_trie_node(&all_trie_nodes[x >> 8], codepoints, pos, sz);
|
||||
}
|
||||
}
|
||||
|
||||
static inline PyObject*
|
||||
codepoints_for_word(const char *word, size_t len) {
|
||||
PyObject *ans = PyFrozenSet_New(NULL); if (ans == NULL) return NULL;
|
||||
const unsigned short *words = words_for_first_letter[(unsigned)*word];
|
||||
if (words == NULL) return ans;
|
||||
for (unsigned short i = 1; i <= words[0]; i++) {
|
||||
unsigned short word_idx = words[i];
|
||||
const char *w = idx_to_word[word_idx];
|
||||
if (strncmp(word, w, len) == 0 && strlen(w) == len) {
|
||||
const char_type* codepoints = codepoints_for_word_idx[word_idx];
|
||||
for (char_type i = 1; i <= codepoints[0]; i++) {
|
||||
PyObject *t = PyLong_FromUnsignedLong(codepoints[i]); if (t == NULL) { Py_DECREF(ans); return NULL; }
|
||||
int ret = PySet_Add(ans, t); Py_DECREF(t); if (ret != 0) { Py_DECREF(ans); return NULL; }
|
||||
const word_trie *wt = all_trie_nodes;
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
unsigned char ch = word[i];
|
||||
size_t num_children = children_array[wt->children_offset];
|
||||
if (!num_children) return PyFrozenSet_New(NULL);
|
||||
bool found = false;
|
||||
for (size_t c = wt->children_offset + 1; c < wt->children_offset + 1 + num_children; c++) {
|
||||
uint32_t x = children_array[c];
|
||||
if ((x & 0xff) == ch) {
|
||||
found = true;
|
||||
wt = &all_trie_nodes[x >> 8];
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!found) return PyFrozenSet_New(NULL);
|
||||
}
|
||||
static char_type codepoints[1024];
|
||||
size_t cpos = 0;
|
||||
process_trie_node(wt, codepoints, &cpos, arraysz(codepoints));
|
||||
PyObject *ans = PyFrozenSet_New(NULL); if (ans == NULL) return NULL;
|
||||
for (size_t i = 0; i < cpos; i++) {
|
||||
PyObject *t = PyLong_FromUnsignedLong(codepoints[i]); if (t == NULL) { Py_DECREF(ans); return NULL; }
|
||||
int ret = PySet_Add(ans, t); Py_DECREF(t); if (ret != 0) { Py_DECREF(ans); return NULL; }
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user