testing version
This commit is contained in:
parent
0480db08fa
commit
29accaf24e
28
.gdb_history
28
.gdb_history
@ -11,3 +11,31 @@ p argv[0]
|
|||||||
p * argv[0]
|
p * argv[0]
|
||||||
p (char *)argv[0]
|
p (char *)argv[0]
|
||||||
p argc
|
p argc
|
||||||
|
r
|
||||||
|
where
|
||||||
|
frame 5
|
||||||
|
l
|
||||||
|
r
|
||||||
|
where
|
||||||
|
frame 5
|
||||||
|
r
|
||||||
|
where
|
||||||
|
r
|
||||||
|
where
|
||||||
|
frame 3
|
||||||
|
l
|
||||||
|
frame 2
|
||||||
|
l
|
||||||
|
start
|
||||||
|
l
|
||||||
|
start
|
||||||
|
n
|
||||||
|
n
|
||||||
|
s
|
||||||
|
n
|
||||||
|
where
|
||||||
|
c
|
||||||
|
where
|
||||||
|
frame 1
|
||||||
|
frame 2
|
||||||
|
p stmt
|
||||||
|
5
Makefile
5
Makefile
@ -1,7 +1,6 @@
|
|||||||
.PHONY: clean run
|
.PHONY: clean run
|
||||||
|
|
||||||
ifeq (${DEBUG}, 1)
|
ifeq (${DEBUG}, 1)
|
||||||
LFLAGS += --debug --trace
|
|
||||||
CXXFLAGS += -DDEBUG -O0 -ggdb -fno-inline
|
CXXFLAGS += -DDEBUG -O0 -ggdb -fno-inline
|
||||||
WRAP := valgrind --track-origins=yes --leak-check=full --show-leak-kinds=all
|
WRAP := valgrind --track-origins=yes --leak-check=full --show-leak-kinds=all
|
||||||
else
|
else
|
||||||
@ -15,7 +14,7 @@ LINKasd += $$(pkgconf --libs ncurses readline sqlite3)
|
|||||||
|
|
||||||
OBJECT.d:=object/
|
OBJECT.d:=object/
|
||||||
SOURCE.d:=source/
|
SOURCE.d:=source/
|
||||||
SOURCE:=bash_history.yy.cpp main.cpp tui.cpp storage.cpp damerau_levenshtein.cpp
|
SOURCE:=bash_history.yy.cpp main.cpp cli.cpp tui.cpp storage.cpp damerau_levenshtein.cpp
|
||||||
OBJECT:=$(addprefix ${OBJECT.d},$(addsuffix .o,$(basename ${SOURCE})))
|
OBJECT:=$(addprefix ${OBJECT.d},$(addsuffix .o,$(basename ${SOURCE})))
|
||||||
SOURCE:=$(addprefix ${SOURCE.d},${SOURCE})
|
SOURCE:=$(addprefix ${SOURCE.d},${SOURCE})
|
||||||
|
|
||||||
@ -25,7 +24,7 @@ ${OUTPUT}: ${OBJECT}
|
|||||||
${LINK.cpp} ${OBJECT} ${LINKasd} -o ${OUTPUT}
|
${LINK.cpp} ${OBJECT} ${LINKasd} -o ${OUTPUT}
|
||||||
|
|
||||||
object/%.yy.cpp: source/%.l
|
object/%.yy.cpp: source/%.l
|
||||||
${LEX} ${LFLAGS} --prefix=$*_ --header-file=$(basename $@).hpp -o $@ $<
|
${LEX} --prefix=$*_ --header-file=$(basename $@).hpp -o $@ $<
|
||||||
|
|
||||||
object/%.o: object/%.l.cpp
|
object/%.o: object/%.l.cpp
|
||||||
${COMPILE.cpp} $< -o $@
|
${COMPILE.cpp} $< -o $@
|
||||||
|
@ -2,13 +2,12 @@
|
|||||||
#include "storage.hpp"
|
#include "storage.hpp"
|
||||||
long timestamp;
|
long timestamp;
|
||||||
%}
|
%}
|
||||||
|
%option nodefault
|
||||||
%option noyywrap
|
%option noyywrap
|
||||||
|
%option nounput
|
||||||
%%
|
%%
|
||||||
\#[[:digit:]]+ {
|
\#[[:digit:]]+ { timestamp = strtoll(yytext+1, NULL, 10);
|
||||||
timestamp = strtoll(yytext+1, NULL, 10);
|
|
||||||
}
|
}
|
||||||
[^\#\n].* {
|
.* { insert_entry(timestamp, yytext); }
|
||||||
insert_entry(timestamp, yytext);
|
\n { ; }
|
||||||
}
|
|
||||||
\n { ; }
|
|
||||||
%%
|
%%
|
||||||
|
@ -1,28 +1,40 @@
|
|||||||
|
#include "cli.hpp"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
[[ noreturn ]]
|
[[ noreturn ]]
|
||||||
void version() {
|
void version() {
|
||||||
puts("Histui "
|
puts(
|
||||||
#include "version.inc"
|
# include "version.inc"
|
||||||
);
|
);
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[ noreturn ]]
|
[[ noreturn ]]
|
||||||
void usage(int exit_value = 0) {
|
void usage(int exit_value) {
|
||||||
// TODO
|
// TODO
|
||||||
|
puts(
|
||||||
|
"histui [options] <verb>\n"
|
||||||
|
"\tOptions:\n"
|
||||||
|
"\t\t-v --version\n"
|
||||||
|
"\t\t-h --help\n"
|
||||||
|
"\tVerbs:\n"
|
||||||
|
"\t\tenable : print a bash script to enable histui in the current shell\n"
|
||||||
|
"\t\ttui : run histui normally\n"
|
||||||
|
);
|
||||||
exit(exit_value);
|
exit(exit_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void global_options(const int argc, const char * const * const argv) {
|
void parse_global_options(const int argc, const char * const * const argv) {
|
||||||
for(int i = 0; i < argc; i++) {
|
for(int i = 1; i < argc; i++) {
|
||||||
|
if (argv[i][0] != '-') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (not strcmp(argv[i], "-v")
|
if (not strcmp(argv[i], "-v")
|
||||||
|| not strcmp(argv[i], "--version")) {
|
|| not strcmp(argv[i], "--version")) {
|
||||||
version();
|
version();
|
||||||
@ -34,9 +46,18 @@ void global_options(const int argc, const char * const * const argv) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef signed (*mainlike_t)(int argc, char * * argv);
|
verb_t get_verb(const int argc, const char * const * const argv) {
|
||||||
map<const char*, mainlike_t> verb_table = {
|
for(int i = 1; i < argc; i++) {
|
||||||
{"tui", tui_main},
|
if (argv[i][0] == '-') {
|
||||||
{"import", import_main},
|
continue;
|
||||||
{"export", export_main},
|
}
|
||||||
};
|
if (not strcmp(argv[i], "tui")) {
|
||||||
|
return TUI;
|
||||||
|
}
|
||||||
|
if (not strcmp(argv[i], "enable")) {
|
||||||
|
return ENABLE;
|
||||||
|
}
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
11
source/cli.hpp
Normal file
11
source/cli.hpp
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
TUI,
|
||||||
|
ENABLE,
|
||||||
|
ERROR,
|
||||||
|
} verb_t;
|
||||||
|
|
||||||
|
extern void parse_global_options(const int argc, const char * const * const argv);
|
||||||
|
extern verb_t get_verb(const int argc, const char * const * const argv);
|
||||||
|
[[ noreturn ]] void usage(int exit_value = 0);
|
@ -65,7 +65,7 @@ damerau_levenshtein_(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
function to determine damerau-levenshtein distance
|
sqlite3 wrapper to determine damerau-levenshtein distance
|
||||||
damerau_levenshtein(src,dts) => int
|
damerau_levenshtein(src,dts) => int
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
@ -85,8 +85,28 @@ damerau_levenshtein(
|
|||||||
sqlite3_result_int(context, distance);
|
sqlite3_result_int(context, distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// XXX
|
||||||
|
void
|
||||||
|
damerau_levenshtein_substring(
|
||||||
|
sqlite3_context *context,
|
||||||
|
[[maybe_unused]] int argc,
|
||||||
|
sqlite3_value **argv
|
||||||
|
){
|
||||||
|
|
||||||
|
const char *const s = (const char *)sqlite3_value_text(argv[0]);
|
||||||
|
const char *const t = (const char *)sqlite3_value_text(argv[1]);
|
||||||
|
int n = strlen(s);
|
||||||
|
int m = strlen(t);
|
||||||
|
n = (n < m ? n : m);
|
||||||
|
m = n;
|
||||||
|
|
||||||
|
const int distance = damerau_levenshtein_(n, s, m, t);
|
||||||
|
|
||||||
|
sqlite3_result_int(context, distance);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
function ensure damerau-levenshtein distance
|
sqlite wrapper to ensure damerau-levenshtein distance
|
||||||
damerau_levenshtein(src,dts,max_distance) => bool
|
damerau_levenshtein(src,dts,max_distance) => bool
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
extern void damerau_levenshtein(sqlite3_context *context, int argc, sqlite3_value **argv);
|
extern void damerau_levenshtein(sqlite3_context *context, int argc, sqlite3_value **argv);
|
||||||
extern void is_damerau_levenshtein(sqlite3_context *context, int argc, sqlite3_value **argv);
|
extern void is_damerau_levenshtein(sqlite3_context *context, int argc, sqlite3_value **argv);
|
||||||
|
extern void damerau_levenshtein_substring(sqlite3_context *context, int argc, sqlite3_value **argv);
|
||||||
|
9
source/histui_enable.sh.inc
Normal file
9
source/histui_enable.sh.inc
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
function _histui_run() {
|
||||||
|
COMMANDFILE="${XDG_CACHE_HOME}/histui_command.txt"
|
||||||
|
histui tui 3> "${COMMANDFILE}"
|
||||||
|
READLINE_LINE=$(cat "${COMMANDFILE}")
|
||||||
|
READLINE_POINT=${#READLINE_LINE}
|
||||||
|
}
|
||||||
|
|
||||||
|
bind -x '"\e[A": _histui_run'
|
||||||
|
bind -x '"\C-r": _histui_run'
|
@ -1,39 +1,83 @@
|
|||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
|
#include "cli.hpp"
|
||||||
|
#include "bash_history.yy.hpp"
|
||||||
#include "storage.hpp"
|
#include "storage.hpp"
|
||||||
#include "tui.hpp"
|
#include "tui.hpp"
|
||||||
#include "bash_history.yy.hpp"
|
|
||||||
|
bool do_run = true;
|
||||||
|
|
||||||
void init() {
|
void init() {
|
||||||
setlocale(LC_TIME, "C");
|
setlocale(LC_TIME, "C");
|
||||||
init_storage();
|
init_storage();
|
||||||
|
bash_history_in = fopen("/home/anon/stow/.cache/.bash_history", "r");
|
||||||
|
bash_history_lex();
|
||||||
init_tui();
|
init_tui();
|
||||||
}
|
}
|
||||||
|
|
||||||
void deinit() {
|
void deinit() {
|
||||||
deinit_storage();
|
|
||||||
deinit_tui();
|
deinit_tui();
|
||||||
|
deinit_storage();
|
||||||
|
}
|
||||||
|
|
||||||
|
[[ noreturn ]]
|
||||||
|
void enable() {
|
||||||
|
// XXX one day...
|
||||||
|
/*
|
||||||
|
puts(
|
||||||
|
# embed "histui_enable.sh.inc"
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
puts(
|
||||||
|
R"delim(
|
||||||
|
function _histui_run() {
|
||||||
|
COMMANDFILE="${XDG_CACHE_HOME}/histui_command.txt"
|
||||||
|
histui tui 3> "${COMMANDFILE}"
|
||||||
|
READLINE_LINE=$(cat "${COMMANDFILE}")
|
||||||
|
READLINE_POINT=${#READLINE_LINE}
|
||||||
|
}
|
||||||
|
|
||||||
|
bind -x '"\e[A": _histui_run'
|
||||||
|
bind -x '"\C-r": _histui_run'
|
||||||
|
)delim"
|
||||||
|
);
|
||||||
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
signed main(int argc, char * argv[]) {
|
signed main(int argc, char * argv[]) {
|
||||||
// TODO cli stuff
|
parse_global_options(argc, argv);
|
||||||
|
verb_t verb = get_verb(argc, argv);
|
||||||
|
switch (verb) {
|
||||||
|
case ENABLE: enable();
|
||||||
|
case ERROR: usage(1);
|
||||||
|
case TUI: break;
|
||||||
|
}
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
||||||
bash_history_in = fopen("/home/anon/stow/.cache/.bash_history", "r");
|
|
||||||
bash_history_lex();
|
|
||||||
|
|
||||||
tui_refresh();
|
tui_refresh();
|
||||||
|
|
||||||
entry_t entry;
|
entry_t entry;
|
||||||
while (true) {
|
while (do_run) {
|
||||||
query(rl_line_buffer);
|
if (is_input_changed) {
|
||||||
|
query(rl_line_buffer, entry_lines, selection_offset);
|
||||||
|
is_input_changed = false;
|
||||||
|
} else {
|
||||||
|
requery();
|
||||||
|
}
|
||||||
while (entry = get_entry(), entry.command != NULL) {
|
while (entry = get_entry(), entry.command != NULL) {
|
||||||
tui_append_back(entry);
|
tui_append_back(entry);
|
||||||
}
|
}
|
||||||
tui_take_input();
|
|
||||||
tui_refresh();
|
tui_refresh();
|
||||||
|
tui_take_input();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
query(rl_line_buffer, 1, selection_offset + selection_relative);
|
||||||
|
int fd[2];
|
||||||
|
pipe(fd);
|
||||||
|
dprintf(3, get_entry().command);
|
||||||
|
close(fd[0]);
|
||||||
|
close(fd[1]);
|
||||||
|
|
||||||
deinit();
|
deinit();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -5,14 +5,15 @@
|
|||||||
#include "damerau_levenshtein.hpp"
|
#include "damerau_levenshtein.hpp"
|
||||||
|
|
||||||
static sqlite3 * db;
|
static sqlite3 * db;
|
||||||
static sqlite3_stmt * stmt;
|
static sqlite3_stmt * stmt = NULL;
|
||||||
|
|
||||||
int init_storage(void) {
|
int init_storage(void) {
|
||||||
sqlite3_open(":memory:", &db);
|
sqlite3_open(":memory:", &db);
|
||||||
|
sqlite3_create_function(db, "damerau_levenshtein_substring", 2, SQLITE_ANY, 0, damerau_levenshtein_substring, NULL, NULL);
|
||||||
sqlite3_create_function(db, "is_damerau_levenshtein", 3, SQLITE_ANY, 0, is_damerau_levenshtein, NULL, NULL);
|
sqlite3_create_function(db, "is_damerau_levenshtein", 3, SQLITE_ANY, 0, is_damerau_levenshtein, NULL, NULL);
|
||||||
sqlite3_create_function(db, "damerau_levenshtein", 2, SQLITE_ANY, 0, damerau_levenshtein, NULL, NULL);
|
sqlite3_create_function(db, "damerau_levenshtein", 2, SQLITE_ANY, 0, damerau_levenshtein, NULL, NULL);
|
||||||
|
|
||||||
static const char * sql_create_table = "CREATE TABLE test (stamp INTEGER, data TEXT);";
|
static const char * sql_create_table = "CREATE TABLE entries (stamp INTEGER, data TEXT);";
|
||||||
sqlite3_exec(db, sql_create_table, 0, 0, 0);
|
sqlite3_exec(db, sql_create_table, 0, 0, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -25,7 +26,8 @@ int deinit_storage(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int insert_entry(int timestamp, const char * const command) {
|
int insert_entry(int timestamp, const char * const command) {
|
||||||
static const char * sql_insert = "INSERT INTO test (stamp, data) VALUES (?, ?);";
|
static const char * sql_insert = "INSERT INTO entries (stamp, data) VALUES (?, ?);";
|
||||||
|
sqlite3_stmt * stmt;
|
||||||
sqlite3_prepare_v2(db, sql_insert, -1, &stmt, 0);
|
sqlite3_prepare_v2(db, sql_insert, -1, &stmt, 0);
|
||||||
|
|
||||||
sqlite3_bind_int64(stmt, 1, timestamp);
|
sqlite3_bind_int64(stmt, 1, timestamp);
|
||||||
@ -36,14 +38,36 @@ int insert_entry(int timestamp, const char * const command) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void query(const char * const string) {
|
void query(const char * const string, const size_t limit, const size_t offset) {
|
||||||
sqlite3_prepare_v2(db, "SELECT * FROM test ORDER BY DAMERAU_LEVENSHTEIN(data, ?) LIMIT 40;", -1, &stmt, 0);
|
sqlite3_finalize(stmt);
|
||||||
sqlite3_bind_text(stmt, 1, string, -1, SQLITE_TRANSIENT);
|
const char * sql_query;
|
||||||
|
if (string[0] != '\0') {
|
||||||
|
sql_query = "SELECT * FROM entries "
|
||||||
|
"ORDER BY DAMERAU_LEVENSHTEIN_SUBSTRING(data, ?) "
|
||||||
|
"LIMIT ? "
|
||||||
|
"OFFSET ?;"
|
||||||
|
;
|
||||||
|
sqlite3_prepare_v2(db, sql_query, -1, &stmt, 0);
|
||||||
|
sqlite3_bind_text(stmt, 1, string, -1, SQLITE_TRANSIENT);
|
||||||
|
sqlite3_bind_int64(stmt, 2, (long)limit);
|
||||||
|
sqlite3_bind_int64(stmt, 3, (long)offset);
|
||||||
|
} else {
|
||||||
|
sql_query = "SELECT * FROM entries "
|
||||||
|
"ORDER BY stamp DESC "
|
||||||
|
"LIMIT ? "
|
||||||
|
"OFFSET ?;";
|
||||||
|
sqlite3_prepare_v2(db, sql_query, -1, &stmt, 0);
|
||||||
|
sqlite3_bind_int64(stmt, 1, (long)limit);
|
||||||
|
sqlite3_bind_int64(stmt, 2, (long)offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void requery(void) {
|
||||||
|
sqlite3_reset(stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
entry_t get_entry(void) {
|
entry_t get_entry(void) {
|
||||||
if (sqlite3_step(stmt) != SQLITE_ROW) {
|
if (sqlite3_step(stmt) != SQLITE_ROW) {
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
return (entry_t){
|
return (entry_t){
|
||||||
.timestamp = 0,
|
.timestamp = 0,
|
||||||
.command = NULL
|
.command = NULL
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <stddef.h>
|
||||||
#include "entry.h"
|
#include "entry.h"
|
||||||
|
|
||||||
int init_storage(void);
|
int init_storage(void);
|
||||||
int deinit_storage(void);
|
int deinit_storage(void);
|
||||||
|
|
||||||
int insert_entry(int timestamp, const char * const command);
|
int insert_entry(int timestamp, const char * const command);
|
||||||
void query(const char * const string);
|
void query(const char * const string, const size_t limit, const size_t offset);
|
||||||
|
void requery(void);
|
||||||
entry_t get_entry(void);
|
entry_t get_entry(void);
|
||||||
|
@ -5,31 +5,54 @@
|
|||||||
#include <ncurses.h>
|
#include <ncurses.h>
|
||||||
#include <readline/readline.h>
|
#include <readline/readline.h>
|
||||||
|
|
||||||
// XXX
|
#include <stdlib.h>
|
||||||
#include <cstdlib>
|
|
||||||
|
extern bool do_run;
|
||||||
|
|
||||||
|
size_t entry_lines;
|
||||||
|
bool is_input_changed = true;
|
||||||
|
|
||||||
static WINDOW * main_window;
|
static WINDOW * main_window;
|
||||||
static WINDOW * entry_window;
|
static WINDOW * entry_window;
|
||||||
static WINDOW * input_window;
|
static WINDOW * input_window;
|
||||||
|
static WINDOW * version_window;
|
||||||
|
|
||||||
static int input_available = false;
|
static int input_available = false;
|
||||||
static char input;
|
static int input;
|
||||||
|
|
||||||
|
size_t selection_offset = 0;
|
||||||
|
size_t selection_relative = 0;
|
||||||
|
static size_t entry_line_index = 0;
|
||||||
|
|
||||||
|
static char version_string[] =
|
||||||
|
# include "version.inc"
|
||||||
|
;
|
||||||
|
|
||||||
static void refresh_input(void);
|
static void refresh_input(void);
|
||||||
|
|
||||||
int init_tui(void) {
|
int init_tui(void) {
|
||||||
// Ncurses
|
// Ncurses
|
||||||
initscr();
|
initscr();
|
||||||
|
nonl();
|
||||||
|
cbreak();
|
||||||
noecho();
|
noecho();
|
||||||
curs_set(0);
|
curs_set(0);
|
||||||
|
keypad(stdscr, TRUE);
|
||||||
|
|
||||||
main_window = newwin(LINES-1, COLS, 0, 0);
|
entry_lines = LINES-3;
|
||||||
entry_window = subwin(main_window, LINES-3, COLS-2, 1, 1);
|
|
||||||
input_window = newwin(1, COLS, LINES-1, 0);
|
main_window = newwin(LINES-1, COLS, 0, 0);
|
||||||
|
entry_window = subwin(main_window, entry_lines, COLS-2, 1, 1);
|
||||||
|
version_window = subwin(main_window, 1, strlen(version_string), 0, 5);
|
||||||
|
input_window = newwin(1, COLS, LINES-1, 0);
|
||||||
refresh();
|
refresh();
|
||||||
|
|
||||||
box(main_window, 0, 0);
|
box(main_window, 0, 0);
|
||||||
|
|
||||||
|
// XXX
|
||||||
|
waddstr(version_window, version_string);
|
||||||
|
wrefresh(version_window);
|
||||||
|
|
||||||
// Readline
|
// Readline
|
||||||
rl_bind_key('\t', rl_insert);
|
rl_bind_key('\t', rl_insert);
|
||||||
rl_catch_signals = 0;
|
rl_catch_signals = 0;
|
||||||
@ -69,13 +92,23 @@ void tui_append_back(const entry_t entry) {
|
|||||||
char time_buffer[TIME_BUFFER_SIZE];
|
char time_buffer[TIME_BUFFER_SIZE];
|
||||||
strftime(time_buffer, TIME_BUFFER_SIZE, "%Y-%m-%d %H:%M:%S", tm_info);
|
strftime(time_buffer, TIME_BUFFER_SIZE, "%Y-%m-%d %H:%M:%S", tm_info);
|
||||||
|
|
||||||
wprintw(entry_window, "%s %s\n",
|
if (entry_line_index == selection_relative) {
|
||||||
time_buffer,
|
wattron(entry_window, A_REVERSE);
|
||||||
entry.command
|
}
|
||||||
|
mvwprintw(entry_window, (entry_lines-1)-entry_line_index, 0,
|
||||||
|
"%s %s\n",
|
||||||
|
time_buffer,
|
||||||
|
entry.command
|
||||||
);
|
);
|
||||||
|
if (entry_line_index == selection_relative) {
|
||||||
|
wattroff(entry_window, A_REVERSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
++entry_line_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void refresh_input(void) {
|
static void refresh_input(void) {
|
||||||
|
entry_line_index = 0;
|
||||||
wmove(input_window, 0, 0);
|
wmove(input_window, 0, 0);
|
||||||
wclrtoeol(input_window);
|
wclrtoeol(input_window);
|
||||||
waddstr(input_window, "$ ");
|
waddstr(input_window, "$ ");
|
||||||
@ -94,6 +127,34 @@ void tui_refresh(void) {
|
|||||||
|
|
||||||
void tui_take_input(void) {
|
void tui_take_input(void) {
|
||||||
input = wgetch(stdscr);
|
input = wgetch(stdscr);
|
||||||
input_available = true;
|
switch (input) {
|
||||||
rl_callback_read_char();
|
case CTRL('p'):
|
||||||
|
case CTRL('k'): {
|
||||||
|
if (selection_relative != entry_lines-1) {
|
||||||
|
++selection_relative;
|
||||||
|
} else {
|
||||||
|
++selection_offset;
|
||||||
|
is_input_changed = true;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case CTRL('n'):
|
||||||
|
case CTRL('j'): {
|
||||||
|
if (selection_relative != 0) {
|
||||||
|
--selection_relative;
|
||||||
|
} else {
|
||||||
|
if (selection_offset != 0) {
|
||||||
|
--selection_offset;
|
||||||
|
is_input_changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case '\r': {
|
||||||
|
do_run = false;
|
||||||
|
} break;
|
||||||
|
default: {
|
||||||
|
input_available = true;
|
||||||
|
rl_callback_read_char();
|
||||||
|
is_input_changed = true;
|
||||||
|
} break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <stddef.h>
|
||||||
#include "entry.h"
|
#include "entry.h"
|
||||||
|
|
||||||
extern "C" char * rl_line_buffer;
|
extern "C" char * rl_line_buffer;
|
||||||
|
|
||||||
|
extern size_t entry_lines;
|
||||||
|
extern size_t selection_offset;
|
||||||
|
extern size_t selection_relative;
|
||||||
|
extern bool is_input_changed;
|
||||||
|
|
||||||
int init_tui(void);
|
int init_tui(void);
|
||||||
int deinit_tui(void);
|
int deinit_tui(void);
|
||||||
void tui_refresh(void);
|
void tui_refresh(void);
|
||||||
|
@ -1 +1 @@
|
|||||||
"0.2"
|
"Histui v0.2"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user