aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/history.cpp16
-rw-r--r--src/path.cpp44
-rw-r--r--src/path.h15
3 files changed, 66 insertions, 9 deletions
diff --git a/src/history.cpp b/src/history.cpp
index 5d9528b2..6b458212 100644
--- a/src/history.cpp
+++ b/src/history.cpp
@@ -388,8 +388,8 @@ static size_t offset_of_next_item_fish_2_0(const char *begin, size_t mmap_length
! memcmp(line_start, "---", 3) ||
! memcmp(line_start, "...", 3))
continue;
-
-
+
+
/* Hackish: fish 1.x rewriting a fish 2.0 history file can produce lines with lots of leading "- cmd: - cmd: - cmd:". Trim all but one leading "- cmd:". */
const char *double_cmd = "- cmd: - cmd: ";
const size_t double_cmd_len = strlen(double_cmd);
@@ -398,13 +398,13 @@ static size_t offset_of_next_item_fish_2_0(const char *begin, size_t mmap_length
/* Skip over just one of the - cmd. In the end there will be just one left. */
line_start += strlen("- cmd: ");
}
-
+
/* Hackish: fish 1.x rewriting a fish 2.0 history file can produce commands like "when: 123456". Ignore those. */
const char *cmd_when = "- cmd: when:";
const size_t cmd_when_len = strlen(cmd_when);
if (newline - line_start >= cmd_when_len && ! memcmp(line_start, cmd_when, cmd_when_len))
continue;
-
+
/* At this point, we know line_start is at the beginning of an item. But maybe we want to skip this item because of timestamps. A 0 cutoff means we don't care; if we do care, then try parsing out a timestamp. */
if (cutoff_timestamp != 0)
@@ -733,7 +733,7 @@ history_item_t history_t::item_at_index(size_t idx)
{
resolved_new_item_count -= 1;
}
-
+
/* idx=0 corresponds to the last resolved item */
if (idx < resolved_new_item_count)
{
@@ -816,7 +816,7 @@ history_item_t history_t::decode_item_fish_2_0(const char *base, size_t len)
size_t indent = 0, cursor = 0;
std::string key, value, line;
-
+
/* Read the "- cmd:" line */
size_t advance = read_line(base, cursor, len, line);
trim_leading_spaces(line);
@@ -824,7 +824,7 @@ history_item_t history_t::decode_item_fish_2_0(const char *base, size_t len)
{
goto done;
}
-
+
cursor += advance;
cmd = str2wcstring(value);
@@ -1275,7 +1275,7 @@ static void unescape_yaml(std::string *str)
static wcstring history_filename(const wcstring &name, const wcstring &suffix)
{
wcstring path;
- if (! path_get_config(path))
+ if (! path_get_data(path))
return L"";
wcstring result = path;
diff --git a/src/path.cpp b/src/path.cpp
index 62a31a63..b8cfd516 100644
--- a/src/path.cpp
+++ b/src/path.cpp
@@ -276,6 +276,42 @@ static wcstring path_create_config()
return res;
}
+static wcstring path_create_data()
+{
+ bool done = false;
+ wcstring res;
+
+ const env_var_t xdg_dir = env_get_string(L"XDG_DATA_HOME");
+ if (! xdg_dir.missing())
+ {
+ res = xdg_dir + L"/fish";
+ if (!create_directory(res))
+ {
+ done = true;
+ }
+ }
+ else
+ {
+ const env_var_t home = env_get_string(L"HOME");
+ if (! home.missing())
+ {
+ res = home + L"/.local/share/fish";
+ if (!create_directory(res))
+ {
+ done = true;
+ }
+ }
+ }
+
+ if (! done)
+ {
+ res.clear();
+
+ debug(0, _(L"Unable to create a data directory for fish. Your history will not be saved. Please set the $XDG_DATA_HOME variable to a directory where the current user has write access."));
+ }
+ return res;
+}
+
/* Cache the config path */
bool path_get_config(wcstring &path)
{
@@ -284,6 +320,14 @@ bool path_get_config(wcstring &path)
return ! result.empty();
}
+/* Cache the data path */
+bool path_get_data(wcstring &path)
+{
+ static const wcstring result = path_create_data();
+ path = result;
+ return ! result.empty();
+}
+
__attribute__((unused))
static void replace_all(wcstring &str, const wchar_t *needle, const wchar_t *replacement)
{
diff --git a/src/path.h b/src/path.h
index eb79ee8a..973e8a3a 100644
--- a/src/path.h
+++ b/src/path.h
@@ -20,7 +20,7 @@
/**
Returns the user configuration directory for fish. If the directory
- or one of it's parents doesn't exist, they are first created.
+ or one of its parents doesn't exist, they are first created.
\param path The directory as an out param
\return whether the directory was returned successfully
@@ -28,6 +28,19 @@
bool path_get_config(wcstring &path);
/**
+ Returns the user data directory for fish. If the directory
+ or one of its parents doesn't exist, they are first created.
+
+ Volatile files presumed to be local to the machine,
+ such as the fish_history and all the generated_completions,
+ will be stored in this directory.
+
+ \param path The directory as an out param
+ \return whether the directory was returned successfully
+*/
+bool path_get_data(wcstring &path);
+
+/**
Finds the full path of an executable. Returns YES if successful.
\param cmd The name of the executable.