Compare commits

...

3 Commits

Author SHA1 Message Date
Přemysl Eric Janouch 7c7e12d8d5
degesch: start with lexically ordered chanusers
This makes nick autocompletion start in a non-arbitrary state.
2021-07-23 19:14:57 +02:00
Přemysl Eric Janouch 3cb93d24e8
degesch: order nick autocomplete by time 2021-07-23 18:43:20 +02:00
Přemysl Eric Janouch acddfe2cfa
degesch: cleanup 2021-07-23 18:43:19 +02:00
2 changed files with 52 additions and 10 deletions

5
NEWS
View File

@ -1,3 +1,8 @@
1.3.0 (20xx-xx-xx)
* degesch: made nick autocompletion ordered by the time of last action
1.2.0 (2021-07-08) "There Are Other Countries As Well"
* degesch: added a /squery command for IRCnet

View File

@ -459,6 +459,10 @@ input_rl_start (void *input, const char *program_name)
rl_completer_word_break_characters = NULL;
rl_attempted_completion_function = app_readline_completion;
// We shouldn't produce any duplicates that the library would help us
// autofilter, and we don't generally want alphabetic ordering at all
rl_sort_completion_matches = false;
hard_assert (self->prompt != NULL);
// The inputrc is read before any callbacks are called, so we need to
// register all functions that our user may want to map up front
@ -7266,6 +7270,19 @@ irc_handle_privmsg_text (struct server *s,
char *prefixes = irc_get_privmsg_prefix
(s, str_map_find (&s->irc_users, nickname), target);
// Make autocomplete offer the last speakers first on partial matches
// TODO: might want to do this on notices as well, and the behaviour
// shouldn't change depending on whether CAP echo-message is enabled
struct user *user;
struct channel_user *channel_user;
if (buffer->channel
&& (user = str_map_find (&s->irc_users, nickname))
&& (channel_user = irc_channel_get_user (buffer->channel, user)))
{
LIST_UNLINK (buffer->channel->users, channel_user);
LIST_PREPEND (buffer->channel->users, channel_user);
}
// IRCv3.2 echo-message could otherwise cause us to highlight ourselves
if (irc_is_this_us (s, msg->prefix) || !irc_is_highlight (s, text->str))
{
@ -7589,20 +7606,35 @@ channel_user_sort_entry_cmp (const void *entry_a, const void *entry_b)
b->channel_user->user->nickname);
}
static void
irc_sort_channel_users (struct channel *channel)
{
size_t n_users = channel->users_len;
struct channel_user_sort_entry entries[n_users], *p = entries;
LIST_FOR_EACH (struct channel_user, iter, channel->users)
{
p->s = channel->s;
p->channel_user = iter;
p++;
}
qsort (entries, n_users, sizeof *entries, channel_user_sort_entry_cmp);
channel->users = NULL;
while (p-- != entries)
LIST_PREPEND (channel->users, p->channel_user);
}
static char *
make_channel_users_list (struct channel *channel)
{
size_t n_users = 0;
LIST_FOR_EACH (struct channel_user, iter, channel->users)
n_users++;
struct channel_user_sort_entry entries[n_users];
size_t i = 0;
size_t n_users = channel->users_len;
struct channel_user_sort_entry entries[n_users], *p = entries;
LIST_FOR_EACH (struct channel_user, iter, channel->users)
{
entries[i].s = channel->s;
entries[i].channel_user = iter;
i++;
p->s = channel->s;
p->channel_user = iter;
p++;
}
qsort (entries, n_users, sizeof *entries, channel_user_sort_entry_cmp);
@ -7610,7 +7642,7 @@ make_channel_users_list (struct channel *channel)
// Make names of users that are away italicised, constructing a formatter
// and adding a new attribute seems like unnecessary work
struct str list = str_make ();
for (i = 0; i < n_users; i++)
for (size_t i = 0; i < n_users; i++)
{
struct channel_user *channel_user = entries[i].channel_user;
if (channel_user->user->away) str_append_c (&list, '\x1d');
@ -7663,6 +7695,9 @@ irc_process_names (struct channel *channel)
struct str_map present = str_map_make (NULL);
present.key_xfrm = channel->s->irc_strxfrm;
// Either that, or there is no other inhabitant, and sorting does nothing
bool we_have_just_joined = channel->users_len == 1;
struct strv *updates = &channel->names_buf;
for (size_t i = 0; i < updates->len; i++)
{
@ -7686,6 +7721,8 @@ irc_process_names (struct channel *channel)
str_map_free (&present);
strv_reset (&channel->names_buf);
if (we_have_just_joined)
irc_sort_channel_users (channel);
if (!channel->show_names_after_who)
irc_process_names_finish (channel);
}