diff --git a/web/codemirror/addon/hint/lammps-hint.js b/web/codemirror/addon/hint/lammps-hint.js new file mode 100644 index 0000000..f952020 --- /dev/null +++ b/web/codemirror/addon/hint/lammps-hint.js @@ -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; + } +}); diff --git a/web/codemirror/mode/lammps/keywords.js b/web/codemirror/mode/lammps/keywords.js new file mode 100644 index 0000000..3363218 --- /dev/null +++ b/web/codemirror/mode/lammps/keywords.js @@ -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(" "); diff --git a/web/codemirror/mode/lammps/lammps.js b/web/codemirror/mode/lammps/lammps.js index b7c2386..a7b7457 100644 --- a/web/codemirror/mode/lammps/lammps.js +++ b/web/codemirror/mode/lammps/lammps.js @@ -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'); @@ -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; @@ -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; } @@ -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); }, diff --git a/web/index.html b/web/index.html index f7f347e..98eab6a 100644 --- a/web/index.html +++ b/web/index.html @@ -6,6 +6,7 @@ + @@ -14,10 +15,15 @@ + + + + + @@ -136,4 +142,4 @@