mirror of
https://github.com/profanity-im/profanity.git
synced 2024-12-04 14:46:46 -05:00
Bash style history
This commit is contained in:
parent
4531aebd29
commit
1730372e00
7
Makefile
7
Makefile
@ -8,7 +8,7 @@ CFLAGS = -I ~/include -O3 $(WARNS) $(LIBS) `pkg-config --cflags glib-2.0`
|
||||
OBJS = log.o windows.o title_bar.o status_bar.o input_win.o jabber.o \
|
||||
profanity.o util.o command.o history.o contact_list.o prof_history.o \
|
||||
main.o
|
||||
TESTOBJS = test_history.o history.o test_contact_list.o contact_list.o \
|
||||
TESTOBJS = test_contact_list.o contact_list.o \
|
||||
test_util.o test_prof_history.o prof_history.o util.o
|
||||
|
||||
profanity: $(OBJS)
|
||||
@ -20,15 +20,14 @@ title_bar.o: windows.h
|
||||
status_bar.o: windows.h util.h
|
||||
input_win.o: windows.h
|
||||
jabber.o: jabber.h log.h windows.h contact_list.h
|
||||
profanity.o: log.h windows.h jabber.h command.h history.h
|
||||
profanity.o: log.h windows.h jabber.h command.h
|
||||
util.o: util.h
|
||||
command.o: command.h util.h history.h contact_list.h
|
||||
history.o: history.h
|
||||
history.o: history.h prof_history.h
|
||||
contact_list.o: contact_list.h
|
||||
prof_history.o: prof_history.h
|
||||
main.o: profanity.h
|
||||
|
||||
test_history.o: history.h
|
||||
test_contact_list.o: contact_list.h
|
||||
test_util.o: util.h
|
||||
test_prof_history.o: prof_history.h
|
||||
|
@ -72,6 +72,11 @@ gboolean process_input(char *inp)
|
||||
return result;
|
||||
}
|
||||
|
||||
void command_init(void)
|
||||
{
|
||||
history_init();
|
||||
}
|
||||
|
||||
static gboolean _handle_command(const char * const command, const char * const inp)
|
||||
{
|
||||
gboolean result = FALSE;
|
||||
|
@ -23,7 +23,7 @@
|
||||
#ifndef COMMAND_H
|
||||
#define COMMAND_H
|
||||
|
||||
void cmd_init(void);
|
||||
void command_init(void);
|
||||
gboolean process_input(char *inp);
|
||||
|
||||
#endif
|
||||
|
64
history.c
64
history.c
@ -23,53 +23,43 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "prof_history.h"
|
||||
|
||||
#define MAX_HISTORY 100
|
||||
|
||||
static char *_history[MAX_HISTORY];
|
||||
static int _size;
|
||||
static int _pos;
|
||||
static PHistory history;
|
||||
|
||||
void history_init(void)
|
||||
{
|
||||
history = p_history_new(MAX_HISTORY);
|
||||
}
|
||||
|
||||
void history_append(char *inp)
|
||||
{
|
||||
p_history_append(history, inp);
|
||||
}
|
||||
|
||||
char * history_previous(char *inp, int *size)
|
||||
{
|
||||
char inp_str[*size + 1];
|
||||
int i;
|
||||
for (i = 0; i < _size; i++)
|
||||
free(_history[i]);
|
||||
|
||||
_size = 0;
|
||||
_pos = -1;
|
||||
}
|
||||
|
||||
// FIXME: Roll history when full
|
||||
void history_append(const char * const inp)
|
||||
{
|
||||
if (_size < MAX_HISTORY) {
|
||||
_history[_size] = (char*) malloc((strlen(inp) + 1) * sizeof(char));
|
||||
strcpy(_history[_size], inp);
|
||||
_pos = _size;
|
||||
_size++;
|
||||
for (i = 0; i < *size; i++) {
|
||||
inp_str[i] = inp[i];
|
||||
}
|
||||
inp_str[*size] = '\0';
|
||||
|
||||
return p_history_previous(history, inp_str);
|
||||
}
|
||||
|
||||
char *history_previous(void)
|
||||
char *history_next(char *inp, int *size)
|
||||
{
|
||||
if (_size == 0 || _pos == -1)
|
||||
return NULL;
|
||||
char inp_str[*size + 1];
|
||||
int i;
|
||||
for (i = 0; i < *size; i++) {
|
||||
inp_str[i] = inp[i];
|
||||
}
|
||||
inp_str[*size] = '\0';
|
||||
|
||||
return _history[_pos--];
|
||||
}
|
||||
|
||||
char *history_next(void)
|
||||
{
|
||||
if (_size == 0)
|
||||
return NULL;
|
||||
if (_pos == (_size - 1))
|
||||
return NULL;
|
||||
if (_pos + 2 >= _size)
|
||||
return NULL;
|
||||
|
||||
int pos = _pos + 2;
|
||||
_pos++;
|
||||
|
||||
return _history[pos];
|
||||
return p_history_next(history, inp_str);
|
||||
}
|
||||
|
||||
|
@ -25,8 +25,8 @@
|
||||
#define HISTORY_H
|
||||
|
||||
void history_init(void);
|
||||
void history_append(const char * const inp);
|
||||
char *history_previous(void);
|
||||
char *history_next(void);
|
||||
void history_append(char *inp);
|
||||
char *history_previous(char *inp, int *size);
|
||||
char *history_next(char *inp, int *size);
|
||||
|
||||
#endif
|
||||
|
@ -210,13 +210,13 @@ static int _handle_edit(const int ch, char *input, int *size)
|
||||
return 1;
|
||||
|
||||
case KEY_UP:
|
||||
prev = history_previous();
|
||||
prev = history_previous(input, size);
|
||||
if (prev)
|
||||
_replace_input(input, prev, size);
|
||||
return 1;
|
||||
|
||||
case KEY_DOWN:
|
||||
next = history_next();
|
||||
next = history_next(input, size);
|
||||
if (next)
|
||||
_replace_input(input, next, size);
|
||||
return 1;
|
||||
|
@ -62,26 +62,19 @@ void p_history_append(PHistory history, char *item)
|
||||
} else {
|
||||
|
||||
// if adding a new item, copy the session over the history
|
||||
if ((history->sess_new != NULL) &&
|
||||
(history->sess_curr == history->sess_new)) {
|
||||
if (history->sess_curr == history->sess_new) {
|
||||
history->sess_curr->data = copied;
|
||||
_replace_history_with_session(history);
|
||||
|
||||
// otherwise, adding edited history item
|
||||
} else {
|
||||
|
||||
// discard the new item if there was one
|
||||
if (history->sess_new != NULL) {
|
||||
history->session = g_list_reverse(history->session);
|
||||
GList *first = g_list_first(history->session);
|
||||
char *first_item = first->data;
|
||||
history->session = g_list_remove(history->session, first_item);
|
||||
history->session = g_list_reverse(history->session);
|
||||
// copy the current string to the last element in session
|
||||
history->sess_new->data = copied;
|
||||
} else {
|
||||
g_list_append(history->session, copied);
|
||||
}
|
||||
|
||||
// copy sess_curr to the end of the session
|
||||
char *new_data = strdup(history->sess_curr->data);
|
||||
history->session = g_list_append(history->session, new_data);
|
||||
|
||||
|
||||
// replace the edited version with the data from the history
|
||||
history->sess_curr->data = strdup(history->items_curr->data);
|
||||
|
||||
@ -114,7 +107,7 @@ char * p_history_previous(PHistory history, char *item)
|
||||
{
|
||||
// no history
|
||||
if (history->items == NULL) {
|
||||
return item;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *copied = "";
|
||||
@ -160,7 +153,7 @@ char * p_history_next(PHistory history, char *item)
|
||||
|
||||
// no history, or no session, return item
|
||||
if ((history->items == NULL) || (history->session == NULL)) {
|
||||
return item;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *copied = "";
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include "windows.h"
|
||||
#include "jabber.h"
|
||||
#include "command.h"
|
||||
#include "history.h"
|
||||
|
||||
static void _profanity_shutdown(void);
|
||||
|
||||
@ -67,7 +66,7 @@ void profanity_init(const int disable_tls)
|
||||
log_init();
|
||||
gui_init();
|
||||
jabber_init(disable_tls);
|
||||
history_init();
|
||||
command_init();
|
||||
atexit(_profanity_shutdown);
|
||||
}
|
||||
|
||||
|
130
test_history.c
130
test_history.c
@ -1,130 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <head-unit.h>
|
||||
#include "history.h"
|
||||
|
||||
static void beforetest(void)
|
||||
{
|
||||
history_init();
|
||||
}
|
||||
|
||||
static void previous_returns_null_after_init(void)
|
||||
{
|
||||
char *prev = history_previous();
|
||||
assert_is_null(prev);
|
||||
}
|
||||
|
||||
static void next_returns_null_after_init(void)
|
||||
{
|
||||
char *next = history_next();
|
||||
assert_is_null(next);
|
||||
}
|
||||
|
||||
static void append_after_init_doesnt_fail(void)
|
||||
{
|
||||
history_append("try append");
|
||||
assert_true(1);
|
||||
}
|
||||
|
||||
static void append_then_previous_returns_appended(void)
|
||||
{
|
||||
history_append("try append");
|
||||
char *prev = history_previous();
|
||||
assert_string_equals("try append", prev);
|
||||
}
|
||||
|
||||
static void append_then_next_returns_null(void)
|
||||
{
|
||||
history_append("try append");
|
||||
char *next = history_next();
|
||||
assert_is_null(next);
|
||||
}
|
||||
|
||||
static void hits_null_at_top(void)
|
||||
{
|
||||
history_append("cmd1");
|
||||
history_append("cmd2");
|
||||
history_previous(); // cmd2
|
||||
history_previous(); // cmd1
|
||||
char *prev = history_previous();
|
||||
assert_is_null(prev);
|
||||
}
|
||||
|
||||
static void navigate_to_correct_item(void)
|
||||
{
|
||||
history_append("cmd1");
|
||||
history_append("cmd2");
|
||||
history_append("cmd3");
|
||||
history_append("cmd4");
|
||||
history_append("cmd5");
|
||||
history_append("cmd6");
|
||||
|
||||
history_previous(); // cmd6
|
||||
history_previous(); // cmd5
|
||||
history_previous(); // cmd4
|
||||
history_previous(); // cmd3
|
||||
history_next(); // cmd4
|
||||
history_previous(); // cmd3
|
||||
history_previous(); // cmd2
|
||||
char *str = history_next(); // cmd3
|
||||
|
||||
assert_string_equals("cmd3", str);
|
||||
}
|
||||
|
||||
static void append_previous_item(void)
|
||||
{
|
||||
history_append("cmd1");
|
||||
history_append("cmd2");
|
||||
history_append("cmd3");
|
||||
history_append("cmd4");
|
||||
history_append("cmd5");
|
||||
history_append("cmd6");
|
||||
|
||||
history_previous(); // cmd6
|
||||
history_previous(); // cmd5
|
||||
history_previous(); // cmd4
|
||||
history_previous(); // cmd3
|
||||
history_next(); // cmd4
|
||||
history_previous(); // cmd3
|
||||
history_previous(); // cmd2
|
||||
char *str = history_next(); // cmd3
|
||||
|
||||
history_append(str);
|
||||
|
||||
char *cmd3_1 = history_previous();
|
||||
assert_string_equals("cmd3", cmd3_1);
|
||||
|
||||
char *cmd6 = history_previous();
|
||||
assert_string_equals("cmd6", cmd6);
|
||||
|
||||
char *cmd5 = history_previous();
|
||||
assert_string_equals("cmd5", cmd5);
|
||||
|
||||
char *cmd4 = history_previous();
|
||||
assert_string_equals("cmd4", cmd4);
|
||||
|
||||
char *cmd3 = history_previous();
|
||||
assert_string_equals("cmd3", cmd3);
|
||||
|
||||
char *cmd2 = history_previous();
|
||||
assert_string_equals("cmd2", cmd2);
|
||||
|
||||
char *cmd1 = history_previous();
|
||||
assert_string_equals("cmd1", cmd1);
|
||||
|
||||
char *end = history_previous();
|
||||
assert_is_null(end);
|
||||
}
|
||||
|
||||
void register_history_tests(void)
|
||||
{
|
||||
TEST_MODULE("history tests");
|
||||
BEFORETEST(beforetest);
|
||||
TEST(previous_returns_null_after_init);
|
||||
TEST(next_returns_null_after_init);
|
||||
TEST(append_after_init_doesnt_fail);
|
||||
TEST(append_then_previous_returns_appended);
|
||||
TEST(append_then_next_returns_null);
|
||||
TEST(hits_null_at_top);
|
||||
TEST(navigate_to_correct_item);
|
||||
TEST(append_previous_item);
|
||||
}
|
@ -2,20 +2,20 @@
|
||||
#include <head-unit.h>
|
||||
#include "prof_history.h"
|
||||
|
||||
void previous_on_empty_returns_current(void)
|
||||
void previous_on_empty_returns_null(void)
|
||||
{
|
||||
PHistory history = p_history_new(10);
|
||||
char *item = p_history_previous(history, "inp");
|
||||
|
||||
assert_string_equals("inp", item);
|
||||
assert_is_null(item);
|
||||
}
|
||||
|
||||
void next_on_empty_returns_current(void)
|
||||
void next_on_empty_returns_null(void)
|
||||
{
|
||||
PHistory history = p_history_new(10);
|
||||
char *item = p_history_next(history, "inp");
|
||||
|
||||
assert_string_equals("inp", item);
|
||||
assert_is_null(item);
|
||||
}
|
||||
|
||||
void previous_once_returns_last(void)
|
||||
@ -105,11 +105,103 @@ void prev_with_val_then_next_twice_returns_val(void)
|
||||
assert_string_equals("Oioi", item3);
|
||||
}
|
||||
|
||||
void navigate_then_append_new(void)
|
||||
{
|
||||
PHistory history = p_history_new(10);
|
||||
p_history_append(history, "Hello");
|
||||
p_history_append(history, "again");
|
||||
p_history_append(history, "testing");
|
||||
p_history_append(history, "history");
|
||||
p_history_append(history, "append");
|
||||
|
||||
char *item1 = p_history_previous(history, "new text");
|
||||
assert_string_equals("append", item1);
|
||||
|
||||
char *item2 = p_history_previous(history, item1);
|
||||
assert_string_equals("history", item2);
|
||||
|
||||
char *item3 = p_history_previous(history, item2);
|
||||
assert_string_equals("testing", item3);
|
||||
|
||||
char *item4 = p_history_next(history, item3);
|
||||
assert_string_equals("history", item4);
|
||||
|
||||
char *item5 = p_history_next(history, item4);
|
||||
assert_string_equals("append", item5);
|
||||
|
||||
char *item6 = p_history_next(history, item5);
|
||||
assert_string_equals("new text", item6);
|
||||
}
|
||||
|
||||
void edit_item_mid_history(void)
|
||||
{
|
||||
PHistory history = p_history_new(10);
|
||||
p_history_append(history, "Hello");
|
||||
p_history_append(history, "again");
|
||||
p_history_append(history, "testing");
|
||||
p_history_append(history, "history");
|
||||
p_history_append(history, "append");
|
||||
|
||||
char *item1 = p_history_previous(history, "new item");
|
||||
assert_string_equals("append", item1);
|
||||
|
||||
char *item2 = p_history_previous(history, item1);
|
||||
assert_string_equals("history", item2);
|
||||
|
||||
char *item3 = p_history_previous(history, item2);
|
||||
assert_string_equals("testing", item3);
|
||||
|
||||
char *item4 = p_history_previous(history, "EDITED");
|
||||
assert_string_equals("again", item4);
|
||||
|
||||
char *item5 = p_history_previous(history, item4);
|
||||
assert_string_equals("Hello", item5);
|
||||
|
||||
char *item6 = p_history_next(history, item5);
|
||||
assert_string_equals("again", item6);
|
||||
|
||||
char *item7 = p_history_next(history, item6);
|
||||
assert_string_equals("EDITED", item7);
|
||||
|
||||
char *item8 = p_history_next(history, item7);
|
||||
assert_string_equals("history", item8);
|
||||
|
||||
char *item9 = p_history_next(history, item8);
|
||||
assert_string_equals("append", item9);
|
||||
|
||||
char *item10 = p_history_next(history, item9);
|
||||
assert_string_equals("new item", item10);
|
||||
}
|
||||
|
||||
void edit_previous_and_append(void)
|
||||
{
|
||||
PHistory history = p_history_new(10);
|
||||
p_history_append(history, "Hello");
|
||||
p_history_append(history, "again");
|
||||
p_history_append(history, "testing");
|
||||
p_history_append(history, "history");
|
||||
p_history_append(history, "append");
|
||||
|
||||
char *item1 = p_history_previous(history, "new item");
|
||||
assert_string_equals("append", item1);
|
||||
|
||||
char *item2 = p_history_previous(history, item1);
|
||||
assert_string_equals("history", item2);
|
||||
|
||||
char *item3 = p_history_previous(history, item2);
|
||||
assert_string_equals("testing", item3);
|
||||
|
||||
p_history_append(history, "EDITED");
|
||||
|
||||
char *item4 = p_history_previous(history, NULL);
|
||||
assert_string_equals("EDITED", item4);
|
||||
}
|
||||
|
||||
void register_prof_history_tests(void)
|
||||
{
|
||||
TEST_MODULE("prof_history tests");
|
||||
TEST(previous_on_empty_returns_current);
|
||||
TEST(next_on_empty_returns_current);
|
||||
TEST(previous_on_empty_returns_null);
|
||||
TEST(next_on_empty_returns_null);
|
||||
TEST(previous_once_returns_last);
|
||||
TEST(previous_twice_when_one_returns_first);
|
||||
TEST(previous_always_stops_at_first);
|
||||
@ -117,4 +209,7 @@ void register_prof_history_tests(void)
|
||||
TEST(prev_then_next_returns_empty);
|
||||
TEST(prev_with_val_then_next_returns_val);
|
||||
TEST(prev_with_val_then_next_twice_returns_val);
|
||||
TEST(navigate_then_append_new);
|
||||
TEST(edit_item_mid_history);
|
||||
TEST(edit_previous_and_append);
|
||||
}
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
int main(void)
|
||||
{
|
||||
register_history_tests();
|
||||
register_prof_history_tests();
|
||||
register_contact_list_tests();
|
||||
register_util_tests();
|
||||
|
@ -1,7 +1,6 @@
|
||||
#ifndef TESTSUITE_H
|
||||
#define TESTSUITE_H
|
||||
|
||||
void register_history_tests(void);
|
||||
void register_prof_history_tests(void);
|
||||
void register_contact_list_tests(void);
|
||||
void register_util_tests(void);
|
||||
|
Loading…
Reference in New Issue
Block a user