git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v3 5/7] completion: get rid of compgen

From
Felipe Contreras <felipe.contreras@gmail.com>
Date
Apr 10, 2013, 06:57 UTC
Message-ID
<1365577077-12648-6-git-send-email-felipe.contreras@gmail.com>
In-Reply-To
<1365577077-12648-1-git-send-email-felipe.contreras@gmail.com>

The functionality we use from compgen is not much, we can do the same manually, with drastical improvements in speed, specially when dealing with only a few words.

This patch also has the sideffect that brekage reported by Jeroen Meijer and SZEDER Gábor gets fixed because we no longer expand the resulting words.

Here are some numbers filtering N amount of words:
  == 1 ==
  original: 0.002s
  new: 0.000s
  == 10 ==
  original: 0.002s
  new: 0.000s
  == 100 ==
  original: 0.003s
  new: 0.002s
  == 1000 ==
  original: 0.012s
  new: 0.011s
  == 10000 ==
  original: 0.056s
  new: 0.066s
  == 100000 ==
  original: 2.669s
  new: 0.622s
If the results are not narrowed:
  == 1 ==
  original: 0.002s
  new: 0.000s
  == 10 ==
  original: 0.002s
  new: 0.001s
  == 100 ==
  original: 0.004s
  new: 0.004s
  == 1000 ==
  original: 0.020s
  new: 0.015s
  == 10000 ==
  original: 0.101s
  new: 0.355s
  == 100000 ==
  original: 2.850s
  new: 31.941s

So, unless 'git checkout <tab>' usually gives you more than 100000 results, you'll get an improvement :)

Other possible solutions perform better after 1000 words, but worst if less than that:

  COMPREPLY=($(awk -v cur="$3" -v pre="$2" -v suf="$4"
	'$0 ~ cur { print pre$0suf }' <<< "$1" ))
  COMPREPLY=($(printf -- "$2%s$4\n" $1 | grep "^$2$3"))
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/completion/git-completion.bash | 15 ++++++++++-----
 t/t9902-completion.sh                  |  6 +++---
 2 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 90b54ab..d8009f5 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -197,11 +197,16 @@ fi
 
 __gitcompadd ()
 {
-	COMPREPLY=($(compgen -W "$1" -P "$2" -S "$4" -- "$3"))
+	local i=0
+	for x in $1; do
+		if [[ "$x" == "$3"* ]]; then
+			COMPREPLY[i++]="$2$x$4"
+		fi
+	done
 }
 
-# Generates completion reply with compgen, appending a space to possible
-# completion words, if necessary.
+# Generates completion reply, appending a space to possible completion words,
+# if necessary.
 # It accepts 1 to 4 arguments:
 # 1: List of possible completion words.
 # 2: A prefix to be added to each possible completion word (optional).
@@ -221,8 +226,8 @@ __gitcomp ()
 	esac
 }
 
-# Generates completion reply with compgen from newline-separated possible
-# completion words by appending a space to all of them.
+# Generates completion reply from newline-separated possible completion words
+# by appending a space to all of them.
 # It accepts 1 to 4 arguments:
 # 1: List of possible completion words, separated by a single newline.
 # 2: A prefix to be added to each possible completion word (optional).
diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index b752f4d..6d9d141 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -165,7 +165,7 @@ test_expect_success '__gitcomp - suffix' '
 	EOF
 '
 
-test_expect_failure '__gitcomp - doesnt fail because of invalid variable name' '
+test_expect_success '__gitcomp - doesnt fail because of invalid variable name' '
 	__gitcomp "$invalid_variable_name"
 '
 
@@ -204,7 +204,7 @@ test_expect_success '__gitcomp_nl - no suffix' '
 	EOF
 '
 
-test_expect_failure '__gitcomp_nl - doesnt fail because of invalid variable name' '
+test_expect_success '__gitcomp_nl - doesnt fail because of invalid variable name' '
 	__gitcomp_nl "$invalid_variable_name"
 '
 
@@ -332,7 +332,7 @@ test_expect_success 'complete tree filename with spaces' '
 	EOF
 '
 
-test_expect_failure 'complete tree filename with metacharacters' '
+test_expect_success 'complete tree filename with metacharacters' '
 	echo content >"name with \${meta}" &&
 	git add . &&
 	git commit -m meta &&
-- 
1.8.2.1
Previous: Felipe ContrerasNext: Eric Sunshine
Message 10 of 20 in “completion: reorg and performance improvements”
  1. 0/7 completion: reorg and performance improvementsFelipe Contreras, Apr 10, 2013
  2. 1/7 completion: trivial test improvementFelipe Contreras, Apr 10, 2013
  3. 2/7 completion: get rid of empty COMPREPLY assignmentsFelipe Contreras, Apr 10, 2013
  4. Eric SunshineApr 10, 2013
  5. 3/7 completion: add new __gitcompadd helperFelipe Contreras, Apr 10, 2013
  6. Junio C HamanoApr 12, 2013
  7. Felipe ContrerasApr 12, 2013
  8. Junio C HamanoApr 12, 2013
  9. 4/7 completion: add __gitcomp_nl testsFelipe Contreras, Apr 10, 2013
  10. 5/7 completion: get rid of compgenFelipe Contreras, Apr 10, 2013
  11. Eric SunshineApr 10, 2013
  12. Felipe ContrerasApr 10, 2013
  13. John KeepingApr 10, 2013
  14. Junio C HamanoApr 12, 2013
  15. 6/7 completion: get rid of __gitcomp_1Felipe Contreras, Apr 10, 2013
  16. Eric SunshineApr 10, 2013
  17. John KeepingApr 10, 2013
  18. Eric SunshineApr 10, 2013
  19. 7/7 completion: small optimizationFelipe Contreras, Apr 10, 2013
  20. Junio C HamanoApr 12, 2013

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.