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-completetries 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-completehas 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-completetries 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-programmingby the author ofauto-programming.el - Vim version:
vim-auto-programmingby 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-caseoption or not when git greppinggit-complete-grep-function: function used to grep over the repo. git-complete by default usesgit grepbut you may tell git-complete to userginstead by setting this variable to'git-complete-ripgrep
See “How it works” section for the options below:
git-complete-thresholdgit-complete-whole-line-completion-thresholdgit-complete-next-line-completion-thresholdgit-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 grepagain, 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",|)
