Added a "reload" command, for use at the REPL
Created a new function, session_t::reread_journal_files, which throws away all previous state data and reads in the same files again. This is needed to allow Emacs to communicate with Ledger via the REPL, so that it tell Ledger when it has made changes to the user's data file.
This commit is contained in:
parent
037dd0f716
commit
70344b82e7
7 changed files with 78 additions and 57 deletions
|
|
@ -109,24 +109,6 @@ void global_scope_t::read_init()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void global_scope_t::read_journal_files()
|
|
||||||
{
|
|
||||||
INFO_START(journal, "Read journal file");
|
|
||||||
|
|
||||||
string master_account;
|
|
||||||
if (session().HANDLED(account_))
|
|
||||||
master_account = session().HANDLER(account_).str();
|
|
||||||
|
|
||||||
std::size_t count = session().read_data(master_account);
|
|
||||||
if (count == 0)
|
|
||||||
throw_(parse_error, "Failed to locate any journal entries; "
|
|
||||||
"did you specify a valid file with -f?");
|
|
||||||
|
|
||||||
INFO_FINISH(journal);
|
|
||||||
|
|
||||||
INFO("Found " << count << " entries");
|
|
||||||
}
|
|
||||||
|
|
||||||
char * global_scope_t::prompt_string()
|
char * global_scope_t::prompt_string()
|
||||||
{
|
{
|
||||||
static char prompt[32];
|
static char prompt[32];
|
||||||
|
|
@ -195,7 +177,7 @@ void global_scope_t::execute_command(strings_list args, bool at_repl)
|
||||||
|
|
||||||
if (! is_precommand) {
|
if (! is_precommand) {
|
||||||
if (! at_repl)
|
if (! at_repl)
|
||||||
read_journal_files();
|
session().read_journal_files();
|
||||||
normalize_report_options(verb);
|
normalize_report_options(verb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,6 @@ public:
|
||||||
~global_scope_t();
|
~global_scope_t();
|
||||||
|
|
||||||
void read_init();
|
void read_init();
|
||||||
void read_journal_files();
|
|
||||||
void read_environment_settings(char * envp[]);
|
void read_environment_settings(char * envp[]);
|
||||||
strings_list read_command_arguments(scope_t& scope, strings_list args);
|
strings_list read_command_arguments(scope_t& scope, strings_list args);
|
||||||
void normalize_session_options();
|
void normalize_session_options();
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ int main(int argc, char * argv[], char * envp[])
|
||||||
|
|
||||||
if (global_scope->HANDLED(script_)) {
|
if (global_scope->HANDLED(script_)) {
|
||||||
// Ledger is being invoked as a script command interpreter
|
// Ledger is being invoked as a script command interpreter
|
||||||
global_scope->read_journal_files();
|
global_scope->session().read_journal_files();
|
||||||
|
|
||||||
status = 0;
|
status = 0;
|
||||||
|
|
||||||
|
|
@ -115,7 +115,7 @@ int main(int argc, char * argv[], char * envp[])
|
||||||
// Commence the REPL by displaying the current Ledger version
|
// Commence the REPL by displaying the current Ledger version
|
||||||
global_scope->show_version_info(std::cout);
|
global_scope->show_version_info(std::cout);
|
||||||
|
|
||||||
global_scope->read_journal_files();
|
global_scope->session().read_journal_files();
|
||||||
|
|
||||||
bool exit_loop = false;
|
bool exit_loop = false;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -556,6 +556,8 @@ expr_t::ptr_op_t report_t::lookup(const string& name)
|
||||||
return WRAP_FUNCTOR
|
return WRAP_FUNCTOR
|
||||||
(reporter<>(new format_xacts(*this, HANDLER(register_format_).str()),
|
(reporter<>(new format_xacts(*this, HANDLER(register_format_).str()),
|
||||||
*this));
|
*this));
|
||||||
|
else if (is_eq(p, "reload"))
|
||||||
|
return MAKE_FUNCTOR(report_t::reload_command);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 's':
|
case 's':
|
||||||
|
|
|
||||||
|
|
@ -143,6 +143,11 @@ public:
|
||||||
return value_t(static_cast<scope_t *>(this));
|
return value_t(static_cast<scope_t *>(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
value_t reload_command(call_scope_t& scope) {
|
||||||
|
session.reread_journal_files();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void append_predicate(const string& str) {
|
void append_predicate(const string& str) {
|
||||||
if (HANDLED(limit_))
|
if (HANDLED(limit_))
|
||||||
HANDLER(limit_).on(string("(") + HANDLER(limit_).str() + ")&" + str);
|
HANDLER(limit_).on(string("(") + HANDLER(limit_).str() + ")&" + str);
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ session_t::session_t()
|
||||||
current_year(CURRENT_DATE().year()),
|
current_year(CURRENT_DATE().year()),
|
||||||
|
|
||||||
commodity_pool(new commodity_pool_t),
|
commodity_pool(new commodity_pool_t),
|
||||||
master(new account_t(NULL, "")),
|
master(new account_t),
|
||||||
journal(new journal_t(master.get()))
|
journal(new journal_t(master.get()))
|
||||||
{
|
{
|
||||||
TRACE_CTOR(session_t, "");
|
TRACE_CTOR(session_t, "");
|
||||||
|
|
@ -106,7 +106,6 @@ std::size_t session_t::read_data(const string& master_account)
|
||||||
|
|
||||||
std::size_t entry_count = 0;
|
std::size_t entry_count = 0;
|
||||||
|
|
||||||
if (entry_count == 0) {
|
|
||||||
account_t * acct = journal->master;
|
account_t * acct = journal->master;
|
||||||
if (! master_account.empty())
|
if (! master_account.empty())
|
||||||
acct = journal->find_account(master_account);
|
acct = journal->find_account(master_account);
|
||||||
|
|
@ -116,7 +115,6 @@ std::size_t session_t::read_data(const string& master_account)
|
||||||
throw_(parse_error, "Entries not allowed in price history file");
|
throw_(parse_error, "Entries not allowed in price history file");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
foreach (const path& pathname, HANDLER(file_).data_files) {
|
foreach (const path& pathname, HANDLER(file_).data_files) {
|
||||||
if (pathname == "-") {
|
if (pathname == "-") {
|
||||||
// To avoid problems with stdin and pipes, etc., we read the entire
|
// To avoid problems with stdin and pipes, etc., we read the entire
|
||||||
|
|
@ -143,13 +141,45 @@ std::size_t session_t::read_data(const string& master_account)
|
||||||
throw_(parse_error, "Could not open journal file '" << pathname << "'");
|
throw_(parse_error, "Could not open journal file '" << pathname << "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
VERIFY(journal->valid());
|
VERIFY(journal->valid());
|
||||||
|
|
||||||
return entry_count;
|
return entry_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void session_t::read_journal_files()
|
||||||
|
{
|
||||||
|
INFO_START(journal, "Read journal file");
|
||||||
|
|
||||||
|
string master_account;
|
||||||
|
if (HANDLED(account_))
|
||||||
|
master_account = HANDLER(account_).str();
|
||||||
|
|
||||||
|
std::size_t count = read_data(master_account);
|
||||||
|
if (count == 0)
|
||||||
|
throw_(parse_error, "Failed to locate any journal entries; "
|
||||||
|
"did you specify a valid file with -f?");
|
||||||
|
|
||||||
|
INFO_FINISH(journal);
|
||||||
|
|
||||||
|
INFO("Found " << count << " entries");
|
||||||
|
}
|
||||||
|
|
||||||
|
void session_t::reread_journal_files()
|
||||||
|
{
|
||||||
|
journal.reset();
|
||||||
|
master.reset();
|
||||||
|
commodity_pool.reset();
|
||||||
|
amount_t::shutdown();
|
||||||
|
|
||||||
|
commodity_pool.reset(new commodity_pool_t);
|
||||||
|
amount_t::initialize(commodity_pool);
|
||||||
|
master.reset(new account_t);
|
||||||
|
journal.reset(new journal_t(master.get()));
|
||||||
|
|
||||||
|
read_journal_files();
|
||||||
|
}
|
||||||
|
|
||||||
void session_t::clean_xacts()
|
void session_t::clean_xacts()
|
||||||
{
|
{
|
||||||
journal_xacts_iterator walker(*journal.get());
|
journal_xacts_iterator walker(*journal.get());
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,9 @@ public:
|
||||||
|
|
||||||
std::size_t read_data(const string& master_account = "");
|
std::size_t read_data(const string& master_account = "");
|
||||||
|
|
||||||
|
void read_journal_files();
|
||||||
|
void reread_journal_files();
|
||||||
|
|
||||||
void clean_xacts();
|
void clean_xacts();
|
||||||
void clean_xacts(entry_t& entry);
|
void clean_xacts(entry_t& entry);
|
||||||
void clean_accounts();
|
void clean_accounts();
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue