Yet another completion engine powered by git grep
git grep
を使った補完エンジン
git-complete
provides an interactive command which, when invoked,
scans the current git project with git grep
and suggests what you
may want to insert.
git-complete
CAN:
- complete not just a symbol but the whole idiom if appropreate, unlike other completion engines (rather like snippet engines)
- be used as an “omni (smart) completion” engine, i.e.
git-complete
tries to suggest expressions you may want to insert next, even when you don’t remember it, by grepping your project (class methods after a class name, typical argument for a function, for examples) - be used with no per-language configurations or dictionaries, unlike snippet engines or omni-completion engines
git-complete
CAN’T:
- complete expressions which has not been used in the git project yet
- start completion automatically, since it’s a bit laggy to git grep over the git repo (especially for the first invokation in the project)
- be 100% accurate, since
git-complete
has no knowledge about the language you are coding in
EXTRA FEATURES:
- “autopair”
git-complete
(optionally) tries to keep the parenthesis balance by inserting or deleting some parens if appropreate
- DWIM newline insertion
git-complete
tries to insert newline after completion if you may want so
The git grep
idea is taken from auto-programming.el
by hitode909.
https://github.com/hitode909/emacs-auto-programming
- Atom version:
atom-auto-programming
by the author ofauto-programming.el
- Vim version:
vim-auto-programming
by haya14busa
(require 'git-complete)
and (optionally) bind some keys.
(global-set-key (kbd "C-c C-c") 'git-complete)
(Consider “|” as the cursor in following examples)
Open a file under a git repo, and M-x git-complete
- after a part of a package name (frequently used in your project)
SHA|
completes the import statement.
use Digest::SHA; |
- after a constructor
var foo = moment().|
suggests method names frequently used in your project.
var foo = moment().format(|
and
M-x git-complete
(again) suggests typical arguments to the method frequently used in your project.var foo = moment().format("YYYY-MM-DD HH:mm:ss"|
- after a complete line
use strict; |
suggests the next line which usually follows “use strict;” in your project.
use strict; use warnings; |
git-complete-enable-autopair
: either git-complete should keep the parenthesis balance during completiongit-complete-ignore-case
: either to use--ignore-case
option or not when git grepping
See “How it works” section for details:
git-complete-omni-completion-threshold
git-complete-line-completion-threshold
git-complete-next-line-completion-threshold
git-complete-repeat-line-completion
git-complete-repeat-omni-completion
There are (internally) three completion methods in git-complete.
- line completion
- next-line completion
- omni completion
and chosen as follows:
- current line has no characters before the cursor ?
- yes -> try “next-line completion”
- no -> try “line completion”
- line completion failed -> try “omni completion”
Each completion methods works as follows:
before:
SHA| * consider "|" as the cursor
after:
use Digest::SHA; |
- Collect lines containing “SHA” in your git repo, by git grepping with “SHA”
- Find the lines frequently appears in your repo (>=2% by default:
see
git-complete-line-completion-threshold
) and suggest them- If 2. failed, try “omni completion”
- If 2. succeeded and
git-complete-repeat-line-completion
is non-nil, try “next-line completion”
before:
use strict; |
after:
use strict; use warnings; |
- Collect lines next to “use strict;” in your git repo, by git grepping with “use strict;”
- Find the lines frequently appears in your repo (>=30% by default:
see
git-complete-next-line-completion-threshold
) and suggest them- If 2. succeeded and
git-complete-repeat-line-completion
is non-nil, try “next-line” completion again
- If 2. succeeded and
before:
var foo = bar(MyClass.|)
after:
var foo = bar(MyClass.my_awesome_method|)
- Collect lines which contains “var foo = bar(MyClass.” in your git repo, by git grepping with “var foo = bar(MyClass.”
- Find the longest (described below) common substrings which
immediately follows “var foo = bar(MyClass.” and frequently appears
in your git repo (>=0.5% by default: see
git-complete-omni-completion-threshold
) and suggest them- “longest”
- if “format()” is found, for example, do not suggest “fo” as a completion candidate
- If no such substrings found, shorten the query by 1 symbol
"var foo = bar(MyClass." => "foo = bar(MyClass."
and if the shortened query still have at least 1 symbol, git grep with the shortened query again (repeat this until all symbols in the query are dropped). Otherwise completion fails.
- If completion succeeded and
git-complete-repeat-omni-completion
is non-nil, try “omni completion” again
When git-grep-enable-autopair
is non-nil, the parenthesis balance is
always kept during completion.
- Open paren
If the completion being inserted has more open parens than close parens:
query: validate| * consider | as the cursor
completion: my %params = Params::Validate::validate(@_, {
then close parens (and an empty line) are inserted automatically.
result: my %params = Params::Validate::validate(@_, { | })
- Close paren
If the completion being inserted has more close parens than open parens:
query: my_awesome_function( | )
completion: an_awesome_argument)
then the close parens in the next line is mereged into the replacement :
result: my_awesome_function( an_awesome_argument) |
If no such close paren exist in the next line, then open parens are inserted at the beginning of the replacement, instead.
query: my_awesome_function( | another_awesome_argument );
result: my_awesome_function( (an_awesome_argument) | foo );
(I’m not sure this behavior is very useful … but just to keep the balance. maybe improved in the future versions … ?)
- Open paren
If the completion being inserted has more open parens than close parens:
query: var formatted = moment.format|
completion: ("YYYY-MM-DD HH:mm:ss",
then close parens are inserted automatically (without an empty line, unlike line completion).
result: var formatted = moment.format("YYYY-MM-DD HH:mm:ss",|)
- Close paren
If the completion being inserted has more close parens than open parens:
query: var foo = my_awesome_function(|)
completion: an_awesome_argument), bra, bra, bra
then the close paren and characters outside the paren (
bra, bra, bra
) are dropped from the completion:result: var foo = my_awesome_function(an_awesome_argument|)