1
0
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:
James Booth 2012-05-01 00:24:31 +01:00
parent 4531aebd29
commit 1730372e00
12 changed files with 152 additions and 203 deletions

View File

@ -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 \ 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 \ profanity.o util.o command.o history.o contact_list.o prof_history.o \
main.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 test_util.o test_prof_history.o prof_history.o util.o
profanity: $(OBJS) profanity: $(OBJS)
@ -20,15 +20,14 @@ title_bar.o: windows.h
status_bar.o: windows.h util.h status_bar.o: windows.h util.h
input_win.o: windows.h input_win.o: windows.h
jabber.o: jabber.h log.h windows.h contact_list.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 util.o: util.h
command.o: command.h util.h history.h contact_list.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 contact_list.o: contact_list.h
prof_history.o: prof_history.h prof_history.o: prof_history.h
main.o: profanity.h main.o: profanity.h
test_history.o: history.h
test_contact_list.o: contact_list.h test_contact_list.o: contact_list.h
test_util.o: util.h test_util.o: util.h
test_prof_history.o: prof_history.h test_prof_history.o: prof_history.h

View File

@ -72,6 +72,11 @@ gboolean process_input(char *inp)
return result; return result;
} }
void command_init(void)
{
history_init();
}
static gboolean _handle_command(const char * const command, const char * const inp) static gboolean _handle_command(const char * const command, const char * const inp)
{ {
gboolean result = FALSE; gboolean result = FALSE;

View File

@ -23,7 +23,7 @@
#ifndef COMMAND_H #ifndef COMMAND_H
#define COMMAND_H #define COMMAND_H
void cmd_init(void); void command_init(void);
gboolean process_input(char *inp); gboolean process_input(char *inp);
#endif #endif

View File

@ -23,53 +23,43 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "prof_history.h"
#define MAX_HISTORY 100 #define MAX_HISTORY 100
static char *_history[MAX_HISTORY]; static PHistory history;
static int _size;
static int _pos;
void history_init(void) 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; int i;
for (i = 0; i < _size; i++) for (i = 0; i < *size; i++) {
free(_history[i]); inp_str[i] = inp[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++;
} }
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) char inp_str[*size + 1];
return NULL; int i;
for (i = 0; i < *size; i++) {
inp_str[i] = inp[i];
}
inp_str[*size] = '\0';
return _history[_pos--]; return p_history_next(history, inp_str);
}
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];
} }

View File

@ -25,8 +25,8 @@
#define HISTORY_H #define HISTORY_H
void history_init(void); void history_init(void);
void history_append(const char * const inp); void history_append(char *inp);
char *history_previous(void); char *history_previous(char *inp, int *size);
char *history_next(void); char *history_next(char *inp, int *size);
#endif #endif

View File

@ -210,13 +210,13 @@ static int _handle_edit(const int ch, char *input, int *size)
return 1; return 1;
case KEY_UP: case KEY_UP:
prev = history_previous(); prev = history_previous(input, size);
if (prev) if (prev)
_replace_input(input, prev, size); _replace_input(input, prev, size);
return 1; return 1;
case KEY_DOWN: case KEY_DOWN:
next = history_next(); next = history_next(input, size);
if (next) if (next)
_replace_input(input, next, size); _replace_input(input, next, size);
return 1; return 1;

View File

@ -62,26 +62,19 @@ void p_history_append(PHistory history, char *item)
} else { } else {
// if adding a new item, copy the session over the history // if adding a new item, copy the session over the history
if ((history->sess_new != NULL) && if (history->sess_curr == history->sess_new) {
(history->sess_curr == history->sess_new)) { history->sess_curr->data = copied;
_replace_history_with_session(history); _replace_history_with_session(history);
// otherwise, adding edited history item // otherwise, adding edited history item
} else { } else {
// discard the new item if there was one
if (history->sess_new != NULL) { if (history->sess_new != NULL) {
history->session = g_list_reverse(history->session); // copy the current string to the last element in session
GList *first = g_list_first(history->session); history->sess_new->data = copied;
char *first_item = first->data; } else {
history->session = g_list_remove(history->session, first_item); g_list_append(history->session, copied);
history->session = g_list_reverse(history->session);
} }
// 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 // replace the edited version with the data from the history
history->sess_curr->data = strdup(history->items_curr->data); history->sess_curr->data = strdup(history->items_curr->data);
@ -114,7 +107,7 @@ char * p_history_previous(PHistory history, char *item)
{ {
// no history // no history
if (history->items == NULL) { if (history->items == NULL) {
return item; return NULL;
} }
char *copied = ""; char *copied = "";
@ -160,7 +153,7 @@ char * p_history_next(PHistory history, char *item)
// no history, or no session, return item // no history, or no session, return item
if ((history->items == NULL) || (history->session == NULL)) { if ((history->items == NULL) || (history->session == NULL)) {
return item; return NULL;
} }
char *copied = ""; char *copied = "";

View File

@ -29,7 +29,6 @@
#include "windows.h" #include "windows.h"
#include "jabber.h" #include "jabber.h"
#include "command.h" #include "command.h"
#include "history.h"
static void _profanity_shutdown(void); static void _profanity_shutdown(void);
@ -67,7 +66,7 @@ void profanity_init(const int disable_tls)
log_init(); log_init();
gui_init(); gui_init();
jabber_init(disable_tls); jabber_init(disable_tls);
history_init(); command_init();
atexit(_profanity_shutdown); atexit(_profanity_shutdown);
} }

View File

@ -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);
}

View File

@ -2,20 +2,20 @@
#include <head-unit.h> #include <head-unit.h>
#include "prof_history.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); PHistory history = p_history_new(10);
char *item = p_history_previous(history, "inp"); 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); PHistory history = p_history_new(10);
char *item = p_history_next(history, "inp"); char *item = p_history_next(history, "inp");
assert_string_equals("inp", item); assert_is_null(item);
} }
void previous_once_returns_last(void) 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); 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) void register_prof_history_tests(void)
{ {
TEST_MODULE("prof_history tests"); TEST_MODULE("prof_history tests");
TEST(previous_on_empty_returns_current); TEST(previous_on_empty_returns_null);
TEST(next_on_empty_returns_current); TEST(next_on_empty_returns_null);
TEST(previous_once_returns_last); TEST(previous_once_returns_last);
TEST(previous_twice_when_one_returns_first); TEST(previous_twice_when_one_returns_first);
TEST(previous_always_stops_at_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_then_next_returns_empty);
TEST(prev_with_val_then_next_returns_val); TEST(prev_with_val_then_next_returns_val);
TEST(prev_with_val_then_next_twice_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);
} }

View File

@ -3,7 +3,6 @@
int main(void) int main(void)
{ {
register_history_tests();
register_prof_history_tests(); register_prof_history_tests();
register_contact_list_tests(); register_contact_list_tests();
register_util_tests(); register_util_tests();

View File

@ -1,7 +1,6 @@
#ifndef TESTSUITE_H #ifndef TESTSUITE_H
#define TESTSUITE_H #define TESTSUITE_H
void register_history_tests(void);
void register_prof_history_tests(void); void register_prof_history_tests(void);
void register_contact_list_tests(void); void register_contact_list_tests(void);
void register_util_tests(void); void register_util_tests(void);