Skip to content

Commit

Permalink
v.4.2.0 (dynamic context-sensitive autocompletion)
Browse files Browse the repository at this point in the history
  • Loading branch information
Nikos M committed Nov 28, 2016
1 parent 987c714 commit 3c167fb
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 65 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ __Transform a JSON grammar into a CodeMirror syntax-highlight parser__



A simple and light-weight (~ 37kB minified, ~ 13kB zipped) [CodeMirror](https://github.com/marijnh/codemirror) add-on
A simple and light-weight (~ 55kB minified, ~ 18kB zipped) [CodeMirror](https://github.com/marijnh/codemirror) add-on

to generate syntax-highlight parsers (codemirror modes) from a grammar specification in JSON format.

Expand Down Expand Up @@ -55,6 +55,7 @@ Code Indentation is Codemirror default, see [Modularity and Future Directions](h
* `Grammar` can define [*action* tokens](https://github.com/foo123/editor-grammar/blob/master/grammar-reference.md#action-tokens) to perform *complex context-specific* parsing functionality, including **associated tag matching** and **duplicate identifiers** (see for example `xml.grammar` example) (**NEW feature**)
* Generated highlight modes can support **toggle comments** and **keyword autocompletion** functionality if defined in the grammar
* **Context-sensitive autocompletion** extracted directly from the grammar specification (**NEW feature**)
* **Dynamic (Context-sensitive) autocompletion** from typed user actions like code/token/symbols (**NEW feature**)
* Generated highlight modes can support **lint-like syntax-annotation** functionality generated from the grammar
* Generated highlight modes can support custom, user-defined, **code folding** functionality from the [grammar `fold` model](https://github.com/foo123/editor-grammar/blob/master/grammar-reference.md#code-folding) (**NEW feature**)
* Generated highlight modes can support custom, user-defined, **code token matching** functionality from the [grammar `match` model](https://github.com/foo123/editor-grammar/blob/master/grammar-reference.md#code-matching) (**NEW feature**)
Expand Down Expand Up @@ -186,6 +187,8 @@ CodeMirror.commands['my_autocompletion'] = function( cm ) {
xml_mode.autocompleter.options = {prefixMatch:true, caseInsensitiveMatch:false};
// or for context-sensitive autocompletion, extracted from the grammar
xml_mode.autocompleter.options = {prefixMatch:true, caseInsensitiveMatch:false, inContext:true};
// or for dynamic (context-sensitive) autocompletion, extracted from user actions
xml_mode.autocompleter.options = {prefixMatch:true, caseInsensitiveMatch:false, inContext:true|false, dynamic:true};

var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: "xml",
Expand Down Expand Up @@ -218,6 +221,7 @@ Result:
![js-recursive-grammar-autocomplete](/test/grammar-js-recursion-2.png)

![js-scoped-grammar](/test/grammar-js-scoped.png)
![js-scoped-grammar](/test/grammar-js-scoped-2.png)

![css-grammar](/test/grammar-css.png)

Expand Down
2 changes: 1 addition & 1 deletion beeld.config
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ tasks =[{}]
replace =[{}]

"@@ROOT@@" = "this"
"@@VERSION@@" = "4.1.0"
"@@VERSION@@" = "4.2.0"
"@@MODULE@@" = "CodeMirrorGrammar"

@
Expand Down
157 changes: 109 additions & 48 deletions build/codemirror_grammar.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions build/codemirror_grammar.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion editor-grammar
19 changes: 10 additions & 9 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,18 +165,19 @@ var CodeMirrorParser = Class(Parser, {

// adapted from codemirror anyword-hint helper
,autocomplete: function( cm, options, CodeMirror ) {
options = options || {};
var parser = this, list = [],
prefix_match = options[HAS]('prefixMatch') ? !!options.prefixMatch : true,
in_context = options[HAS]('inContext')? !!options.inContext : false,
dynamic = options[HAS]('dynamic')? !!options.dynamic : false,
case_insensitive_match = options[HAS]('caseInsensitiveMatch') ? !!options.caseInsensitiveMatch : false,
cur = cm.getCursor(), curLine,
start0 = cur.ch, start = start0, end0 = start0, end = end0,
token, token_i, len, maxlen = 0, word_re, renderer,
case_insensitive_match, prefix_match, in_context, sort_by_score, score;
if ( !!parser.$grammar.$autocomplete )
case_insensitive_match, prefix_match, in_context, dynamic, sort_by_score, score;
if ( dynamic || !!parser.$grammar.$autocomplete )
{
options = options || {};
word_re = options.word || RE_W; curLine = cm.getLine(cur.line);
prefix_match = options[HAS]('prefixMatch') ? !!options.prefixMatch : true;
in_context = options[HAS]('inContext')? !!options.inContext : false;
case_insensitive_match = options[HAS]('caseInsensitiveMatch') ? !!options.caseInsensitiveMatch : false;
while (start && word_re.test(curLine[CHAR](start - 1))) --start;
// operate similar to current ACE autocompleter equivalent
if ( !prefix_match ) while (end < curLine.length && word_re.test(curLine[CHAR](end))) ++end;
Expand Down Expand Up @@ -227,11 +228,11 @@ var CodeMirrorParser = Class(Parser, {
return list;
};

if ( in_context )
if ( dynamic || in_context )
{
sort_by_score = false;
list = operate(parser.autocompletion( cm.getTokenAt( CodeMirror.Pos( cur.line, start ), true ).state.state ), suggest, list);
if ( !list.length )
list = operate(parser.autocompletion( cm.getTokenAt( CodeMirror.Pos( cur.line, start ), true ).state.state, null, dynamic ), suggest, list);
if ( !list.length && !!self.$grammar.$autocomplete )
{
sort_by_score = true;
list = operate(parser.$grammar.$autocomplete, suggest, list);
Expand Down
18 changes: 17 additions & 1 deletion test/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,22 @@ function codemirror_grammar_demo(code, langs)
document.getElementById('editor-version').innerHTML = CodeMirror.version;
document.getElementById('grammar-version').innerHTML = CodeMirrorGrammar.VERSION;

if ( langs.mode )
{
var opts = {
mode: langs.mode,
lineNumbers: true,
indentUnit: 4,
indentWithTabs: false,
localVars: {},
gutters: ["CodeMirror-lint-markers", "CodeMirror-linenumbers", "CodeMirror-foldgutter"],
foldGutter: true
};
var editor = CodeMirror.fromTextArea(code, opts);
editor.setSize(null, 500);
return editor;
}

var main_lang, main_mode;

for (var i=0,l=langs.length; i<l; i++)
Expand All @@ -28,7 +44,7 @@ function codemirror_grammar_demo(code, langs)
main_mode.supportCodeMatching = true;
// enable autocomplete, have a unique cmd to not interfere with any default autocompletes
main_mode.supportAutoCompletion = true;
main_mode.autocompleter.options = {prefixMatch:true, caseInsensitiveMatch:false, inContext:true};
main_mode.autocompleter.options = {prefixMatch:true, caseInsensitiveMatch:false, inContext:true, dynamic:true};

CodeMirror.registerHelper("lint", main_lang, main_mode.linter);
CodeMirror.registerHelper("fold", main_mode.foldType, main_mode.folder);
Expand Down
Binary file added test/grammar-js-scoped-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion test/grammars/javascript-scoped.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ var js_grammar = {
,"@paren:action" : {"push":")"}
,"@bracket:action" : {"push":"]"}
,"@close:action" : {"pop":"$0","msg":"Brackets do not match"}
,"@define:action" : {"define":["local","$0"],"msg":false,"in-hypercontext":true}
,"@define:action" : {"define":["local","$0"],"msg":false,"in-hypercontext":true,"autocomplete":true}
,"@ifscoped:action" : {"defined":["local","$0"],"msg":false,"in-hypercontext":true}
,"@unique:action" : {"unique":["prop","$1"],"msg":"Duplicate object property \"$0\"","in-context":true}

Expand Down

0 comments on commit 3c167fb

Please sign in to comment.