Right now projects cannot be moved to other directories without
losing the base directory setting of the project and the list
of open files. This makes the project totally unportable to different
machines because even if the directory structure under your home is
identical, the user name can be different so the path is different too.
The paths should be relative to the project file, which is what
every other IDE I know does. If you keep the project file in the
same relative path to the project files, you can move it wherever you
want.
This patch does this in a backwards-compatible way - when the path
in the project settings file is absolute, it uses the absoulte path.
However, when the project is saved, all paths are converted to relative.
This means that all new applications will be able to read the old
project definition files but the old applications won't read
the new files (or more precisely, the paths in them).
For the global session file absolute paths are still used mainly because in
Windows you cannot create a relative path to a different volume and the
global settings file can be at a volume different from the project dir.
(I don't expect anyone has the project definition file at different
volume than the project files so this shouldn't be an issue for projects).
As Dimitar suggested, absolute paths could be used for files outside
the base directory which makes sense because the paths outside the project
would be preserved even if the project moves somewhere else. This feature
can be included depending on the further discussion.
One more possibility is to add a settings option (either per project or
global) that determines what kind of paths should be used.
Signed-off-by: Jiří Techet <[email protected]>
---
src/keyfile.c | 39 ++++++++++++++++++++++++++++++++++-----
src/keyfile.h | 2 +-
src/project.c | 26 +++++++++++++++++++++++---
3 files changed, 58 insertions(+), 9 deletions(-)
diff --git a/src/keyfile.c b/src/keyfile.c
index 7b29df7..e6d1273 100644
--- a/src/keyfile.c
+++ b/src/keyfile.c
@@ -253,7 +253,7 @@ static void save_recent_files(GKeyFile *config, GQueue *queue, gchar const *key)
}
-static gchar *get_session_file_string(GeanyDocument *doc)
+static gchar *get_session_file_string(GeanyDocument *doc, gboolean relative)
{
gchar *fname;
gchar *locale_filename;
@@ -263,6 +263,26 @@ static gchar *get_session_file_string(GeanyDocument *doc)
ft = filetypes[GEANY_FILETYPES_NONE];
locale_filename = utils_get_locale_from_utf8(doc->file_name);
+ if (app->project && relative)
+ {
+ gchar *project_dir, *file_dir, *tmp;
+
+ project_dir = g_path_get_dirname(app->project->file_name);
+ file_dir = g_path_get_dirname(locale_filename);
+ tmp = utils_relpath(project_dir, file_dir);
+ if (tmp)
+ {
+ gchar *basename;
+
+ basename = g_path_get_basename(locale_filename);
+ setptr(locale_filename, g_build_filename(tmp, basename, NULL));
+ g_free(basename);
+ }
+ g_free(project_dir);
+ g_free(file_dir);
+ g_free(tmp);
+ }
+
/* If the filename contains any ';' (semi-colons) we need to escape them otherwise
* g_key_file_get_string_list() would fail reading them, so we replace them before
* writing with usual colons which must never appear in a filename and replace them
@@ -285,7 +305,7 @@ static gchar *get_session_file_string(GeanyDocument *doc)
}
-void configuration_save_session_files(GKeyFile *config)
+void configuration_save_session_files(GKeyFile *config, gboolean relative)
{
gint npage;
gchar *tmp;
@@ -306,7 +326,7 @@ void configuration_save_session_files(GKeyFile *config)
gchar *fname;
g_snprintf(entry, sizeof(entry), "FILE_NAME_%d", j);
- fname = get_session_file_string(doc);
+ fname = get_session_file_string(doc, relative);
g_key_file_set_string(config, "files", entry, fname);
g_free(fname);
j++;
@@ -551,7 +571,7 @@ void configuration_save(void)
save_recent_files(config, ui_prefs.recent_projects_queue, "recent_projects");
if (cl_options.load_session)
- configuration_save_session_files(config);
+ configuration_save_session_files(config, FALSE);
/* write the file */
data = g_key_file_to_data(config, NULL, NULL);
@@ -901,7 +921,7 @@ void configuration_save_default_session(void)
g_key_file_load_from_file(config, configfile, G_KEY_FILE_NONE, NULL);
if (cl_options.load_session)
- configuration_save_session_files(config);
+ configuration_save_session_files(config, FALSE);
/* write the file */
data = g_key_file_to_data(config, NULL, NULL);
@@ -981,6 +1001,15 @@ static gboolean open_session_file(gchar **tmp, guint len)
/* replace ':' back with ';' (see get_session_file_string for details) */
g_strdelimit((gchar*) utils_path_skip_root(locale_filename), ":", ';');
+ if (!g_path_is_absolute(locale_filename) && app->project)
+ {
+ gchar *project_dir;
+
+ project_dir = g_path_get_dirname(app->project->file_name);
+ setptr(locale_filename, g_build_filename(project_dir, locale_filename, NULL));
+ g_free(project_dir);
+ }
+
if (len > 8)
line_breaking = atoi(tmp[8]);
diff --git a/src/keyfile.h b/src/keyfile.h
index 3a8da08..d7fe33b 100644
--- a/src/keyfile.h
+++ b/src/keyfile.h
@@ -49,7 +49,7 @@ void configuration_save_default_session(void);
void configuration_load_session_files(GKeyFile *config, gboolean read_recent_files);
-void configuration_save_session_files(GKeyFile *config);
+void configuration_save_session_files(GKeyFile *config, gboolean relative);
/* set some settings which are already read from the config file, but need other things, like the
* realisation of the main window */
diff --git a/src/project.c b/src/project.c
index 11f9ca2..b9f865e 100644
--- a/src/project.c
+++ b/src/project.c
@@ -1014,6 +1014,7 @@ static gboolean load_config(const gchar *filename)
{
GKeyFile *config;
GeanyProject *p;
+ gchar *tmp;
/* there should not be an open project */
g_return_val_if_fail(app->project == NULL && filename != NULL, FALSE);
@@ -1032,7 +1033,18 @@ static gboolean load_config(const gchar *filename)
p->name = utils_get_setting_string(config, "project", "name", GEANY_STRING_UNTITLED);
p->description = utils_get_setting_string(config, "project", "description", "");
p->file_name = utils_get_utf8_from_locale(filename);
- p->base_path = utils_get_setting_string(config, "project", "base_path", "");
+
+ tmp = utils_get_setting_string(config, "project", "base_path", "");
+ if (!g_path_is_absolute(tmp))
+ {
+ gchar *project_dir;
+
+ project_dir = g_path_get_dirname(p->file_name);
+ setptr(tmp, g_build_filename(project_dir, tmp, NULL));
+ utils_tidy_path(tmp);
+ g_free(project_dir);
+ }
+ p->base_path = tmp;
p->file_patterns = g_key_file_get_string_list(config, "project", "file_patterns", NULL, NULL);
p->long_line_behaviour = utils_get_setting_integer(config, "long line marker",
@@ -1079,6 +1091,7 @@ static gboolean write_config(gboolean emit_signal)
GKeyFile *config;
gchar *filename;
gchar *data;
+ gchar *tmp, *project_dir;
gboolean ret = FALSE;
g_return_val_if_fail(app->project != NULL, FALSE);
@@ -1093,7 +1106,14 @@ static gboolean write_config(gboolean emit_signal)
stash_group_save_to_key_file(indent_group, config);
g_key_file_set_string(config, "project", "name", p->name);
- g_key_file_set_string(config, "project", "base_path", p->base_path);
+
+ project_dir = g_path_get_dirname(p->file_name);
+ tmp = utils_relpath(project_dir, p->base_path);
+ if (!tmp)
+ tmp = g_strdup(p->base_path);
+ g_key_file_set_string(config, "project", "base_path", tmp);
+ g_free(tmp);
+ g_free(project_dir);
if (p->description)
g_key_file_set_string(config, "project", "description", p->description);
@@ -1106,7 +1126,7 @@ static gboolean write_config(gboolean emit_signal)
/* store the session files into the project too */
if (project_prefs.project_session)
- configuration_save_session_files(config);
+ configuration_save_session_files(config, TRUE);
build_save_menu(config, (gpointer)p, GEANY_BCS_PROJ);
if (emit_signal)
{
_______________________________________________
Geany-devel mailing list
[email protected]
http://lists.uvena.de/cgi-bin/mailman/listinfo/geany-devel