mirror of
https://oauth2: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@github.com/m1ngsama/TNT.git
synced 2026-06-26 05:44:38 +08:00
commands: highlight matched keyword in :search results (UX-7)
:search dumps the matching lines with username and content, but the
query word itself was just rendered as-is. In a result set with 15
matches you had to eye-scan each line for the keyword.
Now each occurrence of the (case-insensitively matched) needle is
wrapped in a reverse-yellow ANSI chip both in the username column and
in the content column. Original casing of the matched substring is
preserved.
Helper:
append_highlighted(output, buf_size, &pos, text, needle)
emits text into the output buffer with every case-insensitive hit
wrapped in `\033[7;33m … \033[0m`.
strcasestr() needs _DEFAULT_SOURCE / _DARWIN_C_SOURCE feature macros;
the same dance message.c already does is now mirrored in commands.c.
This commit is contained in:
parent
0a013ed40f
commit
0e03c4d216
1 changed files with 40 additions and 1 deletions
|
|
@ -1,3 +1,9 @@
|
|||
#ifndef _DEFAULT_SOURCE
|
||||
#define _DEFAULT_SOURCE /* for strcasestr() on glibc */
|
||||
#endif
|
||||
#if defined(__APPLE__) && !defined(_DARWIN_C_SOURCE)
|
||||
#define _DARWIN_C_SOURCE /* for strcasestr() on macOS */
|
||||
#endif
|
||||
#include "commands.h"
|
||||
#include "chat_room.h"
|
||||
#include "client.h"
|
||||
|
|
@ -10,6 +16,33 @@
|
|||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
/* Append `text` to the output buffer with every case-insensitive match of
|
||||
* `needle` wrapped in a reverse-yellow ANSI chip. Preserves the original
|
||||
* casing of the matched substring. needle == NULL or empty appends raw. */
|
||||
static void append_highlighted(char *output, size_t buf_size, size_t *pos,
|
||||
const char *text, const char *needle) {
|
||||
if (!needle || !*needle) {
|
||||
buffer_appendf(output, buf_size, pos, "%s", text);
|
||||
return;
|
||||
}
|
||||
size_t nlen = strlen(needle);
|
||||
const char *p = text;
|
||||
while (*p) {
|
||||
const char *hit = strcasestr(p, needle);
|
||||
if (!hit) {
|
||||
buffer_appendf(output, buf_size, pos, "%s", p);
|
||||
return;
|
||||
}
|
||||
if (hit > p) {
|
||||
buffer_append_bytes(output, buf_size, pos, p, (size_t)(hit - p));
|
||||
}
|
||||
buffer_append_bytes(output, buf_size, pos, "\033[7;33m", 7);
|
||||
buffer_append_bytes(output, buf_size, pos, hit, nlen);
|
||||
buffer_append_bytes(output, buf_size, pos, "\033[0m", 4);
|
||||
p = hit + nlen;
|
||||
}
|
||||
}
|
||||
|
||||
void commands_dispatch(client_t *client) {
|
||||
char cmd_buf[256];
|
||||
strncpy(cmd_buf, client->command_input, sizeof(cmd_buf) - 1);
|
||||
|
|
@ -253,7 +286,13 @@ void commands_dispatch(client_t *client) {
|
|||
localtime_r(&found[i].timestamp, &tmi);
|
||||
strftime(ts, sizeof(ts), "%m-%d %H:%M", &tmi);
|
||||
buffer_appendf(output, sizeof(output), &pos,
|
||||
"[%s] %s: %s\n", ts, found[i].username, found[i].content);
|
||||
"[%s] ", ts);
|
||||
append_highlighted(output, sizeof(output), &pos,
|
||||
found[i].username, query);
|
||||
buffer_appendf(output, sizeof(output), &pos, ": ");
|
||||
append_highlighted(output, sizeof(output), &pos,
|
||||
found[i].content, query);
|
||||
buffer_appendf(output, sizeof(output), &pos, "\n");
|
||||
}
|
||||
free(found);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue