Skip to content

Commit

Permalink
First hack which implements auto-complete for pair styles and fixes
Browse files Browse the repository at this point in the history
Started implementation of the feature requested in issue #8. In addition to
context-aware auto-completion, it also learns defined group names. So they can
be selected while defining a fix.

Similar things can be done for other styles and variables.
  • Loading branch information
rbberger committed Sep 10, 2016
1 parent 0cbf5b8 commit d6e3836
Show file tree
Hide file tree
Showing 5 changed files with 253 additions and 18 deletions.
153 changes: 153 additions & 0 deletions web/codemirror/addon/hint/lammps-hint.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// LAMMPS hint by Richard Berger

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
var Pos = CodeMirror.Pos;

function forEach(arr, f) {
for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]);
}

function arrayContains(arr, item) {
if (!Array.prototype.indexOf) {
var i = arr.length;
while (i--) {
if (arr[i] === item) {
return true;
}
}
return false;
}
return arr.indexOf(item) != -1;
}

function scriptHint(editor, keywords, getToken, options) {
// Find the token at the cursor
var cur = editor.getCursor(), token = getToken(editor, cur);
if (/\b(?:string|comment)\b/.test(token.type)) return;
token.state = CodeMirror.innerMode(editor.getMode(), token.state).state;
var context = [];

if (token.state.command == 'fix') {

switch(token.state.command_tokens.length) {
case 1:
// expect ident
context.push('ident');
break;

case 2:
// expect group name
context.push('group');
break;

case 3:
// expect fix style name
context.push('fix_style');
break;
}
}

if (token.state.command == 'pair_style') {
switch(token.state.command_tokens.length) {
case 1:
// expect pair style name
context.push('pair_style');
break;
}
}


// If it's not a 'word-style' token, ignore the token.
if (!/^[\w$_\/]*$/.test(token.string)) {
token = {start: cur.ch, end: cur.ch, string: "", state: token.state,
type: token.string == "." ? "property" : null};
} else if (token.end > cur.ch) {
token.end = cur.ch;
token.string = token.string.slice(0, cur.ch - token.start);
}

var tprop = token;
// If it is a property, find out what it is a property of.
while (tprop.type == "property") {
tprop = getToken(editor, Pos(cur.line, tprop.start));
if (tprop.string != ".") return;
tprop = getToken(editor, Pos(cur.line, tprop.start));
if (!context) var context = [];
context.push(tprop);
}
return {list: getCompletions(token, context, keywords, options),
from: Pos(cur.line, token.start),
to: Pos(cur.line, token.end)};
}

function lammpsHint(editor, options) {
return scriptHint(editor, lammps_keywords,
function (e, cur) {return e.getTokenAt(cur);},
options);
};
CodeMirror.registerHelper("hint", "lammps", lammpsHint);

