Index: src/keyfile.c
===================================================================
--- src/keyfile.c	(r��vision 5261)
+++ src/keyfile.c	(copie de travail)
@@ -115,6 +115,8 @@
 	configuration_add_pref_group(group, TRUE);
 	stash_group_add_entry(group, &prefs.default_open_path,
 		"default_open_path", "", "startup_path_entry");
+	stash_group_add_boolean(group, &prefs.per_workspace_instances,
+		"per_workspace_instances", FALSE);
 
 	stash_group_add_toggle_button(group, &file_prefs.cmdline_new_files,
 		"cmdline_new_files", TRUE, "check_cmdline_new_files");
Index: src/prefs.h
===================================================================
--- src/prefs.h	(r��vision 5261)
+++ src/prefs.h	(copie de travail)
@@ -36,6 +36,7 @@
 	gboolean		auto_focus;
 	gchar			*default_open_path;	/**< Default path to look for files when no other path is appropriate. */
 	gchar			*custom_plugin_path;
+	gboolean		per_workspace_instances;
 }
 GeanyPrefs;
 
Index: src/socket.c
===================================================================
--- src/socket.c	(r��vision 5261)
+++ src/socket.c	(copie de travail)
@@ -88,6 +88,7 @@
 #include "utils.h"
 #include "dialogs.h"
 #include "encodings.h"
+#include "prefs.h"
 
 
 
@@ -108,6 +109,7 @@
 static gint socket_fd_open_inet		(gushort port);
 static void socket_init_win32		(void);
 #else
+static gchar *socket_get_candidate_unix	(const gchar *path);
 static gint socket_fd_connect_unix	(const gchar *path);
 static gint socket_fd_open_unix		(const gchar *path);
 #endif
@@ -285,9 +287,20 @@
 		*p = '_';
 
 	if (socket_info.file_name == NULL)
-		socket_info.file_name = g_strdup_printf("%s%cgeany_socket_%s_%s_ws%d",
-			app->configdir, G_DIR_SEPARATOR, hostname, display_name, workspace);
+	{
+		gchar *file_name;
 
+		file_name = g_strdup_printf("%s%cgeany_socket_%s_%s_ws%d",
+				app->configdir, G_DIR_SEPARATOR, hostname, display_name, workspace);
+		if (prefs.per_workspace_instances)
+			socket_info.file_name = file_name;
+		else
+		{
+			socket_info.file_name = socket_get_candidate_unix(file_name);
+			g_free(file_name);
+		}
+	}
+
 	g_free(display_name);
 	g_free(hostname);
 
@@ -355,6 +368,71 @@
 
 
 #ifdef G_OS_UNIX
+/* gets how socket name @name is close to the searched name @search. smaller
+ * values means closer result. */
+static gint socket_candidate_level_unix(const gchar *search, const gchar *name)
+{
+	gint ret;
+	
+	while (*search && (ret = *search - *name) == 0)
+	{
+		search ++;
+		name ++;
+	}
+	
+	return ABS(ret);
+}
+
+
+/* finds out the better socket cantidate for socket path @path, and return it.
+ * if none is found, returns a copy of @path. */
+static gchar *socket_get_candidate_unix(const gchar *path)
+{
+	gchar *dirpath = g_path_get_dirname(path);
+	gchar *found = g_strdup(path);
+	GDir *dir;
+
+	dir = g_dir_open(dirpath, 0, NULL);
+	if (dir)
+	{
+		gchar *basepath = g_path_get_basename(path);
+		gint pertinance = G_MAXINT;
+		gchar *pattern;
+		gchar *p;
+		const gchar *name;
+
+		/* pattern is full socket name without workspace ID */
+		pattern = g_strdup(basepath);
+		p = utils_strrstr(pattern, "_ws");
+		if (p)
+			*(p + 3) = 0;
+
+		while ((name = g_dir_read_name(dir)) != NULL)
+		{
+			if (g_str_has_prefix(name, pattern))
+			{
+				gint name_pertinance;
+				
+				name_pertinance = socket_candidate_level_unix(basepath, name);
+				if (name_pertinance < pertinance)
+				{
+					setptr(found, g_build_filename(dirpath, name, NULL));
+					pertinance = name_pertinance;
+				}
+			}
+		}
+
+		g_free(pattern);
+		g_free(basepath);
+
+		g_dir_close(dir);
+	}
+	g_free(dirpath);
+
+	return found;
+}
+
+
 static gint socket_fd_connect_unix(const gchar *path)
 {
 	gint sock;
Index: src/utils.c
===================================================================
--- src/utils.c	(r��vision 5261)
+++ src/utils.c	(copie de travail)
@@ -702,6 +702,30 @@
 }
 
 
+/* strstr() but finds the last occurrence rather than the first one */
+gchar *utils_strrstr(const gchar *haystack, const gchar *needle)
+{
+	size_t haystack_len = strlen (haystack);
+	size_t needle_len = strlen (needle);
+	const gchar *found = NULL;
+
+	if (haystack_len >= needle_len)
+	{
+		size_t i;
+
+		for (i = 1 + haystack_len - needle_len; ! found && i > 0; i--)
+		{
+			const gchar *p = &haystack[i - 1];
+			
+			if (p[0] == needle[0] && strncmp (p, needle, needle_len) == 0)
+				found = p;
+		}
+	}
+
+	return (gchar *)found;
+}
+
+
 /**
  *  Retrieves a formatted date/time string from strftime().
  *  This function should be preferred to directly calling strftime() since this function
Index: src/utils.h
===================================================================
--- src/utils.h	(r��vision 5261)
+++ src/utils.h	(copie de travail)
@@ -159,6 +159,8 @@
 
 gint utils_strpos(const gchar* haystack, const gchar *needle);
 
+gchar *utils_strrstr(const gchar *haystack, const gchar *needle);
+
 gchar *utils_get_date_time(const gchar *format, time_t *time_to_use);
 
 gchar *utils_get_initials(const gchar *name);
