1
0
mirror of https://github.com/irssi/irssi.git synced 2024-12-04 14:46:39 -05:00

completion fixes

This commit is contained in:
ailin-nemui 2016-06-16 21:30:46 +02:00
parent fd371cc345
commit 77ad62fadb

View File

@ -37,8 +37,11 @@ static int last_want_space, last_line_pos;
#define isseparator_notspace(c) \ #define isseparator_notspace(c) \
((c) == ',') ((c) == ',')
#define isseparator_space(c) \
((c) == ' ')
#define isseparator(c) \ #define isseparator(c) \
((c) == ' ' || isseparator_notspace(c)) (isseparator_space(c) || isseparator_notspace(c))
void chat_completion_init(void); void chat_completion_init(void);
void chat_completion_deinit(void); void chat_completion_deinit(void);
@ -153,20 +156,23 @@ char *word_complete(WINDOW_REC *window, const char *line, int *pos, int erase, i
word = NULL; word = NULL;
linestart = NULL; linestart = NULL;
} else { } else {
char* old_wordstart;
/* get the word we want to complete */ /* get the word we want to complete */
word = get_word_at(line, *pos, &wordstart); word = get_word_at(line, *pos, &wordstart);
old_wordstart = wordstart;
startpos = (int) (wordstart-line); startpos = (int) (wordstart-line);
wordlen = strlen(word); wordlen = strlen(word);
/* get the start of line until the word we're completing */ /* remove trailing spaces from linestart */
if (isseparator(*line)) { while (wordstart > line && isseparator_space(wordstart[-1]))
/* empty space at the start of line */ wordstart--;
if (wordstart == line)
wordstart += strlen(wordstart); /* unless everything was spaces */
} else { if (old_wordstart > line && wordstart == line)
while (wordstart > line && isseparator(wordstart[-1])) wordstart = old_wordstart - 1;
wordstart--;
}
linestart = g_strndup(line, (int) (wordstart-line)); linestart = g_strndup(line, (int) (wordstart-line));
/* completions usually add space after the word, that makes /* completions usually add space after the word, that makes
@ -175,19 +181,24 @@ char *word_complete(WINDOW_REC *window, const char *line, int *pos, int erase, i
BUT if we start completion with "/msg "<tab>, we don't BUT if we start completion with "/msg "<tab>, we don't
want to complete the /msg word, but instead complete empty want to complete the /msg word, but instead complete empty
word with /msg being in linestart. */ word with /msg being in linestart. */
if (!erase && *pos > 0 && line[*pos-1] == ' ' && if (!erase && *pos > 0 && isseparator_space(line[*pos-1]) &&
(*linestart == '\0' || wordstart[-1] != ' ')) { (*linestart == '\0' || !isseparator_space(wordstart[-1]))) {
char *old; char *old;
old = linestart; old = linestart;
linestart = *linestart == '\0' ? linestart = *linestart == '\0' ?
g_strdup(word) : g_strdup(word) :
g_strconcat(linestart, " ", word, NULL); g_strdup_printf("%s%c%s",
/* do not accidentally duplicate the word separator */
line == wordstart - 1 ? "" : linestart,
wordstart[-1], word);
g_free(old); g_free(old);
g_free(word); g_free(word);
word = g_strdup(""); word = g_strdup("");
startpos = strlen(linestart)+1;
startpos = *linestart == '\0' ? 0 :
strlen(linestart)+1;
wordlen = 0; wordlen = 0;
} }
@ -397,7 +408,8 @@ static GList *completion_get_aliases(const char *alias, char cmdchar)
continue; continue;
if (g_ascii_strncasecmp(node->key, alias, len) == 0) { if (g_ascii_strncasecmp(node->key, alias, len) == 0) {
word = g_strdup_printf("%c%s", cmdchar, node->key); word = cmdchar == '\0' ? g_strdup(node->key) :
g_strdup_printf("%c%s", cmdchar, node->key);
/* add matching alias to completion list, aliases will /* add matching alias to completion list, aliases will
be appended after command completions and kept in be appended after command completions and kept in
uppercase to show it's an alias */ uppercase to show it's an alias */
@ -589,13 +601,19 @@ static void sig_complete_word(GList **list, WINDOW_REC *window,
/* command completion? */ /* command completion? */
cmdchars = settings_get_str("cmdchars"); cmdchars = settings_get_str("cmdchars");
if (*word != '\0' && *linestart == '\0' && strchr(cmdchars, *word)) { if (*word != '\0' && ((*linestart == '\0' && strchr(cmdchars, *word)) ||
(*linestart != '\0' && linestart[1] == '\0' &&
strchr(cmdchars, *linestart)))) {
gboolean skip = *linestart == '\0' ? TRUE : FALSE;
/* complete /command */ /* complete /command */
*list = completion_get_commands(word+1, *word); *list = completion_get_commands(word + (skip ? 1 : 0),
skip ? *word : '\0');
/* complete aliases, too */ /* complete aliases, too */
*list = g_list_concat(*list, *list = g_list_concat(*list,
completion_get_aliases(word+1, *word)); completion_get_aliases(word + (skip ? 1 : 0),
skip ? *word : '\0'));
if (*list != NULL) signal_stop(); if (*list != NULL) signal_stop();
return; return;