function getCompletions(token, context, keywords, options) {
var found = [], start = token.string;

function addLower(str) {
if (str == str.toLowerCase()) found.push(str);
}

function maybeAdd(str) {
if (str.indexOf(start) == 0) found.push(str);
}

function maybeAddLower(str) {
if (str.indexOf(start) == 0) addLower(str);
}

function gatherCompletions(obj) {
}

if (context && context.length) {
// If this is a property, see if it belongs to some object we can
// find in the current environment.
var obj = context.pop();

switch(obj) {
case 'ident':
return [];
case 'group':
if (start == '') {
return token.state.groups;
} else {
forEach(token.state.groups, maybeAdd);
}
break;
case 'fix_style':
if (start == '') {
forEach(lammps_fix_styles, addLower);
} else {
forEach(lammps_fix_styles, maybeAddLower);
}
break;
case 'pair_style':
if (start == '') {
forEach(lammps_pair_styles, addLower);
} else {
forEach(lammps_pair_styles, maybeAddLower);
}
break;
}

} else {
forEach(keywords, maybeAdd);
}
return found;
}
});
13 changes: 13 additions & 0 deletions web/codemirror/mode/lammps/keywords.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
var lammps_keywords = ('log write_restart restart dump undump thermo thermo_modify thermo_style print ' +
'include read read_restart read_data ' +
'boundary units atom_style lattice region create_box create_atoms dielectric ' +
'delete_atoms change_box dimension replicate ' +
'pair_coeff pair_style pair_modify mass velocity angle_coeff angle_style ' +
'atom_modify atom_style bond_coeff bond_style delete_bonds kspace_style ' +
'kspace_modify dihedral_style dihedral_coeff improper_style improper_coeff ' +
'min_style fix_modify run_style timestep neighbor neigh_modify fix unfix ' +
'communicate newton nthreads processors reset_timestep ' +
'minimize run variable group compute ' +
'jump next loop ' +
'equal add sub mult div ' +
'if then elif else EDGE NULL &').split(" ");
92 changes: 77 additions & 15 deletions web/codemirror/mode/lammps/lammps.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,7 @@ CodeMirror.defineMode('lammps', function() {
define('atom', 'true false all no yes');

// Keywords
define('keyword', 'log write_restart restart dump undump thermo thermo_modify thermo_style print ' +
'include read read_restart read_data ' +
'boundary units atom_style lattice region create_box create_atoms dielectric ' +
'delete_atoms change_box dimension replicate ' +
'pair_coeff pair_style pair_modify mass velocity angle_coeff angle_style ' +
'atom_modify atom_style bond_coeff bond_style delete_bonds kspace_style ' +
'kspace_modify dihedral_style dihedral_coeff improper_style improper_coeff ' +
'min_style fix_modify run_style timestep neighbor neigh_modify fix unfix ' +
'communicate newton nthreads processors reset_timestep ' +
'minimize run variable group compute ' +
'jump next loop ' +
'equal add sub mult div ' +
'if then elif else EDGE NULL &');

define_word_list('keyword', lammps_keywords);

define('builtin', 'delay every check');

Expand All @@ -59,6 +46,12 @@ CodeMirror.defineMode('lammps', function() {
var sol = stream.sol();
var ch = stream.next();

if (sol) {
state.command = null;
state.command_tokens = null;
state.command_style = null;
}

if (ch === '\\') {
stream.next();
return null;
Expand Down Expand Up @@ -90,12 +83,81 @@ CodeMirror.defineMode('lammps', function() {
if (/\d/.test(ch)) {
stream.eatWhile(/[\d\.]/);
if(stream.eol() || !/\w/.test(stream.peek())) {
if (state.command_tokens) {
state.command_tokens.push('number');
}
return 'number';
}
}
stream.eatWhile(/[\w-\/]/);
var cur = stream.current();
if (stream.peek() === '=' && /[\w\/]+/.test(cur)) return 'def';

if (cur == "fix") {
state.command_tokens = ["keyword"];
state.command = 'fix';
}

if (cur == "pair_style") {
state.command_tokens = ["keyword"];
state.command = 'pair_style';
}

if (cur == "group") {
state.command_tokens = ["keyword"];
state.command = 'group';
}

if (state.command == 'fix') {
switch(state.command_tokens.length) {
case 1:
// expect ident
if(!words.hasOwnProperty(cur)) {
state.command_tokens.push('ident');
}
break;

case 2:
// expect group name
if(cur == 'all' || !words.hasOwnProperty(cur)) {
state.command_tokens.push('group');
}
break;

case 3:
// expect fix style name
if (words.hasOwnProperty(cur) && words[cur] == 'builtin') {
state.command_tokens.push('builtin');
state.command_style = cur;
}
break;
}
}

if (state.command == 'pair_style') {
switch(state.command_tokens.length) {
case 1:
// expect pair style name
if (words.hasOwnProperty(cur) && words[cur] == 'builtin') {
state.command_tokens.push('builtin');
state.command_style = cur;
}
break;
}
}

if (state.command == 'group') {
switch(state.command_tokens.length) {
case 1:
// expect group name
if (!words.hasOwnProperty(cur)) {
state.command_tokens.push('ident');
state.groups.push(cur);
}
break;
}
}

return words.hasOwnProperty(cur) ? words[cur] : null;
}

Expand Down Expand Up @@ -143,7 +205,7 @@ CodeMirror.defineMode('lammps', function() {
};

return {
startState: function() {return {tokens:[]};},
startState: function() {return {tokens:[], groups:['all']};},
token: function(stream, state) {
return tokenize(stream, state);
},
Expand Down
8 changes: 7 additions & 1 deletion web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<link rel="stylesheet" href="codemirror/lib/codemirror.css">
<link rel="stylesheet" href="codemirror/theme/monokai.css">
<link rel="stylesheet" type="text/css" href="css/style.css">
<link rel="stylesheet" href="codemirror/addon/hint/show-hint.css">
<script src="js/jquery.min.js"></script>
<script src="js/lammps.js"> </script>
<script src="js/Detector.js"> </script>
Expand All @@ -14,10 +15,15 @@
<script src="js/md.js"> </script>

<script src="codemirror/lib/codemirror.js"></script>
<script src="codemirror/mode/lammps/keywords.js"></script>
<script src="codemirror/mode/lammps/pair_styles.js"></script>
<script src="codemirror/mode/lammps/fix_styles.js"></script>
<script src="codemirror/mode/lammps/compute_styles.js"></script>
<script src="codemirror/mode/lammps/dump_styles.js"></script>

<script src="codemirror/addon/hint/show-hint.js"></script>
<script src="codemirror/addon/hint/lammps-hint.js"></script>

<script src="codemirror/mode/lammps/lammps.js"></script>
<script src="codemirror/addon/selection/active-line.js"></script>
<script src="codemirror/addon/edit/matchbrackets.js"></script>
Expand Down Expand Up @@ -136,4 +142,4 @@
<div id="toolbar"></div>
<script src="js/Main.js"></script>
</body>
</html>
</html>
5 changes: 3 additions & 2 deletions web/js/Main.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
styleActiveLine: true,
matchBrackets: true,
viewportMargin: Infinity
viewportMargin: Infinity,
evxtraKeys: {"Ctrl-Space": "autocomplete"}
});

editor.setOption("theme", "monokai");
Expand All @@ -87,4 +88,4 @@ document.addEventListener( 'keydown', function ( event ) {

}, false );

initGL();
initGL();

0 comments on commit d6e3836

Please sign in to comment.