New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] XDG support #3198
[WIP] XDG support #3198
Conversation
[cache_home] = "~/.cache", | ||
[runtime_dir] = "", | ||
[config_dirs] = "/etc/xdg/", | ||
[data_dirs] = "/usr/local/share/:/usr/share/", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason that some of these values have a slash at the end and some don't?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just following the spec: http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
[kConfigDirs] = "/etc/xdg/", | ||
[kDataDirs] = "/usr/local/share/:/usr/share/", | ||
}; | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pyrohh Does this look good?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer explicit defines (as opposed to else), but in this case why not.
CYGWIN <-> ~ ??
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jck Looks fine to me, no comment on the actual defines though. I'm not sure if it should instead be __WIN32__
and __APPPLE__
, but we'll deal with that later.
Make sure to update the |
ret = (const char *)expand_env_save((char_u *)fallback); | ||
} | ||
|
||
return ret; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This returns statically allocated memory when os_getenv(env)
returns non-null, and heap-allocated memory when it returns null and fallback
isn't null. How does the caller know whether the return value requires an xfree()
? We could add a parameter, bool *must_free
, but it may be simpler to always return allocated memory.
const char *ret = os_getenv(env);
if (ret) {
ret = xstrdup(ret);
} else if (fallback) {
// ... same as before
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^ This. This should fix the leak ASAN is complainign about.
Hoping to get this in 0.1 milestone. |
A bit late, but in case it helps, this was mentioned in #78 as a useful reference: https://github.com/ActiveState/appdirs/blob/master/appdirs.py |
Will this PR also allow storage of undo and swap files under the cache directory? |
@tarruda Not sure about the exact location, but it would allow us to turn those on by default, which is I think is desirable. |
@justinmk I'll finish this off this weekend. I hope that will be enough for 0.1 |
&& do_source((char_u *)USR_VIMRC_FILE3, TRUE, | ||
DOSO_VIMRC) == FAIL | ||
#endif | ||
if (do_source(user_vimrc, TRUE, DOSO_VIMRC) == FAIL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use true
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of main.c appears to be using TRUE and FALSE. Should I just fix all of them in a new commit/different PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, just change these, the travis build won't pass until you do so. Merely stylistic PRs are not terribly important, and since the linter starts looking for issues in the surrounding lines, they can become quite unwieldy.
|
||
const char *get_from_user_data(const char * fname) | ||
{ | ||
const char *dir = (const char *)concat_fnames(get_user_data_dir(), fname, true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clint says this line is too long
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, there is a leak here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Speaking of that, is there any static analysis planned ? It could be a nice addition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already have static analysis:
https://neovim.io/doc/reports/clang/
https://scan.coverity.com/projects/2227
However coverity has been broken for weeks.
@justinmk I think this should aim for 0.1. 0.1 will probably cause quite a bunch of people to try out nvim, and I feel it's better to have them put their configuration files in the right place right away. |
@@ -31,12 +31,6 @@ | |||
#ifndef USR_EXRC_FILE | |||
# define USR_EXRC_FILE "~/.exrc" | |||
#endif | |||
#ifndef USR_VIMRC_FILE | |||
# define USR_VIMRC_FILE "~/.nvimrc" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this mean that users will be forced to use the new location? Isn't it better to use the old files in case it is not found in the XDG dirs? cc @justinmk
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In #78 @ZyX-I made the case that there is no reason for us to support both old and new config locations. It bothers me because it means the default location is different on each system (this makes support more difficult, and requires extra setup to share configs across systems using GitHub etc).
I would be less bothered by it if we defaulted to ~/.config
on all systems (unix, windows, osx) instead of the terrible ~/Library
and %APPDATA%
paths. (No one really wants their configs there, do they?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not your place to question it really. These are the standards set forth by the operating systems you target. I'll quote some of Raymond Chen's ironic maxims about his frustration when dealing with software during the MS-DOS to Windows 95 transition:
4. Manuals are a waste of time.
9. Find a rule and break it as blatantly as possible.
19. Second-guess the specification whenever possible.
Please don't keep repeating the same mistakes. As for support, different locations is trivial to deal with, please don't use it as an excuse to do the wrong thing.
12. It is better to be lucky than good.
@tarruda This software is pre-1.0 release (assuming you're following semver), there is no reason to support legacy. Just do the right thing now instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm with @Earnestly (and @ZyX-I) on this one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Earnestly Where does the standard specify the default locations for OSX and Windows? So far only source examples like https://github.com/ActiveState/appdirs/blob/master/appdirs.py have been offered, which indicate "best guesses" about default locations, there is no reference to a specification.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kopischke I'm not a OSX user (never really used it, actually), so I was just being conservative ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@justinmk Taking a look at the basedir spec again, most of the XDG_
variables are defined relative to $HOME
, which has its equivalent in %UserProfile%
under Windows. I guess in that sense using that should be the correct behavior as per the basedir spec. However, XDG_DATA_DIRS
and XDG_CONFIG_DIRS
are undefined, since they default to paths Windows doesn't have.
http://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@justinmk Windows is out of scope of XDG Basedir, follow Windows' standards for Windows instead. For example, Vala's Environment.get_user_config_dir()
uses CSIDL_LOCAL_APPDATA
for Windows.
What you want to do about Windows however is up to you,
thank you for working on this btw. ❤
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fmoralesc nothing wrong with that, especially as OS X’ “almost, but not quite, Unix” system does need special treatment in many areas. The XDG spec as applied to CLI applications is not one of them, however, so let’s count our blessings and limit special treatment to The Odd Man Out™, aka Windows :).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was just trying out the PR locally, and it seems to me like it still needs to handle |
@fmoralesc Initialization file location should be stored in |
ga_init(&rtp_ga, (int)sizeof(const char *), 1); | ||
GA_APPEND(const char *, &rtp_ga, get_user_conf_dir()); | ||
GA_APPEND(const char *, &rtp_ga, concat_fnames(get_user_conf_dir(), "after", true)); | ||
set_string_default("runtimepath", ga_concat_strings(&rtp_ga)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The memory allocated by concat_fnames
must be xfree
d. Doesn't look like we gain much by using garray_T
here. sprintf()
(or the custom vim variant) might be more appropriate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you suggest that I precomute the length of the rtp string like this?
ZyX-I@b4331ac
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The safest bet for allocating path names is just xmalloc(PATH_MAX)
. If you care about over-allocated memory, you can xrealloc(rtp strlen(rtp) + 1)
later, but it's not necessary.
I just realized another issue: It looks like the resulting string will be "{get_user_conf_dir()}{get_user_conf_dir()}/after"
. Could just do this:
char* conf_dir = get_user_conf_dir();
set_string_default("runtimepath", concat_fnames(conf_dir, "after", true);
xfree(conf_dir);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Relying on PATH_MAX
is extremely silly and not a very well researched suggestion. Consider the implications of what you're suggesting on a portability level. No, correct handling of paths involve using calloc and snprintf. (I assume xmalloc is just a wrapper around malloc that provides overflow checking like calloc but without the guarantee of zero initialised memory.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately (I guess), we have a lot of code that check paths are less than the maximum, so this convention wouldn't be easy to remove from the codebase, even if it's wrong. For the moment, I think it would be correct to just say "we don't support unreasonably large paths," and if supporting them means unleashing such inefficient code such as in the linked article, I don't see any benefit.
Also, I double checked: I should have said MAXPATHL
, an os-independent variable that we define.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@splinterofchaos Why not simply use my code with minimal modifications (to use different functions to get XDG_* variables)? I see that this variant uses only XDG_CONFIG_HOME which is not enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Note: do not use the commit you referenced, use the head of pr-3120
branch.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ZyX-I “53. So many good ideas are never heard from again once they embark in a voyage on the semantic gulf.” — Alan J. Perlis
'runtimepath' needs to include the system runtime path. |
@fmoralesc My variant includes system runtime path. BTW, after #2506 is merged this PR needs rebasing or you will not be able to move shada file to XDG-compatible location. I have updated #78 to reflect changes (for some reason that issue did not talk about viminfo though). |
Closing in favor of #3470, but if I missed something please reopen. |
This is a continuation of the discussion in #3127 .
I've addressed some of the comments in 8fc0976 but there is still quite a bit to do.