Access fish_history from $XDG_DATA_HOME

Add new functions path_get_data and path_create_data which parallel existing
functions path_get_config and path_create_data.  The new functions refer to
XDG_DATA_HOME, if it is defined, or ./local/share if not.

Modify history_filename to use the new function path_get_data.

As a consequence, fish_history will now be located in XDG_DATA_HOME,
not XDG_CONFIG_HOME.

Note that these changes mirror what is already used in
fish-shell/share/tools/create_manpage_completions.py, which stores the
completions in XDG_DATA_HOME

This change matches recommendations in the xdg basedir spec at
http://standards.freedesktop.org/basedir-spec/basedir-spec-0.7.html
($XDG_DATA_HOME defines the base directory relative to which user specific data
files should be stored. If $XDG_DATA_HOME is either not set or empty, a default
equal to $HOME/.local/share should be used.)

It addresses suggestions from the following issues:

1. Don't put history in $XDG_CONFIG_HOME (closes #744)
   https://github.com/fish-shell/fish-shell/issues/744

2. Fish is placing non-config files in $XDG_CONFIG_HOME #1257
   https://github.com/fish-shell/fish-shell/issues/1257

3. Move non-config data out of $XDG_CONFIG_HOME #1669
   https://github.com/fish-shell/fish-shell/issues/1669
This commit is contained in:
Jeff Kowalski 2015-09-16 21:31:08 -07:00 committed by David Adam
parent b776327b9d
commit 2971887bbd
3 changed files with 66 additions and 9 deletions

View file

@ -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;

View file

@ -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)
{

View file

@ -20,13 +20,26 @@
/**
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
*/
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.