Migrate fish_history from config to data dir

New implementation of migration code within the history_t class will
copy the contents of the old fish_history found in the config directory
to its new location in the data directory.  The old file is left intact.

This is done only in the event that a fish_history is not already found in
the data directory ($XDG_DATA_HOME/fish or ~/.local/share/fish).
This commit is contained in:
Jeff Kowalski 2015-09-18 20:47:38 -07:00 committed by David Adam
parent 4c2cc384d2
commit b13f0701a4
3 changed files with 71 additions and 15 deletions

View file

@ -1664,6 +1664,53 @@ bool history_t::is_empty(void)
return empty; return empty;
} }
/* Populates from older location (in config path, rather than data path)
This is accomplished by clearing ourselves, and copying the contents of
the old history file to the new history file. The new contents will
automatically be re-mapped later.
*/
void history_t::populate_from_config_path()
{
wcstring old_file;
if (path_get_config(old_file)) {
old_file.append(L"/");
old_file.append(name);
old_file.append(L"_history");
int src_fd = wopen_cloexec(old_file, O_RDONLY, 0);
if (src_fd != -1)
{
wcstring new_file;
history_filename(new_file, L"");
/* clear must come after we've retrieved the new_file name,
and before we open destination file descriptor,
since it destroys the name and the file */
this->clear();
int dst_fd = wopen_cloexec(new_file, O_WRONLY | O_CREAT, 0644);
char buf[BUFSIZ];
size_t size;
while ((size = read(src_fd, buf, BUFSIZ)) > 0) {
ssize_t written = write(dst_fd, buf, size);
if (written == -1) {
/*
This message does not have high enough priority to
be shown by default.
*/
debug(2, L"Error when writing history file");
break;
}
}
close(src_fd);
close(dst_fd);
}
}
}
/* Indicate whether we ought to import the bash history file into fish */ /* Indicate whether we ought to import the bash history file into fish */
static bool should_import_bash_history_line(const std::string &line) static bool should_import_bash_history_line(const std::string &line)
{ {

View file

@ -236,6 +236,9 @@ public:
/** Irreversibly clears history */ /** Irreversibly clears history */
void clear(); void clear();
/** Populates from older location ()in config path, rather than data path) */
void populate_from_config_path();
/** Populates from a bash history file */ /** Populates from a bash history file */
void populate_from_bash(FILE *f); void populate_from_bash(FILE *f);

View file

@ -2660,7 +2660,13 @@ void reader_set_exit_on_interrupt(bool i)
void reader_import_history_if_necessary(void) void reader_import_history_if_necessary(void)
{ {
/* Import history from bash, etc. if our current history is empty */ /* Import history from older location (config path) if our current history is empty */
if (data->history && data->history->is_empty())
{
data->history->populate_from_config_path();
}
/* Import history from bash, etc. if our current history is still empty */
if (data->history && data->history->is_empty()) if (data->history && data->history->is_empty())
{ {
/* Try opening a bash file. We make an effort to respect $HISTFILE; this isn't very complete (AFAIK it doesn't have to be exported), and to really get this right we ought to ask bash itself. But this is better than nothing. /* Try opening a bash file. We make an effort to respect $HISTFILE; this isn't very complete (AFAIK it doesn't have to be exported), and to really get this right we ought to ask bash itself. But this is better than nothing.