Skip to content
Snippets Groups Projects
Commit d31ab146 authored by Jan Trávníček's avatar Jan Trávníček
Browse files

takeout history handling from Prompt

parent 46b1b5d2
No related branches found
No related tags found
1 merge request!50aql: basic tab-completion using readline
......@@ -7,81 +7,16 @@
 
#include "Prompt.h"
#include "ReadlinePromptCompletion.h"
char esc_char [] = { '\a', '\b', '\f', '\n', '\r', '\t', '\v', '\\' };
char essc_str [] = { 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\' };
size_t esc_char_size = sizeof ( esc_char );
char * descape ( const char * buffer ) {
size_t l = strlen ( buffer );
char * dest = ( char * ) malloc ( ( l + 1 ) * sizeof ( char ) );
char * ptr = dest;
for ( size_t i = 0; i < l; ++ i ) {
if ( buffer [ i ] == '\\' ) {
++ i;
size_t j = std::find ( essc_str, essc_str + esc_char_size, buffer [ i ] ) - essc_str;
if ( j == esc_char_size ) {
free ( dest );
return strdup ( buffer );
}
* ptr ++ = esc_char [ j ];
} else {
* ptr ++ = buffer [ i ];
}
}
* ptr = '\0';
return dest;
}
char * escape ( const char * buffer){
size_t l = strlen ( buffer );
char * dest = ( char * ) malloc ( ( l * 2 + 1 ) * sizeof ( char ) );
char * ptr = dest;
for ( size_t i = 0; i < l; ++ i ) {
size_t j = std::find ( esc_char, esc_char + esc_char_size, buffer [ i ] ) - esc_char;
if ( j == esc_char_size ) {
* ptr ++ = buffer [ i ];
} else {
* ptr ++ = '\\';
* ptr ++ = essc_str [ j ];
}
}
* ptr = '\0';
return dest;
}
#include "ReadlinePromptHistory.h"
 
Prompt::Prompt ( cli::Environment environment ) : m_history_file ( std::string ( std::getenv ( "HOME" ) ) + "/.aql_history" ), m_environment ( std::move ( environment ) ) {
read_history ( m_history_file.c_str ( ) );
HIST_ENTRY ** history = history_list ( );
int i = 0;
if ( history ) while ( * history ) {
char * tmp = descape ( ( * history )->line );
replace_history_entry ( i, tmp, ( * history )->data );
free ( tmp );
++ history;
++ i;
}
ReadlinePromptHistory::readHistory ( m_history_file.c_str ( ) );
// register readline completion function, pass environment
rl_attempted_completion_function = ReadlinePromptCompletion::readline_completion;
}
 
Prompt::~Prompt ( ) {
HIST_ENTRY ** history = history_list ( );
int i = 0;
if ( history ) while ( * history ) {
char * tmp = escape ( ( * history )->line );
replace_history_entry ( i, tmp, ( * history )->data );
free ( tmp );
++ history;
++ i;
}
write_history ( m_history_file.c_str ( ) );
ReadlinePromptHistory::writeHistory ( m_history_file.c_str ( ) );
}
 
cli::Command::Result Prompt::run ( ) {
......
/*
* ReadlinePromptHistory.cpp
*
* Created on: 26. 1. 2019
* Author: Jan Travnicek
*/
#include "ReadlinePromptHistory.h"
char ReadlinePromptHistory::esc_char [] = { '\a', '\b', '\f', '\n', '\r', '\t', '\v', '\\' };
char ReadlinePromptHistory::essc_str [] = { 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\' };
size_t ReadlinePromptHistory::esc_char_size = sizeof ( ReadlinePromptHistory::esc_char );
/*
* ReadlinePromptCompletion.h
*
* Created on: 26. 1. 2019
* Author: Jan Travnicek
*/
#ifndef _READLINE_PROMPT_HISTORY_H
#define _READLINE_PROMPT_HISTORY_H
#include <string.h>
#include <stdio.h>
#include <alib/string>
#include <readline/history.h>
class ReadlinePromptHistory {
static char esc_char [];
static char essc_str [];
static size_t esc_char_size;
static char * descape ( const char * buffer ) {
size_t l = strlen ( buffer );
char * dest = ( char * ) malloc ( ( l + 1 ) * sizeof ( char ) );
char * ptr = dest;
for ( size_t i = 0; i < l; ++ i ) {
if ( buffer [ i ] == '\\' ) {
++ i;
size_t j = std::find ( essc_str, essc_str + esc_char_size, buffer [ i ] ) - essc_str;
if ( j == esc_char_size ) {
free ( dest );
return strdup ( buffer );
}
* ptr ++ = esc_char [ j ];
} else {
* ptr ++ = buffer [ i ];
}
}
* ptr = '\0';
return dest;
}
static char * escape ( const char * buffer){
size_t l = strlen ( buffer );
char * dest = ( char * ) malloc ( ( l * 2 + 1 ) * sizeof ( char ) );
char * ptr = dest;
for ( size_t i = 0; i < l; ++ i ) {
size_t j = std::find ( esc_char, esc_char + esc_char_size, buffer [ i ] ) - esc_char;
if ( j == esc_char_size ) {
* ptr ++ = buffer [ i ];
} else {
* ptr ++ = '\\';
* ptr ++ = essc_str [ j ];
}
}
* ptr = '\0';
return dest;
}
template < class Callable >
static void history_transform ( Callable callable ) {
HIST_ENTRY ** history = history_list ( );
int i = 0;
if ( history ) while ( * history ) {
char * tmp = callable ( ( * history )->line );
replace_history_entry ( i, tmp, ( * history )->data );
free ( tmp );
++ history;
++ i;
}
}
public:
static void readHistory ( const std::string & history_file ) {
read_history ( history_file.c_str ( ) );
ReadlinePromptHistory::history_transform ( ReadlinePromptHistory::descape );
}
static void writeHistory ( const std::string & history_file ) {
ReadlinePromptHistory::history_transform ( ReadlinePromptHistory::escape );
write_history ( history_file.c_str ( ) );
}
};
#endif /* _READLINE_PROMPT_HISTORY_H */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment