Browse Source

Implement language aware code highlight

Lucas de Souza 4 years ago
parent
commit
b8ffaf6bf5

+ 3 - 0
css/ivprog-editor.css

@@ -0,0 +1,3 @@
+.CodeMirror {
+  height: 100% !important;
+}

+ 5 - 5
js/iassign-integration-functions.js

@@ -455,11 +455,11 @@ function prepareTableSettings (div_el) {
 
   div_el.append('<h4 class="ui header">'+LocalizedStrings.getUI('text_teacher_data_types')+'</h4>');
   div_el.append('<form name="settings_data_types"><div class="ui stackable five column grid">'
-    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="integer_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('integer')+'</label></div></div>'
-    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="real_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('real')+'</label></div></div>'
-    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="text_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text')+'</label></div></div>'
-    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="boolean_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('boolean')+'</label></div></div>'
-    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="void_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('void')+'</label></div></div>'
+    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="integer_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('type_integer')+'</label></div></div>'
+    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="real_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('type_real')+'</label></div></div>'
+    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="text_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('type_text')+'</label></div></div>'
+    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="boolean_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('type_boolean')+'</label></div></div>'
+    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="void_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('type_void')+'</label></div></div>'
     +'</div></form>');
 
   div_el.append('<h4 class="ui header">'+LocalizedStrings.getUI('text_teacher_commands')+'</h4>');

+ 14 - 19
js/util/editorMode2.js

@@ -1,11 +1,6 @@
-(function (mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("codemirror/lib/codemirror"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["codemirror/lib/codemirror"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function (CodeMirror) {
+import { getCodeEditorModeConfig } from "./utils";
+
+export function CodeEditorMode (CodeMirror) {
   "use strict";
 
   function Context(indented, column, type, info, align, prev) {
@@ -266,13 +261,13 @@
       return words.propertyIsEnumerable(word);
     }
   }
-  var ivprogKeywords =  "programa E OU nao senao se " +
-    "enquanto faca pare para retorne funcao const " +
-    "contrario caso escolha";
+  const codeConfig = getCodeEditorModeConfig();
+
+  var ivprogKeywords =  codeConfig.keywords.join(" ");
 
   // Do not use this. Use the cTypes function below. This is global just to avoid
   // excessive calls when cTypes is being called multiple times during a parse.
-  var basicTypes = words("inteiro logico cadeia real vazio");
+  var basicTypes = words(codeConfig.types.join(" "));
 
   // Returns true if identifier is a "C" type.
   // C type is defined as those that are reserved by the compiler (basicTypes),
@@ -282,7 +277,7 @@
     return contains(basicTypes, identifier);
   }
 
-  var ivprogBlockKeywords = "programa caso escolha contrario faca enquanto para se senao";
+  var ivprogBlockKeywords = codeConfig.blocks.join(" ");
   var ivprogDefKeywords = "funcao const";
 
   function def(mimes, mode) {
@@ -304,7 +299,7 @@
     for (var i = 0; i < mimes.length; ++i)
       CodeMirror.defineMIME(mimes[i], mode);
   }
-
+  
   def(["text/x-ivprog"], {
     name: "ivprog",
     keywords: words(ivprogKeywords),
@@ -312,11 +307,11 @@
     blockKeywords: words(ivprogBlockKeywords),
     defKeywords: words(ivprogDefKeywords),
     typeFirstDefinitions: true,
-    atoms: words("verdadeiro falso"),
-    switchKeyword: "escolha",
-    caseKeyword: "caso",
-    defaultKeyword: "contrario",
+    atoms: words(codeConfig.atoms.join(" ")),
+    switchKeyword: codeConfig.switchString,
+    caseKeyword: codeConfig.case_default[0],
+    defaultKeyword: codeConfig.case_default[1],
     modeProps: { fold: ["brace"] }
   });
 
-});
+}

+ 66 - 0
js/util/utils.js

@@ -149,3 +149,69 @@ function fillCache () {
     }
   }
 }
