[PATCH 15/16] ls: strip common directory prefix from output

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



In GNU ls, files are printed relative to their parent directory.
We don't have such thing, so stay as close as we can.

The result is quite good. If the given pathspec is a directory prefix,
it will be stripped, strictly following GNU ls behavior. If the pathspec
has wildcards, then the command part is stripped. Usually this is the
prefix part in the pathspec.

Signed-off-by: Nguyán ThÃi Ngác Duy <pclouds@xxxxxxxxx>
---
 builtin/ls-files.c |   37 +++++++++++++++++++++++++++++++++++++
 1 files changed, 37 insertions(+), 0 deletions(-)

diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 22e0c87..bc438b2 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -710,6 +710,41 @@ static int one_match_pathspec(const char *pathspec)
 	return 0;
 }
 
+static void remove_common_prefix()
+{
+	int i, len = -1;
+	const char *s1, *s2;
+
+	if (output.nr <= 1)
+		return;
+
+	/*
+	 * Eliminate common prefix. This is caused by a prefix
+	 * pathspec like "ls builtin" or even "ls 't/t*.sh'"
+	 */
+
+	s1 = output.items[output.nr-1].string;
+	len = strlen(s1);
+	for (i = 1; i < output.nr; i++) {
+		int j = 0;
+		s1 = output.items[i-1].string;
+		s2 = output.items[i].string;
+		while (j < len && s1[j] == s2[j])
+			j++;
+		len = j;
+	}
+	while (len && s1[len] != '/')
+		len--;
+	if (len && s1[len] == '/')
+		len++;
+	if (len) {
+		for (i = 0; i < output.nr; i++) {
+			char *s = output.items[i].string;
+			memcpy(s, s+len, strlen(s) - len + 1);
+		}
+	}
+}
+
 int cmd_ls(int argc, const char **argv, const char *cmd_prefix)
 {
 	int show_pathspec;
@@ -801,6 +836,7 @@ int cmd_ls(int argc, const char **argv, const char *cmd_prefix)
 		one_matches[len] = NULL;
 		pathspec = one_matches;
 		show_files(&dir);
+		remove_common_prefix();
 		display_columns(&output, column_mode, term_columns(), 2, NULL);
 		string_list_clear(&output, 0);
 		if (dst)
@@ -821,6 +857,7 @@ int cmd_ls(int argc, const char **argv, const char *cmd_prefix)
 		if (output.nr && show_pathspec)
 			printf("%s:\n", pathspec[0]);
 
+		remove_common_prefix();
 		display_columns(&output, column_mode, term_columns(), 2, NULL);
 		string_list_clear(&output, 0);
 		if (show_pathspec && pathspecs[0])
-- 
1.7.2.2

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]