reasonable prototype
This commit is contained in:
6
Makefile
6
Makefile
@ -2,7 +2,6 @@
|
||||
|
||||
ifeq (${DEBUG}, 1)
|
||||
LFLAGS += --debug --trace
|
||||
CXXFLAGS += -Wall -Wextra -Wpedantic
|
||||
CXXFLAGS += -DDEBUG -O0 -ggdb -fno-inline
|
||||
WRAP := valgrind --track-origins=yes --leak-check=full --show-leak-kinds=all
|
||||
else
|
||||
@ -11,6 +10,7 @@ endif
|
||||
|
||||
LIBFLAGS := $$(pkgconf --cflags ncurses readline sqlite3)
|
||||
CXXFLAGS += -std=gnu++20 -I./source/ -I./object/ -I./ ${LIBFLAGS}
|
||||
CXXFLAGS += -Wall -Wextra -Wpedantic
|
||||
LINKasd += $$(pkgconf --libs ncurses readline sqlite3)
|
||||
|
||||
OBJECT.d:=object/
|
||||
@ -37,5 +37,5 @@ clean:
|
||||
-rm ${OBJECT.d}/*
|
||||
-rm ./${OUTPUT}
|
||||
|
||||
run:
|
||||
./${OUTPUT}
|
||||
test:
|
||||
${WRAP} ./${OUTPUT}
|
||||
|
@ -71,7 +71,7 @@ damerau_levenshtein_(
|
||||
void
|
||||
damerau_levenshtein(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
[[maybe_unused]] int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
|
||||
@ -92,7 +92,7 @@ damerau_levenshtein(
|
||||
void
|
||||
is_damerau_levenshtein(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
[[maybe_unused]] int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
|
||||
|
6
source/entry.h
Normal file
6
source/entry.h
Normal file
@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
typedef struct {
|
||||
int timestamp;
|
||||
char * command;
|
||||
} entry_t;
|
@ -1,11 +1,10 @@
|
||||
#include <locale.h>
|
||||
#include "storage.hpp"
|
||||
#include "tui.hpp"
|
||||
#include "bash_history.yy.hpp"
|
||||
|
||||
// XXX
|
||||
#include <sqlite3.h>
|
||||
|
||||
void init() {
|
||||
setlocale(LC_TIME, "C");
|
||||
init_storage();
|
||||
init_tui();
|
||||
}
|
||||
@ -16,9 +15,6 @@ void deinit() {
|
||||
}
|
||||
|
||||
signed main(int argc, char * argv[]) {
|
||||
// XXX
|
||||
extern sqlite3 * db;
|
||||
extern sqlite3_stmt * stmt;
|
||||
// TODO cli stuff
|
||||
|
||||
init();
|
||||
@ -26,13 +22,15 @@ signed main(int argc, char * argv[]) {
|
||||
bash_history_in = fopen("/home/anon/stow/.cache/.bash_history", "r");
|
||||
bash_history_lex();
|
||||
|
||||
// XXX
|
||||
tui_refresh();
|
||||
|
||||
entry_t entry;
|
||||
while (true) {
|
||||
sqlite3_prepare_v2(db, "SELECT * FROM test WHERE DAMERAU_LEVENSHTEIN(data, 'a');", -1, &stmt, 0);
|
||||
while (sqlite3_step(stmt) == SQLITE_ROW) {
|
||||
tui_append_back(sqlite3_column_int(stmt, 0), sqlite3_column_text(stmt, 1));
|
||||
query(rl_line_buffer);
|
||||
while (entry = get_entry(), entry.command != NULL) {
|
||||
tui_append_back(entry);
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
tui_take_input();
|
||||
tui_refresh();
|
||||
}
|
||||
|
||||
|
@ -2,11 +2,10 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <sqlite3.h>
|
||||
//#include "damerau_levenshtein.h"
|
||||
#include "damerau_levenshtein2.h"
|
||||
#include "damerau_levenshtein.hpp"
|
||||
|
||||
sqlite3 * db;
|
||||
sqlite3_stmt * stmt;
|
||||
static sqlite3 * db;
|
||||
static sqlite3_stmt * stmt;
|
||||
|
||||
int init_storage(void) {
|
||||
sqlite3_open(":memory:", &db);
|
||||
@ -20,6 +19,7 @@ int init_storage(void) {
|
||||
}
|
||||
|
||||
int deinit_storage(void) {
|
||||
sqlite3_finalize(stmt);
|
||||
sqlite3_close(db);
|
||||
return 0;
|
||||
}
|
||||
@ -35,3 +35,22 @@ int insert_entry(int timestamp, const char * const command) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void query(const char * const string) {
|
||||
sqlite3_prepare_v2(db, "SELECT * FROM test ORDER BY DAMERAU_LEVENSHTEIN(data, ?) LIMIT 40;", -1, &stmt, 0);
|
||||
sqlite3_bind_text(stmt, 1, string, -1, SQLITE_TRANSIENT);
|
||||
}
|
||||
|
||||
entry_t get_entry(void) {
|
||||
if (sqlite3_step(stmt) != SQLITE_ROW) {
|
||||
sqlite3_finalize(stmt);
|
||||
return (entry_t){
|
||||
.timestamp = 0,
|
||||
.command = NULL
|
||||
};
|
||||
}
|
||||
return (entry_t){
|
||||
.timestamp = sqlite3_column_int(stmt, 0),
|
||||
.command = (char*)sqlite3_column_text(stmt, 1)
|
||||
};
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
#pragma once
|
||||
#include "entry.h"
|
||||
|
||||
int init_storage(void);
|
||||
int deinit_storage(void);
|
||||
|
||||
int insert_entry(int timestamp, const char * const command);
|
||||
void query(const char * const string);
|
||||
entry_t get_entry(void);
|
||||
|
@ -1,16 +1,60 @@
|
||||
#include "tui.hpp"
|
||||
|
||||
#include <time.h>
|
||||
#include <locale.h>
|
||||
#include <ncurses.h>
|
||||
#include <readline/readline.h>
|
||||
|
||||
WINDOW * main_window;
|
||||
WINDOW * input_window;
|
||||
// XXX
|
||||
#include <cstdlib>
|
||||
|
||||
static WINDOW * main_window;
|
||||
static WINDOW * entry_window;
|
||||
static WINDOW * input_window;
|
||||
|
||||
static int input_available = false;
|
||||
static char input;
|
||||
|
||||
static void refresh_input(void);
|
||||
|
||||
int init_tui(void) {
|
||||
// Ncurses
|
||||
initscr();
|
||||
noecho();
|
||||
curs_set(0);
|
||||
main_window = newwin(COLS-1, LINES, 0, 0);
|
||||
|
||||
main_window = newwin(LINES-1, COLS, 0, 0);
|
||||
entry_window = subwin(main_window, LINES-3, COLS-2, 1, 1);
|
||||
input_window = newwin(1, COLS, LINES-1, 0);
|
||||
refresh();
|
||||
|
||||
box(main_window, 0, 0);
|
||||
|
||||
// Readline
|
||||
rl_bind_key('\t', rl_insert);
|
||||
rl_catch_signals = 0;
|
||||
rl_catch_sigwinch = 0;
|
||||
rl_prep_term_function = NULL;
|
||||
rl_deprep_term_function = NULL;
|
||||
rl_change_environment = 0;
|
||||
|
||||
rl_getc_function = []([[maybe_unused]] FILE* ignore){
|
||||
input_available = false;
|
||||
return (int)input;
|
||||
};
|
||||
rl_input_available_hook = []{
|
||||
return input_available;
|
||||
};
|
||||
rl_redisplay_function = refresh_input;
|
||||
/* We must specify an input handler or readline chimps out,
|
||||
* but we dont want the line to be actually submittable,
|
||||
* (search is continous and that would delete what the user
|
||||
* has typedso far)
|
||||
* so we also override enter to do nothing.
|
||||
*/
|
||||
rl_callback_handler_install("", []([[maybe_unused]] char *line){ ; });
|
||||
rl_bind_key('\n', []([[maybe_unused]] int i, [[maybe_unused]] int h){ return 0; });
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -19,11 +63,37 @@ int deinit_tui(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tui_append_back(int timestamp, const unsigned char * const text) {
|
||||
mvprintw(1, 1, "%d, %s\n", timestamp, text);
|
||||
void tui_append_back(const entry_t entry) {
|
||||
struct tm *tm_info = localtime((time_t*)&entry.timestamp);
|
||||
const int TIME_BUFFER_SIZE = 30;
|
||||
char time_buffer[TIME_BUFFER_SIZE];
|
||||
strftime(time_buffer, TIME_BUFFER_SIZE, "%Y-%m-%d %H:%M:%S", tm_info);
|
||||
|
||||
wprintw(entry_window, "%s %s\n",
|
||||
time_buffer,
|
||||
entry.command
|
||||
);
|
||||
}
|
||||
|
||||
static void refresh_input(void) {
|
||||
wmove(input_window, 0, 0);
|
||||
wclrtoeol(input_window);
|
||||
waddstr(input_window, "$ ");
|
||||
waddstr(input_window, rl_line_buffer);
|
||||
waddch(input_window, ACS_BLOCK);
|
||||
wrefresh(input_window);
|
||||
}
|
||||
|
||||
void tui_refresh(void) {
|
||||
wmove(entry_window, 0, 0);
|
||||
wrefresh(entry_window);
|
||||
wrefresh(main_window);
|
||||
refresh();
|
||||
refresh_input();
|
||||
}
|
||||
|
||||
|
||||
void tui_take_input(void) {
|
||||
input = wgetch(stdscr);
|
||||
input_available = true;
|
||||
rl_callback_read_char();
|
||||
}
|
||||
|
@ -1,7 +1,11 @@
|
||||
#pragma once
|
||||
#include "entry.h"
|
||||
|
||||
extern "C" char * rl_line_buffer;
|
||||
|
||||
int init_tui(void);
|
||||
int deinit_tui(void);
|
||||
void tui_refresh(void);
|
||||
void tui_take_input(void);
|
||||
|
||||
void tui_append_back(int timestamp, const unsigned char * const text);
|
||||
void tui_append_back(const entry_t entry);
|
||||
|
Reference in New Issue
Block a user