From 17ed380b576d12968ef516f8dc67c3f796d91030 Mon Sep 17 00:00:00 2001
From: Arun Prakash Jana <engineerarun@gmail.com>
Date: Mon, 12 Dec 2022 18:03:11 +0530
Subject: [PATCH] Optimize link creation

---
 src/nnn.c | 31 +++++++++++++++++++++++++------
 1 file changed, 25 insertions(+), 6 deletions(-)

diff --git a/src/nnn.c b/src/nnn.c
index 9c61a8cf..ec33aea0 100644
--- a/src/nnn.c
+++ b/src/nnn.c
@@ -1137,7 +1137,19 @@ static size_t mkpath(const char *dir, const char *name, char *out)
 {
 	size_t len = 0;
 
-	if (name[0] != '/') { // NOLINT
+	if (name[0] == '~') { //NOLINT
+		len = xstrsncpy(out, home, PATH_MAX);
+		if (!name[1])
+			return len;
+
+		if (name[1] != '/') {
+			out[0] = '\0';
+			return 0;
+		}
+
+		--len;
+		++name;
+	} else if (name[0] != '/') { // NOLINT
 		/* Handle root case */
 		len = istopdir(dir) ? 1 : xstrsncpy(out, dir, PATH_MAX);
 		out[len - 1] = '/'; // NOLINT
@@ -1275,6 +1287,8 @@ static char *abspath(const char *filepath, char *cwd, char *buf)
 	if (xstrlen(resolved_path) >= PATH_MAX) {
 		if (!buf)
 			free(resolved_path);
+		else
+			buf[0] = '\0';
 		return NULL;
 	}
 
@@ -3716,10 +3730,14 @@ static int xlink(char *prefix, char *path, char *curfname, char *buf, int type)
 		link_fn = &link;
 
 	if (choice == 'c' || (nselected == 1)) {
-		mkpath(path, prefix, lnpath); /* Generate link path */
-		mkpath(path, (choice == 'c') ? curfname : pselbuf, buf); /* Generate target file path */
+		prefix = abspath(prefix, path, lnpath); /* Generate link path */
+		if (!prefix)
+			return -1;
 
-		if (!link_fn(buf, lnpath)) {
+		if (choice == 'c')
+			mkpath(path, curfname, buf); /* Generate target file path */
+
+		if (!link_fn((choice == 'c') ? buf : pselbuf, lnpath)) {
 			if (choice == 's')
 				clearselection();
 			return 1; /* One link created */
@@ -3727,11 +3745,12 @@ static int xlink(char *prefix, char *path, char *curfname, char *buf, int type)
 		return 0;
 	}
 
+	r = xstrsncpy(buf, prefix, NAME_MAX + 1); /* Copy prefix */
+
 	while (pos < selbufpos) {
 		len = xstrlen(psel);
 		fname = xbasename(psel);
 
-		r = xstrsncpy(buf, prefix, NAME_MAX + 1); /* Copy prefix */
 		xstrsncpy(buf + r - 1, fname, NAME_MAX - r); /* Suffix target file name */
 		mkpath(path, buf, lnpath); /* Generate link path */
 
@@ -7594,7 +7613,7 @@ nochange:
 				if (r == 'f' || r == 'd')
 					tmp = xreadline(tmp, messages[MSG_NEW_PATH]);
 				else if (r == 's' || r == 'h')
-					tmp = xreadline(nselected == 1 ? xbasename(pselbuf) : NULL,
+					tmp = xreadline(NULL,
 						messages[nselected <= 1 ? MSG_NEW_PATH : MSG_LINK_PREFIX]);
 				else
 					tmp = NULL;
-- 
2.51.0