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

Simplified autocompleters and command history

This commit is contained in:
James Booth 2015-01-16 22:50:40 +00:00
parent 7a5deca77c
commit 4c6cfcdca0
28 changed files with 315 additions and 456 deletions

View File

@ -21,9 +21,9 @@ core_sources = \
src/ui/windows.c src/ui/windows.h \
src/ui/rosterwin.c src/ui/occupantswin.c \
src/ui/buffer.c src/ui/buffer.h \
src/command/command.h src/command/command.c src/command/history.c \
src/command/command.h src/command/command.c \
src/command/commands.h src/command/commands.c \
src/command/history.h src/tools/parser.c \
src/tools/parser.c \
src/tools/parser.h \
src/tools/p_sha1.h src/tools/p_sha1.c \
src/tools/autocomplete.c src/tools/autocomplete.h \
@ -44,9 +44,9 @@ tests_sources = \
src/roster_list.c src/roster_list.h \
src/xmpp/xmpp.h src/xmpp/form.c \
src/ui/ui.h \
src/command/command.h src/command/command.c src/command/history.c \
src/command/command.h src/command/command.c \
src/command/commands.h src/command/commands.c \
src/command/history.h src/tools/parser.c \
src/tools/parser.c \
src/tools/parser.h \
src/tools/p_sha1.h src/tools/p_sha1.c \
src/tools/autocomplete.c src/tools/autocomplete.h \

File diff suppressed because it is too large Load Diff

View File

@ -44,7 +44,7 @@ GHashTable *commands;
void cmd_init(void);
void cmd_uninit(void);
void cmd_autocomplete(char *input, int *size);
char* cmd_autocomplete(const char * const input);
void cmd_reset_autocomplete(void);
void cmd_autocomplete_add(char *value);
void cmd_autocomplete_remove(char *value);
@ -63,7 +63,7 @@ GSList * cmd_get_settings_help(void);
GSList * cmd_get_presence_help(void);
void cmd_history_append(char *inp);
char *cmd_history_previous(char *inp, int *size);
char *cmd_history_next(char *inp, int *size);
char *cmd_history_previous(char *inp);
char *cmd_history_next(char *inp);
#endif

View File

