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, according to the context, 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 time-consuming to grep over the project (especially for the first invokation)
- 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 parentheses balanced by inserting or merging 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)
You may also invoke git-complete with M-x git-complete
.
Note that you also need to install git
if it’s not installed yet.
(Consider “|” as the cursor in following examples)
- after a part of a package name:
SHA|
git-complete completes the import statement.
use Digest::SHA; |
- after a constructor:
var foo = moment().|
git-complete 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 newline:
use strict; |
suggests next line which usually follows the line
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 greppinggit-complete-grep-function
: function used to grep over the repo. git-complete by default usesgit grep
but you may tell git-complete to userg
instead by setting this variable to =’git-complete-ripgrep=
See “How it works” section for the options below:
git-complete-threshold
git-complete-whole-line-completion-threshold
git-complete-next-line-completion-threshold
git-complete-repeat-completion
There are three methods to collect completions:
- whole current-line completion
- omni current-line completion
- omni next-line completion
User is prompted to select one of the completions, and the selected completion is inserted to the buffer in different ways according to its type.
example:
React| * consider | as the cursor
- Collect lines with “React” in your git repo, by
git grep
-ing with “React”$ git grep -F -h "React" import React from 'react'; export default class extends React.Component { export default class extends React.Component { import React from 'react'; export default class extends React.Component { import React from 'react'; import ReactDOM from 'react-dom'; export default class extends React.Component { ReactDOM.render(<MyComponent />); import React from 'react'; export default class extends React.Component { import ReactDOM from 'react-dom'; ReactDOM.render(<AnotherComponent />); ...
- If some identical lines appear “frequently” (as defined by
git-complete-whole-line-completion-threshold
), they are added to the completions list, as “whole-line” completions.| | frequency | type | +-------------------------------------------------+-----------+------------| | export default class extends React.Component{\n | 60% | whole-line | | import React from 'react';\n | 30% | whole-line | | ... | ... | ... |
example:
React| * consider | as the cursor
- Collect lines with “React” in your git repo, by
git grep
-ing with “React”$ git grep -F -h "React" import React from 'react'; export default class extends React.Component { export default class extends React.Component { import React from 'react'; export default class extends React.Component { import React from 'react'; import ReactDOM from 'react-dom'; export default class extends React.Component { ReactDOM.render(<MyComponent />); import React from 'react'; export default class extends React.Component { import ReactDOM from 'react-dom'; ReactDOM.render(<AnotherComponent />); ...
- Trim each lines found in 1. as follows:
- Find the query string (“React” in this case) inside the line and remove characters before the query and the query itself.
- If the line has more close parens than open parens, remove characters after the innermost matching close paren.
from 'react'; .Component { .Component { from 'react'; .Component { from 'react'; DOM from 'react-dom'; .Component { DOM.render(<MyComponent />); from 'react'; .Component { DOM from 'react-dom'; DOM.render(<AnotherComponent />); ...
- If some identical idioms appear “frequently” (as defined in
git-complete-threshold
) at the beginning of the lines, add the idioms to the completions list as “omni” completions.| | frequency | type | +-------------------------+-----------+------| | .Component {\n | 60% | omni | | from 'react';\n | 30% | omni | | DOM from 'react-dom';\n | 5% | omni | | DOM.render(< | 5% | omni | | ... | ... | ... |
Note that
DOM.render(<
is added to the list butDOM.render(<MyComponent />)
is not, since it does not appear “frequently”. - If no completions are found, shorten the query by one subword
(configurable via
git-cmopletion-omni-completion-type
) from the beginning andgit grep
again, then back to the step 3. .example:
var foo = bar(MyClass.|
The query
var foo = bar(MyClass.
is too specific to find some “frequent” idioms, thus shortened tofoo = bar(MyClass.
,bar(MyClass.
thenMyClass.
which may give some “frequent” idioms: method names of the classMyClass
.When the query is shortened, all completions will be type of “omni”, since the step 2. is skipped.
example:
use strict; |
- Collect lines next to
use strict;
in your git repo, by grepping withuse strict;
> git grep -F -h -A1 "use strict;" use strict; sub foo { -- use strict; use warnings; -- use strict; use warnings; -- use strict; sub bar { -- use strict; use utf8; -- ...
- Find identical lines as like the step 2. of “Whole current-line
completion”, according to
git-complete-next-line-completion-threshold
| | frequency | type | +-----------------+-----------+------| | use warnings;\n | 80% | omni | | use utf8;\n | 20% | omni | | ... | ... | ... |
- If no completions are found, shorten the query and repeat like the step 3 of “Omni current-line completion”.
example:
React|
when you select a “whole-line” completion like below:
export default class extends React.Component {\n
then
- Delete all characters in the current line
|
- Insert the completion
export default class extends React.Component { |
- Add some close parens as needed (if “autopair” feature is not disabled)
export default class extends React.Component { | }
example:
var foo = moment().format|
when you select a “omni” completion like below:
("YYYY-MM-DD HH:mm:ss",
then
- Insert the completion after the cursor
var foo = moment().format("YYYY-MM-DD HH:mm:ss",|
- Add some close parens as needed (if “autopair” feature is not
disabled) after the cursor
var foo = moment().format("YYYY-MM-DD HH:mm:ss",|)