+
+export function getCodeEditorModeConfig () {
+  const blockList = ["RK_SWITCH", "RK_PROGRAM","RK_CASE","RK_DEFAULT","RK_FOR",
+    "RK_FUNCTION","RK_DO","RK_WHILE","RK_IF","RK_ELSE"]
+  const keywordsList = [,"RK_CONST","RK_RETURN","RK_BREAK"];
+  const typeList = ["RK_REAL","RK_VOID","RK_BOOLEAN","RK_STRING","RK_INTEGER"];
+  const atomList = ["RK_FALSE", "RK_TRUE"];
+
+  const case_default = [];
+  const blocks = [];
+  const keywords = [];
+  const types = [];
+  const atoms = []
+  let switchString = "";
+
+  cacheMainList = [];
+  const lexerClass = LanguageService.getCurrentLexer();
+  const nullLexer = new lexerClass();
+  blockList.forEach( v => {
+    const keyword = nullLexer.literalNames[lexerClass[v]];
+    const value = keyword.substring(1, keyword.length-1);
+    cacheMainList.push(value);
+    keywords.push(value);
+    blocks.push(value);
+    if(v == "RK_SWITCH") {
+      switchString = value;
+    } else if (v == "RK_CASE" || v == "RK_DEFAULT") {
+      case_default.push(value);
+    }
+  });
+  keywordsList.forEach( v => {
+    const keyword = nullLexer.literalNames[lexerClass[v]];
+    const value = keyword.substring(1, keyword.length-1);
+    cacheMainList.push(value);
+    keywords.push(value);
+  });
+  typeList.forEach(v => {
+    const keyword = nullLexer.literalNames[lexerClass[v]];
+    const value = keyword.substring(1, keyword.length-1);
+    cacheMainList.push(value);
+    types.push(value);
+  })
+  atomList.forEach( v => {
+    const keyword = nullLexer.literalNames[lexerClass[v]];
+    const value = keyword.substring(1, keyword.length-1);
+    cacheMainList.push(value);
+    atoms.push(value);
+  })
+  
+  cacheOp = []
+  const logicOpList = [Operators.AND.value, Operators.OR.value, Operators.NOT.value];
+  for (let op = 0; op < logicOpList.length; ++op) {
+    const lOp = `logic_operator_${logicOpList[op]}`;
+    const value = LocalizedStrings.getUI(lOp);
+    cacheOp.push(value)
+    keywords.push(value);
+  }
+  return {
+    case_default: case_default,
+    atoms: atoms,
+    keywords: keywords,
+    switchString: switchString,
+    types: types,
+    blocks: blocks
+  }
+}

+ 3 - 1
js/visualUI/text_editor.js

@@ -4,7 +4,8 @@ import "codemirror/addon/edit/matchbrackets";
 // import "codemirror/addon/hint/show-hint";
 // import "codemirror/addon/hint/anyword-hint";
 import "codemirror/addon/selection/active-line";
-import "./../util/editorMode2"
+import { CodeEditorMode } from "./../util/editorMode2"
+CodeEditorMode(CodeMirror);
 
 let codeEditor = null;
 
@@ -14,6 +15,7 @@ export function initTextEditor (element) {
     id = element.substring(1);
   }
   codeEditor = CodeMirror.fromTextArea(document.getElementById(id), {
+    theme: "ttcn",
     value: "",
     mode: "text/x-ivprog",
     indentUnit: 4,

+ 4 - 7
templates/index.html

@@ -5,10 +5,12 @@
     <title></title>
     <link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
     <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.0/semantic.min.css" integrity="sha256-9mbkOfVho3ZPXfM7W8sV2SndrGDuh7wuyLjtsWeTI1Q=" crossorigin="anonymous" />
-    <link rel="stylesheet" type="text/css" href="css/ivprog-visual-1.0.css">
-    <link rel="stylesheet" type="text/css" href="css/ivprog-term.css">
     <link rel="stylesheet" type="text/css" href="css/codemirror.css">
     <link rel="stylesheet" type="text/css" href="css/show-hint.css">
+    <link rel="stylesheet" type="text/css" href="css/ttcn.css">
+    <link rel="stylesheet" type="text/css" href="css/ivprog-visual-1.0.css">
+    <link rel="stylesheet" type="text/css" href="css/ivprog-term.css">
+    <link rel="stylesheet" type="text/css" href="css/ivprog-editor.css">
     <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"
       integrity="sha256-KM512VNnjElC30ehFwehXjx1YCHPiQkOPmqnrWtpccM="
@@ -16,11 +18,6 @@
     <script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.0/semantic.min.js" integrity="sha256-x1fC6BXl6BwnUhfQqqqC0Fd/n12wH+u8u9va6+E7xaA=" crossorigin="anonymous"></script>
     <script src="js/Sortable.js"></script>
     <script src="js/iassign-integration-functions.js"></script>
-    <style>
-      .CodeMirror {
-        height: 100% !important;
-      }
-    </style>
   </head>
   <body>
 

+ 2 - 0
webpack.config.js

@@ -59,11 +59,13 @@ module.exports = {
         {from:'js/iassign-integration-functions.js', to:path.resolve(__dirname, 'build/js')},
         {from:"css/ivprog-visual-1.0.css", to:path.resolve(__dirname, 'build/css')},
         {from:"css/ivprog-term.css", to:path.resolve(__dirname, 'build/css')},
+        {from:"css/ivprog-editor.css", to:path.resolve(__dirname, 'build/css')},
         {from:'js/Sortable.js', to:path.resolve(__dirname, 'build/js')},
         {from: 'img/trash-icon.png', to:path.resolve(__dirname, 'build/img')},
         {from:'js/jquery.json-editor.min.js', to:path.resolve(__dirname, 'build/js')},
         {from:'node_modules/codemirror/lib/codemirror.css', to:path.resolve(__dirname, 'build/css')},
         {from:'node_modules/codemirror/addon/hint/show-hint.css', to:path.resolve(__dirname, 'build/css')},
+        {from:'node_modules/codemirror/theme/ttcn.css', to:path.resolve(__dirname, 'build/css')},
         /*{from:'index.html', to:path.resolve(__dirname, 'build')},
         {from:'runner.html', to:path.resolve(__dirname, 'build')},*/
       ])