@ -1,81 +0,0 @@
/*
* history.c
*
* Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com>
*
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#include "tools/history.h"
#define MAX_HISTORY 100
static History history;
void _stringify_input(char *inp, int size, char *string);
void
cmd_history_init(void)
{
history = history_new(MAX_HISTORY);
}
void
cmd_history_append(char *inp)
{
history_append(history, inp);
}
char *
cmd_history_previous(char *inp, int *size)
{
char inp_str[*size + 1];
_stringify_input(inp, *size, inp_str);
return history_previous(history, inp_str);
}
char *
cmd_history_next(char *inp, int *size)
{
char inp_str[*size + 1];
_stringify_input(inp, *size, inp_str);
return history_next(history, inp_str);
}
void
_stringify_input(char *inp, int size, char *string)
{
int i;
for (i = 0; i < size; i++) {
string[i] = inp[i];
}
string[size] = '\0';
}

View File

@ -1,40 +0,0 @@
/*
* history.h
*
* Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com>
*
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#ifndef COMMAND_HISTORY_H
#define COMMAND_HISTORY_H
void cmd_history_init(void);
#endif

View File

@ -191,7 +191,7 @@ str_replace(const char *string, const char *substr,
}
int
str_contains(char str[], int size, char ch)
str_contains(const char str[], int size, char ch)
{
int i;
for (i = 0; i < size; i++) {

View File

@ -103,7 +103,7 @@ gboolean create_dir(char *name);
gboolean mkdir_recursive(const char *dir);
char * str_replace(const char *string, const char *substr,
const char *replacement);
int str_contains(char str[], int size, char ch);
int str_contains(const char str[], int size, char ch);
char * prof_getline(FILE *stream);
char* release_get_latest(void);
gboolean release_is_new(char *found_version);

View File

@ -117,13 +117,13 @@ accounts_close(void)
}
char *
accounts_find_enabled(char *prefix)
accounts_find_enabled(const char * const prefix)
{
return autocomplete_complete(enabled_ac, prefix, TRUE);
}
char *
accounts_find_all(char *prefix)
accounts_find_all(const char * const prefix)
{
return autocomplete_complete(all_ac, prefix, TRUE);
}

View File

@ -43,8 +43,8 @@
void accounts_load(void);
void accounts_close(void);
char * accounts_find_all(char *prefix);
char * accounts_find_enabled(char *prefix);
char * accounts_find_all(const char * const prefix);
char * accounts_find_enabled(const char * const prefix);
void accounts_reset_all_search(void);
void accounts_reset_enabled_search(void);
void accounts_add(const char *jid, const char *altdomain, const int port);

View File

@ -154,7 +154,7 @@ prefs_close(void)
}
char *
prefs_autocomplete_boolean_choice(char *prefix)
prefs_autocomplete_boolean_choice(const char * const prefix)
{
return autocomplete_complete(boolean_choice_ac, prefix, TRUE);
}

View File

@ -114,7 +114,7 @@ void prefs_close(void);
char * prefs_find_login(char *prefix);
void prefs_reset_login_search(void);
char * prefs_autocomplete_boolean_choice(char *prefix);
char * prefs_autocomplete_boolean_choice(const char * const prefix);
void prefs_reset_boolean_choice(void);
gint prefs_get_gone(void);

View File

@ -141,7 +141,7 @@ muc_invites_reset_ac(void)
}
char *
muc_invites_find(char *search_str)
muc_invites_find(const char * const search_str)
{
return autocomplete_complete(invite_ac, search_str, TRUE);
}
@ -632,8 +632,8 @@ muc_roster_nick_change_complete(const char * const room,
return NULL;
}
void
muc_autocomplete(char *input, int *size)
char *
muc_autocomplete(const char * const input)
{
win_type_t wintype = ui_current_win_type();
if (wintype == WIN_MUC) {
@ -641,8 +641,7 @@ muc_autocomplete(char *input, int *size)
ChatRoom *chat_room = g_hash_table_lookup(rooms, mucwin->roomjid);
if (chat_room && chat_room->nick_ac) {
input[*size] = '\0';
char *search_str = NULL;
const char * search_str = NULL;
gchar *last_space = g_strrstr(input, " ");
if (!last_space) {
@ -664,12 +663,15 @@ muc_autocomplete(char *input, int *size)
if (!last_space || (*(last_space+1) == '\0')) {
g_string_append(replace_with, ": ");
}
ui_replace_input(input, replace_with->str, size);
g_string_free(replace_with, TRUE);
g_free(result);
result = replace_with->str;
g_string_free(replace_with, FALSE);
return result;
}
}
}
return NULL;
}
void

View File

@ -114,7 +114,7 @@ gint muc_invites_count(void);
GSList* muc_invites(void);
gboolean muc_invites_contain(const char * const room);
void muc_invites_reset_ac(void);
char* muc_invites_find(char *search_str);
char* muc_invites_find(const char * const search_str);
void muc_invites_clear(void);
void muc_set_subject(const char * const room, const char * const subject);
@ -123,7 +123,7 @@ char* muc_subject(const char * const room);
void muc_pending_broadcasts_add(const char * const room, const char * const message);
GList * muc_pending_broadcasts(const char * const room);
void muc_autocomplete(char *input, int *size);
char* muc_autocomplete(const char * const input);
void muc_autocomplete_reset(const char * const room);
gboolean muc_requires_config(const char * const room);

View File

@ -344,13 +344,13 @@ roster_has_pending_subscriptions(void)
}
char *
roster_contact_autocomplete(char *search_str)
roster_contact_autocomplete(const char * const search_str)
{
return autocomplete_complete(name_ac, search_str, TRUE);
}
char *
roster_fulljid_autocomplete(char *search_str)
roster_fulljid_autocomplete(const char * const search_str)
{
return autocomplete_complete(fulljid_ac, search_str, TRUE);
}
@ -406,13 +406,13 @@ roster_get_groups(void)
}
char *
roster_group_autocomplete(char *search_str)
roster_group_autocomplete(const char * const search_str)
{
return autocomplete_complete(groups_ac, search_str, TRUE);
}
char *
roster_barejid_autocomplete(char *search_str)
roster_barejid_autocomplete(const char * const search_str)
{
return autocomplete_complete(barejid_ac, search_str, TRUE);
}

View File

@ -59,12 +59,12 @@ char * roster_barejid_from_name(const char * const name);
GSList * roster_get_contacts(void);
GSList * roster_get_contacts_online(void);
gboolean roster_has_pending_subscriptions(void);
char * roster_contact_autocomplete(char *search_str);
char * roster_fulljid_autocomplete(char *search_str);
char * roster_contact_autocomplete(const char * const search_str);
char * roster_fulljid_autocomplete(const char * const search_str);
GSList * roster_get_group(const char * const group);
GSList * roster_get_groups(void);
char * roster_group_autocomplete(char *search_str);
char * roster_barejid_autocomplete(char *search_str);
char * roster_group_autocomplete(const char * const search_str);
char * roster_barejid_autocomplete(const char * const search_str);
GSList * roster_get_contacts_by_presence(const char * const presence);
GSList * roster_get_nogroup(void);

View File

@ -169,7 +169,7 @@ autocomplete_contains(Autocomplete ac, const char *value)
}
gchar *
autocomplete_complete(Autocomplete ac, gchar *search_str, gboolean quote)
autocomplete_complete(Autocomplete ac, const gchar *search_str, gboolean quote)
{
gchar *found = NULL;
@ -216,8 +216,7 @@ autocomplete_complete(Autocomplete ac, gchar *search_str, gboolean quote)
}
char *
autocomplete_param_with_func(char *input, int *size, char *command,
autocomplete_func func)
autocomplete_param_with_func(const char * const input, char *command, autocomplete_func func)
{
GString *auto_msg = NULL;
char *result = NULL;
@ -225,15 +224,16 @@ autocomplete_param_with_func(char *input, int *size, char *command,
sprintf(command_cpy, "%s ", command);
int len = strlen(command_cpy);
if ((strncmp(input, command_cpy, len) == 0) && (*size > len)) {
if ((strncmp(input, command_cpy, len) == 0) && (strlen(input) > len)) {
int i;
char inp_cpy[*size];
for(i = len; i < *size; i++) {
inp_cpy[i-len] = input[i];
int inp_len = strlen(input);
char prefix[inp_len];
for(i = len; i < inp_len; i++) {
prefix[i-len] = input[i];
}
inp_cpy[(*size) - len] = '\0';
prefix[inp_len - len] = '\0';
char *found = func(inp_cpy);
char *found = func(prefix);
if (found) {
auto_msg = g_string_new(command_cpy);
g_string_append(auto_msg, found);
@ -247,23 +247,23 @@ autocomplete_param_with_func(char *input, int *size, char *command,
}
char *
autocomplete_param_with_ac(char *input, int *size, char *command,
Autocomplete ac, gboolean quote)
autocomplete_param_with_ac(const char * const input, char *command, Autocomplete ac, gboolean quote)
{
GString *auto_msg = NULL;
char *result = NULL;
char *command_cpy = malloc(strlen(command) + 2);
sprintf(command_cpy, "%s ", command);
int len = strlen(command_cpy);
if ((strncmp(input, command_cpy, len) == 0) && (*size > len)) {
int inp_len = strlen(input);
if ((strncmp(input, command_cpy, len) == 0) && (strlen(input) > len)) {
int i;
char inp_cpy[*size];
for(i = len; i < *size; i++) {
inp_cpy[i-len] = input[i];
char prefix[inp_len];
for(i = len; i < inp_len; i++) {
prefix[i-len] = input[i];
}
inp_cpy[(*size) - len] = '\0';
prefix[inp_len - len] = '\0';
char *found = autocomplete_complete(ac, inp_cpy, quote);
char *found = autocomplete_complete(ac, prefix, quote);
if (found) {
auto_msg = g_string_new(command_cpy);
g_string_append(auto_msg, found);
@ -278,28 +278,18 @@ autocomplete_param_with_ac(char *input, int *size, char *command,
}
char *
autocomplete_param_no_with_func(char *input, int *size, char *command,
int arg_number, autocomplete_func func)
autocomplete_param_no_with_func(const char * const input, char *command, int arg_number, autocomplete_func func)
{
if (strncmp(input, command, strlen(command)) == 0 && (*size > strlen(command))) {
int i = 0;
if (strncmp(input, command, strlen(command)) == 0 && (strlen(input) > strlen(command))) {
GString *result_str = NULL;
// copy and null terminate input
gchar inp_cpy[*size];
for (i = 0; i < *size; i++) {
inp_cpy[i] = input[i];
}
inp_cpy[i] = '\0';
g_strstrip(inp_cpy);
// count tokens properly
int num_tokens = count_tokens(inp_cpy);
int num_tokens = count_tokens(input);
// if correct number of tokens, then candidate for autocompletion of last param
if (num_tokens == arg_number) {
gchar *start_str = get_start(inp_cpy, arg_number);
gchar *comp_str = g_strdup(&inp_cpy[strlen(start_str)]);
gchar *start_str = get_start(input, arg_number);
gchar *comp_str = g_strdup(&input[strlen(start_str)]);
// autocomplete param
if (comp_str) {

View File

@ -37,7 +37,7 @@
#include <glib.h>
typedef char*(*autocomplete_func)(char *);
typedef char*(*autocomplete_func)(const char * const);
typedef struct autocomplete_t *Autocomplete;
// allocate new autocompleter with no items
@ -53,18 +53,18 @@ void autocomplete_add(Autocomplete ac, const char *item);
void autocomplete_remove(Autocomplete ac, const char * const item);
// find the next item prefixed with search string
gchar * autocomplete_complete(Autocomplete ac, gchar *search_str, gboolean quote);
gchar * autocomplete_complete(Autocomplete ac, const gchar *search_str, gboolean quote);
GSList * autocomplete_create_list(Autocomplete ac);
gint autocomplete_length(Autocomplete ac);
char * autocomplete_param_with_func(char *input, int *size, char *command,
char * autocomplete_param_with_func(const char * const input, char *command,
autocomplete_func func);
char * autocomplete_param_with_ac(char *input, int *size, char *command,
char * autocomplete_param_with_ac(const char * const input, char *command,
Autocomplete ac, gboolean quote);
char * autocomplete_param_no_with_func(char *input, int *size, char *command,
char * autocomplete_param_no_with_func(const char * const input, char *command,
int arg_number, autocomplete_func func);
void autocomplete_reset(Autocomplete ac);

View File

@ -316,7 +316,7 @@ parse_args_with_freetext(const char * const inp, int min, int max, gboolean *res
}
int
count_tokens(char *string)
count_tokens(const char * const string)
{
int length = g_utf8_strlen(string, -1);
gboolean in_quotes = FALSE;
@ -347,7 +347,7 @@ count_tokens(char *string)
}
char *
get_start(char *string, int tokens)
get_start(const char * const string, int tokens)
{
GString *result = g_string_new("");
int length = g_utf8_strlen(string, -1);

View File

@ -39,8 +39,8 @@
gchar** parse_args(const char * const inp, int min, int max, gboolean *result);
gchar** parse_args_with_freetext(const char * const inp, int min, int max, gboolean *result);
int count_tokens(char *string);
char* get_start(char *string, int tokens);
int count_tokens(const char * const string);
char* get_start(const char * const string, int tokens);
GHashTable* parse_options(gchar **args, gchar **keys, gboolean *res);
void options_destroy(GHashTable *options);

View File

@ -204,15 +204,15 @@ ui_readline(void)
}
void
ui_input_clear(void)
ui_inp_history_append(char *inp)
{
inp_win_reset();
inp_history_append(inp);
}
void
ui_replace_input(char *input, const char * const new_input, int *size)
ui_input_clear(void)
{
inp_replace_input(input, new_input, size);
inp_win_reset();
}
void

View File

@ -50,6 +50,7 @@
#include "config/accounts.h"
#include "config/preferences.h"
#include "config/theme.h"
#include "tools/history.h"
#include "log.h"
#include "muc.h"
#include "profanity.h"
@ -72,6 +73,7 @@
#define KEY_CTRL_U 0025
#define KEY_CTRL_W 0027
#define MAX_HISTORY 100
#define INP_WIN_MAX 1000
static WINDOW *inp_win;
@ -79,6 +81,7 @@ static int pad_start = 0;
static int rows, cols;
static char line[INP_WIN_MAX];
static int inp_size;
static History history;
static int _handle_edit(int key_type, const wint_t ch);
static int _handle_alt_key(int key);
@ -103,6 +106,7 @@ create_input_window(void)
keypad(inp_win, TRUE);
wmove(inp_win, 0, 0);
_inp_win_update_virtual();
history = history_new(MAX_HISTORY);
}
void
@ -227,7 +231,7 @@ inp_read(int *key_type, wint_t *ch)
echo();
if (*ch == '\n') {
line[inp_size++] = '\0';
line[inp_size] = '\0';
inp_size = 0;
return strdup(line);
} else {
@ -255,13 +259,13 @@ inp_put_back(void)
}
void
inp_replace_input(char *input, const char * const new_input, int *size)
inp_replace_input(const char * const new_input)
{
strncpy(input, new_input, INP_WIN_MAX);
*size = strlen(input);
strncpy(line, new_input, INP_WIN_MAX);
inp_size = strlen(line);
inp_win_reset();
input[*size] = '\0';
waddstr(inp_win, input);
line[inp_size] = '\0';
waddstr(inp_win, line);
_go_to_end();
}
@ -273,6 +277,12 @@ inp_win_reset(void)
_inp_win_update_virtual();
}
void
inp_history_append(char *inp)
{
history_append(history, inp);
}
static void
_clear_input(void)
{
@ -497,9 +507,10 @@ _handle_edit(int key_type, const wint_t ch)
return 0;
}
case KEY_CTRL_P:
prev = cmd_history_previous(line, &inp_size);
line[inp_size] = '\0';
prev = history_previous(history, line);
if (prev) {
inp_replace_input(line, prev, &inp_size);
inp_replace_input(prev);
}
return 1;
@ -508,13 +519,14 @@ _handle_edit(int key_type, const wint_t ch)
return 0;
}
case KEY_CTRL_N:
next = cmd_history_next(line, &inp_size);
line[inp_size] = '\0';
next = history_next(history, line);
if (next) {
inp_replace_input(line, next, &inp_size);
inp_replace_input(next);
} else if (inp_size != 0) {
line[inp_size] = '\0';
cmd_history_append(line);
inp_replace_input(line, "", &inp_size);
history_append(history, line);
inp_replace_input("");
}
return 1;
@ -538,10 +550,21 @@ _handle_edit(int key_type, const wint_t ch)
case 9: // tab
if (inp_size != 0) {
line[inp_size] = '\0';
if ((strncmp(line, "/", 1) != 0) && (ui_current_win_type() == WIN_MUC)) {
muc_autocomplete(line, &inp_size);
char *result = muc_autocomplete(line);
if (result) {
cons_debug("ac result = %s", result);
inp_replace_input(result);
free(result);
}
} else if (strncmp(line, "/", 1) == 0) {
cmd_autocomplete(line, &inp_size);
char *result = cmd_autocomplete(line);
if (result) {
cons_debug("ac result = %s", result);
inp_replace_input(result);
free(result);
}
}
}
return 1;

View File

@ -43,6 +43,7 @@ void inp_put_back(void);
void inp_non_block(gint);
void inp_block(void);
void inp_get_password(char *passwd);
void inp_replace_input(char *input, const char * const new_input, int *size);
void inp_replace_input(const char * const new_input);
void inp_history_append(char *inp);
#endif

View File

@ -230,7 +230,6 @@ void ui_statusbar_new(const int win);
char * ui_readline(void);
void ui_input_clear(void);
void ui_input_nonblocking(gboolean);
void ui_replace_input(char *input, const char * const new_input, int *size);
void ui_invalid_command_usage(const char * const usage, void (*setting_func)(void));
@ -240,6 +239,8 @@ void ui_open_xmlconsole_win(void);
gboolean ui_win_has_unsaved_form(int num);
void ui_inp_history_append(char *inp);
// console window actions
void cons_show(const char * const msg, ...);
void cons_about(void);

View File

@ -220,7 +220,7 @@ bookmark_get_list(void)
}
char *
bookmark_find(char *search_str)
bookmark_find(const char * const search_str)
{
return autocomplete_complete(bookmark_ac, search_str, TRUE);
}

View File

@ -158,7 +158,7 @@ presence_clear_sub_requests(void)
}
char *
presence_sub_request_find(char * search_str)
presence_sub_request_find(const char * const search_str)
{
return autocomplete_complete(sub_requests_ac, search_str, TRUE);
}

View File

@ -163,7 +163,7 @@ void presence_subscription(const char * const jid, const jabber_subscr_t action)
GSList* presence_get_subscription_requests(void);
gint presence_sub_request_count(void);
void presence_reset_sub_request_search(void);
char * presence_sub_request_find(char * search_str);
char * presence_sub_request_find(const char * const search_str);
void presence_join_room(char *room, char *nick, char * passwd);
void presence_change_room_nick(const char * const room, const char * const nick);
void presence_leave_chat_room(const char * const room_jid);
@ -208,7 +208,7 @@ gboolean bookmark_update(const char *jid, const char *nick, const char *password
gboolean bookmark_remove(const char *jid);
gboolean bookmark_join(const char *jid);
const GList * bookmark_get_list(void);
char * bookmark_find(char *search_str);
char * bookmark_find(const char * const search_str);
void bookmark_autocomplete_reset(void);
void roster_send_name_change(const char * const barejid, const char * const new_name, GSList *groups);

View File

@ -328,9 +328,10 @@ char * ui_readline(void)
return NULL;
}
void ui_inp_history_append(char *inp) {}
void ui_input_clear(void) {}
void ui_input_nonblocking(gboolean reset) {}
void ui_replace_input(char *input, const char * const new_input, int *size) {}
void ui_invalid_command_usage(const char * const usage, void (*setting_func)(void)) {}

View File

@ -91,7 +91,7 @@ gint presence_sub_request_count(void)
void presence_reset_sub_request_search(void) {}
char * presence_sub_request_find(char * search_str)
char * presence_sub_request_find(const char * const search_str)
{
return NULL;
}
@ -189,7 +189,7 @@ const GList * bookmark_get_list(void)
return (GList *)mock();
}
char * bookmark_find(char *search_str)
char * bookmark_find(const char * const search_str)
{
return NULL;
}