{"thread":{"id":"33455","subject":"[PATCH v3 0/7] completion: reorg and performance improvements","startedAt":"2013-04-10T06:57:50Z","lastAt":"2013-04-12T18:54:23Z","messageCount":20,"participants":["Felipe Contreras","Eric Sunshine","John Keeping","Junio C Hamano"],"isPatch":true,"patchVersion":3,"patchTotal":7},"messages":[{"id":"213747","messageId":"1365577077-12648-1-git-send-email-felipe.contreras@gmail.com","threadId":"33455","inReplyTo":null,"subject":"[PATCH v3 0/7] completion: reorg and performance improvements","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-04-10T06:57:50Z","receivedAt":"2013-04-10T06:57:50Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Hi,\n\nI sent these some time ago for comments, but I think they are ready. Basically\nsome reorganization in order to achieve some performance improvements, also,\nfix a few bugs.\n\nFelipe Contreras (7):\n  completion: trivial test improvement\n  completion: get rid of empty COMPREPLY assignments\n  completion: add new __gitcompadd helper\n  completion: add __gitcomp_nl tests\n  completion: get rid of compgen\n  completion: get rid of __gitcomp_1\n  completion: small optimization\n\n contrib/completion/git-completion.bash | 71 +++++++++++++---------------------\n t/t9902-completion.sh                  | 65 ++++++++++++++++++++++++++++++-\n 2 files changed, 90 insertions(+), 46 deletions(-)\n\n-- \n1.8.2.1\n"},{"id":"213748","messageId":"1365577077-12648-2-git-send-email-felipe.contreras@gmail.com","threadId":"33455","inReplyTo":"1365577077-12648-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v3 1/7] completion: trivial test improvement","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-04-10T06:57:51Z","receivedAt":"2013-04-10T06:57:51Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Instead of passing a dummy \"\", let's check if the last character is a\nspace, and then move the _cword accordingly.\n\nApparently we were passing \"\" all the way to compgen, which fortunately\nexpanded it to nothing.\n\nLets do the right thing though.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n t/t9902-completion.sh | 3 ++-\n 1 file changed, 2 insertions(+), 1 deletion(-)\n\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex adc1372..99d5c01 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -69,6 +69,7 @@ run_completion ()\n \tlocal -a COMPREPLY _words\n \tlocal _cword\n \t_words=( $1 )\n+\ttest \"${1: -1}\" == ' ' && _words+=('')\n \t(( _cword = ${#_words[@]} - 1 ))\n \t__git_wrap__git_main && print_comp\n }\n@@ -148,7 +149,7 @@ test_expect_success '__gitcomp - suffix' '\n '\n \n test_expect_success 'basic' '\n-\trun_completion \"git \\\"\\\"\" &&\n+\trun_completion \"git \" &&\n \t# built-in\n \tgrep -q \"^add \\$\" out &&\n \t# script\n-- \n1.8.2.1\n"},{"id":"213749","messageId":"1365577077-12648-3-git-send-email-felipe.contreras@gmail.com","threadId":"33455","inReplyTo":"1365577077-12648-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v3 2/7] completion: get rid of empty COMPREPLY assignments","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-04-10T06:57:52Z","receivedAt":"2013-04-10T06:57:52Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"There's no functional reason for those, the only purpose they are\nsupposed to serve is to say \"we don't provide any words here\", but even\nfor that it's not used consitently.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.bash | 21 ---------------------\n 1 file changed, 21 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 93eba46..2c87fd8 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -208,7 +208,6 @@ __gitcomp ()\n \n \tcase \"$cur_\" in\n \t--*=)\n-\t\tCOMPREPLY=()\n \t\t;;\n \t*)\n \t\tlocal IFS=$'\\n'\n@@ -614,7 +613,6 @@ __git_complete_remote_or_refspec ()\n \t\t\tcase \"$cmd\" in\n \t\t\tpush) no_complete_refspec=1 ;;\n \t\t\tfetch)\n-\t\t\t\tCOMPREPLY=()\n \t\t\t\treturn\n \t\t\t\t;;\n \t\t\t*) ;;\n@@ -630,7 +628,6 @@ __git_complete_remote_or_refspec ()\n \t\treturn\n \tfi\n \tif [ $no_complete_refspec = 1 ]; then\n-\t\tCOMPREPLY=()\n \t\treturn\n \tfi\n \t[ \"$remote\" = \".\" ] && remote=\n@@ -951,7 +948,6 @@ _git_am ()\n \t\t\t\"\n \t\treturn\n \tesac\n-\tCOMPREPLY=()\n }\n \n _git_apply ()\n@@ -971,7 +967,6 @@ _git_apply ()\n \t\t\t\"\n \t\treturn\n \tesac\n-\tCOMPREPLY=()\n }\n \n _git_add ()\n@@ -1031,7 +1026,6 @@ _git_bisect ()\n \t\t__gitcomp_nl \"$(__git_refs)\"\n \t\t;;\n \t*)\n-\t\tCOMPREPLY=()\n \t\t;;\n \tesac\n }\n@@ -1170,7 +1164,6 @@ _git_clone ()\n \t\treturn\n \t\t;;\n \tesac\n-\tCOMPREPLY=()\n }\n \n _git_commit ()\n@@ -1354,7 +1347,6 @@ _git_fsck ()\n \t\treturn\n \t\t;;\n \tesac\n-\tCOMPREPLY=()\n }\n \n _git_gc ()\n@@ -1365,7 +1357,6 @@ _git_gc ()\n \t\treturn\n \t\t;;\n \tesac\n-\tCOMPREPLY=()\n }\n \n _git_gitk ()\n@@ -1442,7 +1433,6 @@ _git_init ()\n \t\treturn\n \t\t;;\n \tesac\n-\tCOMPREPLY=()\n }\n \n _git_ls_files ()\n@@ -1578,7 +1568,6 @@ _git_mergetool ()\n \t\treturn\n \t\t;;\n \tesac\n-\tCOMPREPLY=()\n }\n \n _git_merge_base ()\n@@ -1891,7 +1880,6 @@ _git_config ()\n \t\treturn\n \t\t;;\n \t*.*)\n-\t\tCOMPREPLY=()\n \t\treturn\n \t\t;;\n \tesac\n@@ -2272,7 +2260,6 @@ _git_remote ()\n \t\t__gitcomp \"$c\"\n \t\t;;\n \t*)\n-\t\tCOMPREPLY=()\n \t\t;;\n \tesac\n }\n@@ -2388,8 +2375,6 @@ _git_stash ()\n \t\t*)\n \t\t\tif [ -z \"$(__git_find_on_cmdline \"$save_opts\")\" ]; then\n \t\t\t\t__gitcomp \"$subcommands\"\n-\t\t\telse\n-\t\t\t\tCOMPREPLY=()\n \t\t\tfi\n \t\t\t;;\n \t\tesac\n@@ -2402,14 +2387,12 @@ _git_stash ()\n \t\t\t__gitcomp \"--index --quiet\"\n \t\t\t;;\n \t\tshow,--*|drop,--*|branch,--*)\n-\t\t\tCOMPREPLY=()\n \t\t\t;;\n \t\tshow,*|apply,*|drop,*|pop,*|branch,*)\n \t\t\t__gitcomp_nl \"$(git --git-dir=\"$(__gitdir)\" stash list \\\n \t\t\t\t\t| sed -n -e 's/:.*//p')\"\n \t\t\t;;\n \t\t*)\n-\t\t\tCOMPREPLY=()\n \t\t\t;;\n \t\tesac\n \tfi\n@@ -2526,7 +2509,6 @@ _git_svn ()\n \t\t\t__gitcomp \"--revision= --parent\"\n \t\t\t;;\n \t\t*)\n-\t\t\tCOMPREPLY=()\n \t\t\t;;\n \t\tesac\n \tfi\n@@ -2551,13 +2533,10 @@ _git_tag ()\n \n \tcase \"$prev\" in\n \t-m|-F)\n-\t\tCOMPREPLY=()\n \t\t;;\n \t-*|tag)\n \t\tif [ $f = 1 ]; then\n \t\t\t__gitcomp_nl \"$(__git_tags)\"\n-\t\telse\n-\t\t\tCOMPREPLY=()\n \t\tfi\n \t\t;;\n \t*)\n-- \n1.8.2.1\n"},{"id":"213750","messageId":"1365577077-12648-4-git-send-email-felipe.contreras@gmail.com","threadId":"33455","inReplyTo":"1365577077-12648-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v3 3/7] completion: add new __gitcompadd helper","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-04-10T06:57:53Z","receivedAt":"2013-04-10T06:57:53Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"The idea is to never touch the COMPREPLY variable directly.\n\nThis allows other completion systems (i.e. zsh) to override\n__gitcompadd, and do something different instead.\n\nAlso, this allows further optimizations down the line.\n\nThere should be no functional changes.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.bash | 13 ++++++++-----\n 1 file changed, 8 insertions(+), 5 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 2c87fd8..90b54ab 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -195,6 +195,11 @@ _get_comp_words_by_ref ()\n }\n fi\n \n+__gitcompadd ()\n+{\n+\tCOMPREPLY=($(compgen -W \"$1\" -P \"$2\" -S \"$4\" -- \"$3\"))\n+}\n+\n # Generates completion reply with compgen, appending a space to possible\n # completion words, if necessary.\n # It accepts 1 to 4 arguments:\n@@ -211,9 +216,7 @@ __gitcomp ()\n \t\t;;\n \t*)\n \t\tlocal IFS=$'\\n'\n-\t\tCOMPREPLY=($(compgen -P \"${2-}\" \\\n-\t\t\t-W \"$(__gitcomp_1 \"${1-}\" \"${4-}\")\" \\\n-\t\t\t-- \"$cur_\"))\n+\t\t__gitcompadd \"$(__gitcomp_1 \"${1-}\" \"${4-}\")\" \"${2-}\" \"$cur_\" \"\"\n \t\t;;\n \tesac\n }\n@@ -230,7 +233,7 @@ __gitcomp ()\n __gitcomp_nl ()\n {\n \tlocal IFS=$'\\n'\n-\tCOMPREPLY=($(compgen -P \"${2-}\" -S \"${4- }\" -W \"$1\" -- \"${3-$cur}\"))\n+\t__gitcompadd \"$1\" \"${2-}\" \"${3-$cur}\" \"${4- }\"\n }\n \n # Generates completion reply with compgen from newline-separated possible\n@@ -1820,7 +1823,7 @@ _git_config ()\n \t\tlocal remote=\"${prev#remote.}\"\n \t\tremote=\"${remote%.fetch}\"\n \t\tif [ -z \"$cur\" ]; then\n-\t\t\tCOMPREPLY=(\"refs/heads/\")\n+\t\t\t__gitcompadd \"refs/heads/\"\n \t\t\treturn\n \t\tfi\n \t\t__gitcomp_nl \"$(__git_refs_remotes \"$remote\")\"\n-- \n1.8.2.1\n"},{"id":"213751","messageId":"1365577077-12648-5-git-send-email-felipe.contreras@gmail.com","threadId":"33455","inReplyTo":"1365577077-12648-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v3 4/7] completion: add __gitcomp_nl tests","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-04-10T06:57:54Z","receivedAt":"2013-04-10T06:57:54Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Original patch by SZEDER Gábor.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n t/t9902-completion.sh | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 60 insertions(+)\n\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 99d5c01..b752f4d 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -105,6 +105,23 @@ test_gitcomp ()\n \ttest_cmp expected out\n }\n \n+# Test __gitcomp_nl\n+# Arguments are:\n+# 1: current word (cur)\n+# -: the rest are passed to __gitcomp_nl\n+test_gitcomp_nl ()\n+{\n+\tlocal -a COMPREPLY &&\n+\tsed -e 's/Z$//' >expected &&\n+\tcur=\"$1\" &&\n+\tshift &&\n+\t__gitcomp_nl \"$@\" &&\n+\tprint_comp &&\n+\ttest_cmp expected out\n+}\n+\n+invalid_variable_name='${foo.bar}'\n+\n test_expect_success '__gitcomp - trailing space - options' '\n \ttest_gitcomp \"--re\" \"--dry-run --reuse-message= --reedit-message=\n \t\t--reset-author\" <<-EOF\n@@ -148,6 +165,49 @@ test_expect_success '__gitcomp - suffix' '\n \tEOF\n '\n \n+test_expect_failure '__gitcomp - doesnt fail because of invalid variable name' '\n+\t__gitcomp \"$invalid_variable_name\"\n+'\n+\n+read -r -d \"\" refs <<-\\EOF\n+maint\n+master\n+next\n+pu\n+EOF\n+\n+test_expect_success '__gitcomp_nl - trailing space' '\n+\ttest_gitcomp_nl \"m\" \"$refs\" <<-EOF\n+\tmaint Z\n+\tmaster Z\n+\tEOF\n+'\n+\n+test_expect_success '__gitcomp_nl - prefix' '\n+\ttest_gitcomp_nl \"--fixup=m\" \"$refs\" \"--fixup=\" \"m\" <<-EOF\n+\t--fixup=maint Z\n+\t--fixup=master Z\n+\tEOF\n+'\n+\n+test_expect_success '__gitcomp_nl - suffix' '\n+\ttest_gitcomp_nl \"branch.ma\" \"$refs\" \"branch.\" \"ma\" \".\" <<-\\EOF\n+\tbranch.maint.Z\n+\tbranch.master.Z\n+\tEOF\n+'\n+\n+test_expect_success '__gitcomp_nl - no suffix' '\n+\ttest_gitcomp_nl \"ma\" \"$refs\" \"\" \"ma\" \"\" <<-\\EOF\n+\tmaintZ\n+\tmasterZ\n+\tEOF\n+'\n+\n+test_expect_failure '__gitcomp_nl - doesnt fail because of invalid variable name' '\n+\t__gitcomp_nl \"$invalid_variable_name\"\n+'\n+\n test_expect_success 'basic' '\n \trun_completion \"git \" &&\n \t# built-in\n-- \n1.8.2.1\n"},{"id":"213752","messageId":"1365577077-12648-6-git-send-email-felipe.contreras@gmail.com","threadId":"33455","inReplyTo":"1365577077-12648-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v3 5/7] completion: get rid of compgen","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-04-10T06:57:55Z","receivedAt":"2013-04-10T06:57:55Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"The functionality we use from compgen is not much, we can do the same\nmanually, with drastical improvements in speed, specially when dealing\nwith only a few words.\n\nThis patch also has the sideffect that brekage reported by Jeroen Meijer\nand SZEDER Gábor gets fixed because we no longer expand the resulting\nwords.\n\nHere are some numbers filtering N amount of words:\n\n  == 1 ==\n  original: 0.002s\n  new: 0.000s\n  == 10 ==\n  original: 0.002s\n  new: 0.000s\n  == 100 ==\n  original: 0.003s\n  new: 0.002s\n  == 1000 ==\n  original: 0.012s\n  new: 0.011s\n  == 10000 ==\n  original: 0.056s\n  new: 0.066s\n  == 100000 ==\n  original: 2.669s\n  new: 0.622s\n\nIf the results are not narrowed:\n\n  == 1 ==\n  original: 0.002s\n  new: 0.000s\n  == 10 ==\n  original: 0.002s\n  new: 0.001s\n  == 100 ==\n  original: 0.004s\n  new: 0.004s\n  == 1000 ==\n  original: 0.020s\n  new: 0.015s\n  == 10000 ==\n  original: 0.101s\n  new: 0.355s\n  == 100000 ==\n  original: 2.850s\n  new: 31.941s\n\nSo, unless 'git checkout <tab>' usually gives you more than 100000\nresults, you'll get an improvement :)\n\nOther possible solutions perform better after 1000 words, but worst if\nless than that:\n\n  COMPREPLY=($(awk -v cur=\"$3\" -v pre=\"$2\" -v suf=\"$4\"\n\t'$0 ~ cur { print pre$0suf }' <<< \"$1\" ))\n\n  COMPREPLY=($(printf -- \"$2%s$4\\n\" $1 | grep \"^$2$3\"))\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.bash | 15 ++++++++++-----\n t/t9902-completion.sh                  |  6 +++---\n 2 files changed, 13 insertions(+), 8 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 90b54ab..d8009f5 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -197,11 +197,16 @@ fi\n \n __gitcompadd ()\n {\n-\tCOMPREPLY=($(compgen -W \"$1\" -P \"$2\" -S \"$4\" -- \"$3\"))\n+\tlocal i=0\n+\tfor x in $1; do\n+\t\tif [[ \"$x\" == \"$3\"* ]]; then\n+\t\t\tCOMPREPLY[i++]=\"$2$x$4\"\n+\t\tfi\n+\tdone\n }\n \n-# Generates completion reply with compgen, appending a space to possible\n-# completion words, if necessary.\n+# Generates completion reply, appending a space to possible completion words,\n+# if necessary.\n # It accepts 1 to 4 arguments:\n # 1: List of possible completion words.\n # 2: A prefix to be added to each possible completion word (optional).\n@@ -221,8 +226,8 @@ __gitcomp ()\n \tesac\n }\n \n-# Generates completion reply with compgen from newline-separated possible\n-# completion words by appending a space to all of them.\n+# Generates completion reply from newline-separated possible completion words\n+# by appending a space to all of them.\n # It accepts 1 to 4 arguments:\n # 1: List of possible completion words, separated by a single newline.\n # 2: A prefix to be added to each possible completion word (optional).\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex b752f4d..6d9d141 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -165,7 +165,7 @@ test_expect_success '__gitcomp - suffix' '\n \tEOF\n '\n \n-test_expect_failure '__gitcomp - doesnt fail because of invalid variable name' '\n+test_expect_success '__gitcomp - doesnt fail because of invalid variable name' '\n \t__gitcomp \"$invalid_variable_name\"\n '\n \n@@ -204,7 +204,7 @@ test_expect_success '__gitcomp_nl - no suffix' '\n \tEOF\n '\n \n-test_expect_failure '__gitcomp_nl - doesnt fail because of invalid variable name' '\n+test_expect_success '__gitcomp_nl - doesnt fail because of invalid variable name' '\n \t__gitcomp_nl \"$invalid_variable_name\"\n '\n \n@@ -332,7 +332,7 @@ test_expect_success 'complete tree filename with spaces' '\n \tEOF\n '\n \n-test_expect_failure 'complete tree filename with metacharacters' '\n+test_expect_success 'complete tree filename with metacharacters' '\n \techo content >\"name with \\${meta}\" &&\n \tgit add . &&\n \tgit commit -m meta &&\n-- \n1.8.2.1\n"},{"id":"213753","messageId":"1365577077-12648-7-git-send-email-felipe.contreras@gmail.com","threadId":"33455","inReplyTo":"1365577077-12648-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v3 6/7] completion: get rid of __gitcomp_1","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-04-10T06:57:56Z","receivedAt":"2013-04-10T06:57:56Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"There's no point in calling a separate function that is only used in one\nplace. Specially considering that there's no need to call compgen, and\nwe traverse the words ourselves both in __gitcompadd, and __gitcomp_1.\n\nSo lets squash the functions together, and traverse only once.\n\nThis improves performance. For N number of words:\n\n  == 1 ==\n  original: 0.002s\n  new: 0.000s\n  == 10 ==\n  original: 0.005s\n  new: 0.001s\n  == 100 ==\n  original: 0.009s\n  new: 0.006s\n  == 1000 ==\n  original: 0.027s\n  new: 0.019s\n  == 10000 ==\n  original: 0.163s\n  new: 0.151s\n  == 100000 ==\n  original: 1.555s\n  new: 1.497s\n\nNo functional changes.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.bash | 26 +++++++++++---------------\n 1 file changed, 11 insertions(+), 15 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex d8009f5..301de15 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -53,19 +53,6 @@ __gitdir ()\n \tfi\n }\n \n-__gitcomp_1 ()\n-{\n-\tlocal c IFS=$' \\t\\n'\n-\tfor c in $1; do\n-\t\tc=\"$c$2\"\n-\t\tcase $c in\n-\t\t--*=*|*.) ;;\n-\t\t*) c=\"$c \" ;;\n-\t\tesac\n-\t\tprintf '%s\\n' \"$c\"\n-\tdone\n-}\n-\n # The following function is based on code from:\n #\n #   bash_completion - programmable completion functions for bash 3.2+\n@@ -220,8 +207,17 @@ __gitcomp ()\n \t--*=)\n \t\t;;\n \t*)\n-\t\tlocal IFS=$'\\n'\n-\t\t__gitcompadd \"$(__gitcomp_1 \"${1-}\" \"${4-}\")\" \"${2-}\" \"$cur_\" \"\"\n+\t\tlocal c i=0 IFS=$' \\t\\n'\n+\t\tfor c in $1; do\n+\t\t\tc=\"$c${4-}\"\n+\t\t\tcase $c in\n+\t\t\t--*=*|*.) ;;\n+\t\t\t*) c=\"$c \" ;;\n+\t\t\tesac\n+\t\t\tif [[ $c == \"$cur_\"* ]]; then\n+\t\t\t\tCOMPREPLY[i++]=\"${2-}$c\"\n+\t\t\tfi\n+\t\tdone\n \t\t;;\n \tesac\n }\n-- \n1.8.2.1\n"},{"id":"213754","messageId":"1365577077-12648-8-git-send-email-felipe.contreras@gmail.com","threadId":"33455","inReplyTo":"1365577077-12648-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v3 7/7] completion: small optimization","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-04-10T06:57:57Z","receivedAt":"2013-04-10T06:57:57Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"No need to calculate a new $c with a space if we are not going to do\nanything it with it.\n\nThere should be no functional changes, except that a word \"foo \" with no\nsuffixes can't be matched. But $cur cannot have a space at the end\nanyway. So it's safe.\n\nBased on the code from SZEDER Gábor.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.bash | 8 ++++----\n 1 file changed, 4 insertions(+), 4 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 301de15..1666213 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -210,11 +210,11 @@ __gitcomp ()\n \t\tlocal c i=0 IFS=$' \\t\\n'\n \t\tfor c in $1; do\n \t\t\tc=\"$c${4-}\"\n-\t\t\tcase $c in\n-\t\t\t--*=*|*.) ;;\n-\t\t\t*) c=\"$c \" ;;\n-\t\t\tesac\n \t\t\tif [[ $c == \"$cur_\"* ]]; then\n+\t\t\t\tcase $c in\n+\t\t\t\t--*=*|*.) ;;\n+\t\t\t\t*) c=\"$c \" ;;\n+\t\t\t\tesac\n \t\t\t\tCOMPREPLY[i++]=\"${2-}$c\"\n \t\t\tfi\n \t\tdone\n-- \n1.8.2.1\n"},{"id":"213759","messageId":"CAPig+cR7mSiG-s4S6wgL0R4fQOuriyNndHT568WDC076NB7Z9A@mail.gmail.com","threadId":"33455","inReplyTo":"1365577077-12648-3-git-send-email-felipe.contreras@gmail.com","subject":"Re: [PATCH v3 2/7] completion: get rid of empty COMPREPLY assignments","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2013-04-10T09:47:49Z","receivedAt":"2013-04-10T09:47:49Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, Apr 10, 2013 at 2:57 AM, Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n> There's no functional reason for those, the only purpose they are\n> supposed to serve is to say \"we don't provide any words here\", but even\n> for that it's not used consitently.\n\ns/consitently/consistently/\n\n> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n"},{"id":"213760","messageId":"CAPig+cThNDvHWMq3h1Kh2QKNew0kqbXrfxcS05jrBh+rCLghzA@mail.gmail.com","threadId":"33455","inReplyTo":"1365577077-12648-6-git-send-email-felipe.contreras@gmail.com","subject":"Re: [PATCH v3 5/7] completion: get rid of compgen","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2013-04-10T10:10:28Z","receivedAt":"2013-04-10T10:10:28Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, Apr 10, 2013 at 2:57 AM, Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n> The functionality we use from compgen is not much, we can do the same\n> manually, with drastical improvements in speed, specially when dealing\n\ns/drastical/drastic/\ns/specially/especially/\n\n> with only a few words.\n>\n> This patch also has the sideffect that brekage reported by Jeroen Meijer\n\ns/sideffect/side effect/\ns/brekage/breakage/\n\n> and SZEDER Gábor gets fixed because we no longer expand the resulting\n> words.\n>\n> So, unless 'git checkout <tab>' usually gives you more than 100000\n> results, you'll get an improvement :)\n>\n> Other possible solutions perform better after 1000 words, but worst if\n\ns/worst/worse/\n\n> less than that:\n>\n>   COMPREPLY=($(awk -v cur=\"$3\" -v pre=\"$2\" -v suf=\"$4\"\n>         '$0 ~ cur { print pre$0suf }' <<< \"$1\" ))\n>\n>   COMPREPLY=($(printf -- \"$2%s$4\\n\" $1 | grep \"^$2$3\"))\n>\n> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n"},{"id":"213761","messageId":"CAPig+cR4_ZB=s8JVT2LRJGcNhM9ZaESWZQ5v6Wa20=bWGoMydg@mail.gmail.com","threadId":"33455","inReplyTo":"1365577077-12648-7-git-send-email-felipe.contreras@gmail.com","subject":"Re: [PATCH v3 6/7] completion: get rid of __gitcomp_1","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2013-04-10T10:13:06Z","receivedAt":"2013-04-10T10:13:06Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, Apr 10, 2013 at 2:57 AM, Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n> There's no point in calling a separate function that is only used in one\n> place. Specially considering that there's no need to call compgen, and\n\ns/Specially/Especially/\n\n> we traverse the words ourselves both in __gitcompadd, and __gitcomp_1.\n\ns/ourselves/ourself/\n\n> So lets squash the functions together, and traverse only once.\n\ns/lets/let's/\n\n> This improves performance. For N number of words:\n>\n>   == 1 ==\n>   original: 0.002s\n>   new: 0.000s\n>   == 10 ==\n>   original: 0.005s\n>   new: 0.001s\n>   == 100 ==\n>   original: 0.009s\n>   new: 0.006s\n>   == 1000 ==\n>   original: 0.027s\n>   new: 0.019s\n>   == 10000 ==\n>   original: 0.163s\n>   new: 0.151s\n>   == 100000 ==\n>   original: 1.555s\n>   new: 1.497s\n>\n> No functional changes.\n>\n> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n"},{"id":"213763","messageId":"CAMP44s2qnDB7Ms4-afAa9UkMA5WNzXaFTwzOCZ=cXogZmPEiGA@mail.gmail.com","threadId":"33455","inReplyTo":"CAPig+cThNDvHWMq3h1Kh2QKNew0kqbXrfxcS05jrBh+rCLghzA@mail.gmail.com","subject":"Re: [PATCH v3 5/7] completion: get rid of compgen","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-04-10T11:07:33Z","receivedAt":"2013-04-10T11:07:33Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Wed, Apr 10, 2013 at 5:10 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> s/specially/especially/\n\nhttp://www.merriam-webster.com/dictionary/specially\n\n--\nFelipe Contreras\n"},{"id":"213764","messageId":"20130410113224.GI2222@serenity.lan","threadId":"33455","inReplyTo":"CAMP44s2qnDB7Ms4-afAa9UkMA5WNzXaFTwzOCZ=cXogZmPEiGA@mail.gmail.com","subject":"Re: [PATCH v3 5/7] completion: get rid of compgen","fromName":"John Keeping","fromEmail":"john@keeping.me.uk","sentAt":"2013-04-10T11:32:24Z","receivedAt":"2013-04-10T11:32:24Z","isPatch":true,"sender":{"key":"john@keeping.me.uk","avatar":"https://avatars.githubusercontent.com/u/1702081?v=4"},"body":"On Wed, Apr 10, 2013 at 06:07:33AM -0500, Felipe Contreras wrote:\n> On Wed, Apr 10, 2013 at 5:10 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> > s/specially/especially/\n> \n> http://www.merriam-webster.com/dictionary/specially\n\nBut see also:\n\n    http://www.merriam-webster.com/dictionary/especially\n\nwhich notes \"in particular\" as a synonym, which is what makes it more\nnatural in the case under discussion here.\n"},{"id":"213765","messageId":"20130410113531.GJ2222@serenity.lan","threadId":"33455","inReplyTo":"CAPig+cR4_ZB=s8JVT2LRJGcNhM9ZaESWZQ5v6Wa20=bWGoMydg@mail.gmail.com","subject":"Re: [PATCH v3 6/7] completion: get rid of __gitcomp_1","fromName":"John Keeping","fromEmail":"john@keeping.me.uk","sentAt":"2013-04-10T11:35:31Z","receivedAt":"2013-04-10T11:35:31Z","isPatch":true,"sender":{"key":"john@keeping.me.uk","avatar":"https://avatars.githubusercontent.com/u/1702081?v=4"},"body":"On Wed, Apr 10, 2013 at 06:13:06AM -0400, Eric Sunshine wrote:\n> On Wed, Apr 10, 2013 at 2:57 AM, Felipe Contreras\n> <felipe.contreras@gmail.com> wrote:\n> > we traverse the words ourselves both in __gitcompadd, and __gitcomp_1.\n> \n> s/ourselves/ourself/\n\nHuh?  \"we traverse ... ourselves\" is correct since \"ourselves\" is\nassociated with the \"we\".  I don't think \"ourself\" is ever correct in\nnormal usage - the dictionary notes that it applies only to the \"royal\nwe\".\n"},{"id":"213796","messageId":"CAPig+cQyyokpKP8My=1j=eaa3cc50h1_rwqDmOdOkCGFesrW-A@mail.gmail.com","threadId":"33455","inReplyTo":"20130410113531.GJ2222@serenity.lan","subject":"Re: [PATCH v3 6/7] completion: get rid of __gitcomp_1","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2013-04-10T18:23:37Z","receivedAt":"2013-04-10T18:23:37Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, Apr 10, 2013 at 7:35 AM, John Keeping <john@keeping.me.uk> wrote:\n> On Wed, Apr 10, 2013 at 06:13:06AM -0400, Eric Sunshine wrote:\n>> On Wed, Apr 10, 2013 at 2:57 AM, Felipe Contreras\n>> <felipe.contreras@gmail.com> wrote:\n>> > we traverse the words ourselves both in __gitcompadd, and __gitcomp_1.\n>>\n>> s/ourselves/ourself/\n>\n> Huh?  \"we traverse ... ourselves\" is correct since \"ourselves\" is\n> associated with the \"we\".  I don't think \"ourself\" is ever correct in\n> normal usage - the dictionary notes that it applies only to the \"royal\n> we\".\n\nLate-night lapse. Thanks for the correction.\n"},{"id":"214083","messageId":"7vli8neiqi.fsf@alter.siamese.dyndns.org","threadId":"33455","inReplyTo":"1365577077-12648-4-git-send-email-felipe.contreras@gmail.com","subject":"Re: [PATCH v3 3/7] completion: add new __gitcompadd helper","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-04-12T17:55:49Z","receivedAt":"2013-04-12T17:55:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Felipe Contreras <felipe.contreras@gmail.com> writes:\n\n> The idea is to never touch the COMPREPLY variable directly.\n>\n> This allows other completion systems (i.e. zsh) to override\n> __gitcompadd, and do something different instead.\n>\n> Also, this allows further optimizations down the line.\n>\n> There should be no functional changes.\n>\n> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> ---\n>  contrib/completion/git-completion.bash | 13 ++++++++-----\n>  1 file changed, 8 insertions(+), 5 deletions(-)\n>\n> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> index 2c87fd8..90b54ab 100644\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n> @@ -195,6 +195,11 @@ _get_comp_words_by_ref ()\n>  }\n>  fi\n>  \n> +__gitcompadd ()\n> +{\n> +\tCOMPREPLY=($(compgen -W \"$1\" -P \"$2\" -S \"$4\" -- \"$3\"))\n\nMaking a mental note that this takes prefix ($2), suffix ($4) and\nthe actual word ($3) are given in addition to the list of expansions\n($1)...\n\n> +}\n> +\n>  # Generates completion reply with compgen, appending a space to possible\n>  # completion words, if necessary.\n>  # It accepts 1 to 4 arguments:\n> @@ -211,9 +216,7 @@ __gitcomp ()\n>  \t\t;;\n>  \t*)\n>  \t\tlocal IFS=$'\\n'\n> -\t\tCOMPREPLY=($(compgen -P \"${2-}\" \\\n> -\t\t\t-W \"$(__gitcomp_1 \"${1-}\" \"${4-}\")\" \\\n> -\t\t\t-- \"$cur_\"))\n> +\t\t__gitcompadd \"$(__gitcomp_1 \"${1-}\" \"${4-}\")\" \"${2-}\" \"$cur_\" \"\"\n\nThis did not use to use suffix, but we pass an empty string as $4,\nso it is an equivalent rewrite.\n\n>  \t\t;;\n>  \tesac\n>  }\n> @@ -230,7 +233,7 @@ __gitcomp ()\n>  __gitcomp_nl ()\n>  {\n>  \tlocal IFS=$'\\n'\n> -\tCOMPREPLY=($(compgen -P \"${2-}\" -S \"${4- }\" -W \"$1\" -- \"${3-$cur}\"))\n> +\t__gitcompadd \"$1\" \"${2-}\" \"${3-$cur}\" \"${4- }\"\n\nThis also is a straight-forward rewrite.\n\n>  }\n>  \n>  # Generates completion reply with compgen from newline-separated possible\n> @@ -1820,7 +1823,7 @@ _git_config ()\n>  \t\tlocal remote=\"${prev#remote.}\"\n>  \t\tremote=\"${remote%.fetch}\"\n>  \t\tif [ -z \"$cur\" ]; then\n> -\t\t\tCOMPREPLY=(\"refs/heads/\")\n> +\t\t\t__gitcompadd \"refs/heads/\"\n\nI am not sure about this one, though.\n\nOther callers took pains to protet against triggering unset variable\nreferences by using ${1-} instead of ${1}.  Shouldn't this caller be\npassing three empty strings?\n\n>  \t\t\treturn\n>  \t\tfi\n>  \t\t__gitcomp_nl \"$(__git_refs_remotes \"$remote\")\"\n"},{"id":"214084","messageId":"7vhajbei8o.fsf@alter.siamese.dyndns.org","threadId":"33455","inReplyTo":"1365577077-12648-6-git-send-email-felipe.contreras@gmail.com","subject":"Re: [PATCH v3 5/7] completion: get rid of compgen","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-04-12T18:06:31Z","receivedAt":"2013-04-12T18:06:31Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Felipe Contreras <felipe.contreras@gmail.com> writes:\n\n> Here are some numbers filtering N amount of words:\n\nNice table.  \"N amount of words\" sounded somewhat funny to me, but I\nam not a native.\n\n> ...\n>   == 1000 ==\n>   original: 0.012s\n>   new: 0.011s\n>   == 10000 ==\n>   original: 0.056s\n>   new: 0.066s\n>   == 100000 ==\n>   original: 2.669s\n>   new: 0.622s\n>\n> If the results are not narrowed:\n> ...\n>   == 1000 ==\n>   original: 0.020s\n>   new: 0.015s\n>   == 10000 ==\n>   original: 0.101s\n>   new: 0.355s\n>   == 100000 ==\n>   original: 2.850s\n>   new: 31.941s\n>\n> So, unless 'git checkout <tab>' usually gives you more than 100000\n> results, you'll get an improvement :)\n\nNice numbers.  I think you meant 10000 not 100000 here.\n\n> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> index 90b54ab..d8009f5 100644\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n> @@ -197,11 +197,16 @@ fi\n>  \n>  __gitcompadd ()\n>  {\n> -\tCOMPREPLY=($(compgen -W \"$1\" -P \"$2\" -S \"$4\" -- \"$3\"))\n> +\tlocal i=0\n> +\tfor x in $1; do\n> +\t\tif [[ \"$x\" == \"$3\"* ]]; then\n> +\t\t\tCOMPREPLY[i++]=\"$2$x$4\"\n> +\t\tfi\n> +\tdone\n>  }\n\nNice; can't be simpler than that ;-)\n"},{"id":"214086","messageId":"CAMP44s2rE2nniJhC_ZpsdNbp5uZ=tCo+wV6ygth2R5xiVTN=ng@mail.gmail.com","threadId":"33455","inReplyTo":"7vli8neiqi.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v3 3/7] completion: add new __gitcompadd helper","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-04-12T18:47:15Z","receivedAt":"2013-04-12T18:47:15Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Fri, Apr 12, 2013 at 12:55 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Felipe Contreras <felipe.contreras@gmail.com> writes:\n\n>>  }\n>>\n>>  # Generates completion reply with compgen from newline-separated possible\n>> @@ -1820,7 +1823,7 @@ _git_config ()\n>>               local remote=\"${prev#remote.}\"\n>>               remote=\"${remote%.fetch}\"\n>>               if [ -z \"$cur\" ]; then\n>> -                     COMPREPLY=(\"refs/heads/\")\n>> +                     __gitcompadd \"refs/heads/\"\n>\n> I am not sure about this one, though.\n>\n> Other callers took pains to protet against triggering unset variable\n> references by using ${1-} instead of ${1}.  Shouldn't this caller be\n> passing three empty strings?\n\nPerhaps, or perhaps we were being too careful before: 'compgen -W foo'\nis the same as 'compgen -W foo -S \"\" -P \"\" -- \"\"'.\n\n--\nFelipe Contreras\n"},{"id":"214088","messageId":"7v7gk7eg5p.fsf@alter.siamese.dyndns.org","threadId":"33455","inReplyTo":"CAMP44s2rE2nniJhC_ZpsdNbp5uZ=tCo+wV6ygth2R5xiVTN=ng@mail.gmail.com","subject":"Re: [PATCH v3 3/7] completion: add new __gitcompadd helper","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-04-12T18:51:30Z","receivedAt":"2013-04-12T18:51:30Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Felipe Contreras <felipe.contreras@gmail.com> writes:\n\n> On Fri, Apr 12, 2013 at 12:55 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>> Felipe Contreras <felipe.contreras@gmail.com> writes:\n>\n>>>  }\n>>>\n>>>  # Generates completion reply with compgen from newline-separated possible\n>>> @@ -1820,7 +1823,7 @@ _git_config ()\n>>>               local remote=\"${prev#remote.}\"\n>>>               remote=\"${remote%.fetch}\"\n>>>               if [ -z \"$cur\" ]; then\n>>> -                     COMPREPLY=(\"refs/heads/\")\n>>> +                     __gitcompadd \"refs/heads/\"\n>>\n>> I am not sure about this one, though.\n>>\n>> Other callers took pains to protet against triggering unset variable\n>> references by using ${1-} instead of ${1}.  Shouldn't this caller be\n>> passing three empty strings?\n>\n> Perhaps, or perhaps we were being too careful before: 'compgen -W foo'\n> is the same as 'compgen -W foo -S \"\" -P \"\" -- \"\"'.\n\nYes, they are the same (otherwise this patch would not be valid),\nbut that is not what i was wondering about.\n"},{"id":"214089","messageId":"7v38uveg0w.fsf@alter.siamese.dyndns.org","threadId":"33455","inReplyTo":"1365577077-12648-1-git-send-email-felipe.contreras@gmail.com","subject":"Re: [PATCH v3 0/7] completion: reorg and performance improvements","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-04-12T18:54:23Z","receivedAt":"2013-04-12T18:54:23Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"All patches in this series and the other cherry-pick one looked\nsensible, with a fix to [3/7] I suggested in the other thread about\nprotecting against \"set -u\".\n\nQueued.\n"}]}