undo: Automatically create undo directory if needed

This commit is contained in:
ZyX 2015-10-29 01:24:04 +03:00
parent d99941777d
commit ffdf9399ba
2 changed files with 22 additions and 5 deletions

View File

@ -6695,7 +6695,7 @@ A jump table for the options with a short description can be found at |Q_op|.
global
Alias for 'term', see above.
*'undodir'* *'udir'*
*'undodir'* *'udir'* *E926*
'undodir' 'udir' string (default ".")
global
{only when compiled with the |+persistent_undo| feature}
@ -6705,8 +6705,10 @@ A jump table for the options with a short description can be found at |Q_op|.
"file.txt" is ".file.txt.un~".
For other directories the file name is the full path of the edited
file, with path separators replaced with "%".
When writing: The first directory that exists is used. "." always
works, no directories after "." will be used for writing.
When writing: The first directory that exists is used. "." always
works, no directories after "." will be used for writing. If none of
the directories exist Neovim will attempt to create last directory in
the list.
When reading all entries are tried to find an undo file. The first
undo file that exists is used. When it cannot be read an error is
given, no further entry is used.

View File

@ -644,7 +644,9 @@ void u_compute_hash(char_u *hash)
/// be found.
/// @param[in] reading If true, find the file to read by traversing all of the
/// directories in &undodir. If false use the first
/// existing directory.
/// existing directory. If none of the directories in
/// &undodir option exist then last directory in the list
/// will be automatically created.
///
/// @return [allocated] File name to read from/write to or NULL.
char *u_get_undo_file_name(const char *const buf_ffname, const bool reading)
@ -690,7 +692,20 @@ char *u_get_undo_file_name(const char *const buf_ffname, const bool reading)
memmove(tail + tail_len + 1, ".un~", sizeof(".un~"));
} else {
dir_name[dir_len] = NUL;
if (os_isdir((char_u *)dir_name)) {
bool has_directory = os_isdir((char_u *)dir_name);
if (!has_directory && *dirp == NUL && !reading) {
// Last directory in the list does not exist, create it.
int ret;
char *failed_dir;
if ((ret = os_mkdir_recurse(dir_name, 0755, &failed_dir)) != 0) {
EMSG3(_("E926: Unable to create directory \"%s\" for undo file: %s"),
failed_dir, os_strerror(ret));
xfree(failed_dir);
} else {
has_directory = true;
}
}
if (has_directory) {
if (munged_name == NULL) {
munged_name = xstrdup(ffname);
for (char *p = munged_name; *p != NUL; mb_ptr_adv(p)) {