mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-27 05:13:10 +00:00
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:
parent
4c2cc384d2
commit
b13f0701a4
3 changed files with 71 additions and 15 deletions
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -64,7 +64,7 @@ private:
|
||||||
|
|
||||||
/** Paths that we require to be valid for this item to be autosuggested */
|
/** Paths that we require to be valid for this item to be autosuggested */
|
||||||
path_list_t required_paths;
|
path_list_t required_paths;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const wcstring &str() const
|
const wcstring &str() const
|
||||||
{
|
{
|
||||||
|
@ -141,7 +141,7 @@ private:
|
||||||
|
|
||||||
/** Whether we have a pending item. If so, the most recently added item is ignored by item_at_index. */
|
/** Whether we have a pending item. If so, the most recently added item is ignored by item_at_index. */
|
||||||
bool has_pending_item;
|
bool has_pending_item;
|
||||||
|
|
||||||
/** Whether we should disable saving to the file for a time */
|
/** Whether we should disable saving to the file for a time */
|
||||||
uint32_t disable_automatic_save_counter;
|
uint32_t disable_automatic_save_counter;
|
||||||
|
|
||||||
|
@ -222,7 +222,7 @@ public:
|
||||||
|
|
||||||
/** Add a new pending history item to the end, and then begin file detection on the items to determine which arguments are paths */
|
/** Add a new pending history item to the end, and then begin file detection on the items to determine which arguments are paths */
|
||||||
void add_pending_with_file_detection(const wcstring &str);
|
void add_pending_with_file_detection(const wcstring &str);
|
||||||
|
|
||||||
/** Resolves any pending history items, so that they may be returned in history searches. */
|
/** Resolves any pending history items, so that they may be returned in history searches. */
|
||||||
void resolve_pending();
|
void resolve_pending();
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -1226,7 +1226,7 @@ static bool insert_string(editable_line_t *el, const wcstring &str, bool allow_e
|
||||||
size_t len = str.size();
|
size_t len = str.size();
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Start inserting. If we are expanding abbreviations, we have to do this after every space (see #1434), so look for spaces. We try to do this efficiently (rather than the simpler character at a time) to avoid expensive work in command_line_changed() */
|
/* Start inserting. If we are expanding abbreviations, we have to do this after every space (see #1434), so look for spaces. We try to do this efficiently (rather than the simpler character at a time) to avoid expensive work in command_line_changed() */
|
||||||
size_t cursor = 0;
|
size_t cursor = 0;
|
||||||
while (cursor < len)
|
while (cursor < len)
|
||||||
|
@ -1236,14 +1236,14 @@ static bool insert_string(editable_line_t *el, const wcstring &str, bool allow_e
|
||||||
size_t char_triggering_expansion_pos = allow_expand_abbreviations ? str.find_first_of(expansion_triggering_chars, cursor) : wcstring::npos;
|
size_t char_triggering_expansion_pos = allow_expand_abbreviations ? str.find_first_of(expansion_triggering_chars, cursor) : wcstring::npos;
|
||||||
bool has_expansion_triggering_char = (char_triggering_expansion_pos != wcstring::npos);
|
bool has_expansion_triggering_char = (char_triggering_expansion_pos != wcstring::npos);
|
||||||
size_t range_end = (has_expansion_triggering_char ? char_triggering_expansion_pos + 1 : len);
|
size_t range_end = (has_expansion_triggering_char ? char_triggering_expansion_pos + 1 : len);
|
||||||
|
|
||||||
/* Insert from the cursor up to but not including the range end */
|
/* Insert from the cursor up to but not including the range end */
|
||||||
assert(range_end > cursor);
|
assert(range_end > cursor);
|
||||||
el->insert_string(str, cursor, range_end - cursor);
|
el->insert_string(str, cursor, range_end - cursor);
|
||||||
|
|
||||||
update_buff_pos(el, el->position);
|
update_buff_pos(el, el->position);
|
||||||
data->command_line_changed(el);
|
data->command_line_changed(el);
|
||||||
|
|
||||||
/* If we got an expansion trigger, then the last character we inserted was it (i.e. was a space). Expand abbreviations. */
|
/* If we got an expansion trigger, then the last character we inserted was it (i.e. was a space). Expand abbreviations. */
|
||||||
if (has_expansion_triggering_char && allow_expand_abbreviations)
|
if (has_expansion_triggering_char && allow_expand_abbreviations)
|
||||||
{
|
{
|
||||||
|
@ -1253,16 +1253,16 @@ static bool insert_string(editable_line_t *el, const wcstring &str, bool allow_e
|
||||||
}
|
}
|
||||||
cursor = range_end;
|
cursor = range_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (el == &data->command_line)
|
if (el == &data->command_line)
|
||||||
{
|
{
|
||||||
data->suppress_autosuggestion = false;
|
data->suppress_autosuggestion = false;
|
||||||
|
|
||||||
/* Syntax highlight. Note we must have that buff_pos > 0 because we just added something nonzero to its length */
|
/* Syntax highlight. Note we must have that buff_pos > 0 because we just added something nonzero to its length */
|
||||||
assert(el->position > 0);
|
assert(el->position > 0);
|
||||||
reader_super_highlight_me_plenty(-1);
|
reader_super_highlight_me_plenty(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
reader_repaint();
|
reader_repaint();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1562,7 +1562,7 @@ static void accept_autosuggestion(bool full)
|
||||||
{
|
{
|
||||||
/* Accepting an autosuggestion clears the pager */
|
/* Accepting an autosuggestion clears the pager */
|
||||||
clear_pager();
|
clear_pager();
|
||||||
|
|
||||||
/* Accept the autosuggestion */
|
/* Accept the autosuggestion */
|
||||||
if (full)
|
if (full)
|
||||||
{
|
{
|
||||||
|
@ -1877,7 +1877,7 @@ static bool handle_completions(const std::vector<completion_t> &comp, bool conti
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Determine if we use the prefix. We use it if it's non-empty and it will actually make the command line longer. It may make the command line longer by virtue of not using REPLACE_TOKEN (so it always appends to the command line), or by virtue of replacing the token but being longer than it. */
|
/* Determine if we use the prefix. We use it if it's non-empty and it will actually make the command line longer. It may make the command line longer by virtue of not using REPLACE_TOKEN (so it always appends to the command line), or by virtue of replacing the token but being longer than it. */
|
||||||
bool use_prefix = common_prefix.size() > (will_replace_token ? tok.size() : 0);
|
bool use_prefix = common_prefix.size() > (will_replace_token ? tok.size() : 0);
|
||||||
assert(! use_prefix || ! common_prefix.empty());
|
assert(! use_prefix || ! common_prefix.empty());
|
||||||
|
@ -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.
|
||||||
|
@ -3157,7 +3163,7 @@ const wchar_t *reader_readline(int nchars)
|
||||||
|
|
||||||
editable_line_t *el = data->active_edit_line();
|
editable_line_t *el = data->active_edit_line();
|
||||||
insert_string(el, arr, true);
|
insert_string(el, arr, true);
|
||||||
|
|
||||||
/* End paging upon inserting into the normal command line */
|
/* End paging upon inserting into the normal command line */
|
||||||
if (el == &data->command_line)
|
if (el == &data->command_line)
|
||||||
{
|
{
|
||||||
|
@ -3440,7 +3446,7 @@ const wchar_t *reader_readline(int nchars)
|
||||||
{
|
{
|
||||||
begin--;
|
begin--;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Push end forwards to just past the next newline, or just past the last char. */
|
/* Push end forwards to just past the next newline, or just past the last char. */
|
||||||
size_t end = el->position;
|
size_t end = el->position;
|
||||||
while (buff[end] != L'\0')
|
while (buff[end] != L'\0')
|
||||||
|
|
Loading…
Reference in a new issue