2015-10-02 5 views
1

Я пытаюсь написать мой модуль owm, для нашего собственного языка скриптов для codemirror.Right знаю, что я вишу на наших ключевых словах.Codemirror: Собственные ключевые слова модуля

У меня есть этот тест-код:

Window(EditWin, SELECT_MULTIPLE, NO_SIZE, 310, 87, 500, 60, T("Sitzungsdatum", "Session date")) 
{ 
    Prompt(SessionDatePmt, 11, 4, T("Sitzungsdatum", "Session date")) 
    Date(SessionDate, 175, 4, 88) 

    Button(SystemDateAsSessionDateBtn, 290, 3, 190, 10, T("Übernehme Systemdatum", "Get system date")) 
    [ SELECT: SystemObject Call(SystemDate) PutObject(, SessionDate) ] 
} 

И некоторые наши слова являются:

  • Window
  • SELECT_MULTIPLE
  • NO_SIZE
  • Подскажите
  • Дата
  • Кнопка
  • Выберите
  • SystemObject
  • Вызов
  • PutObject

Для моего регулярного выражения, я использую массив, называемые минусы, со всеми ключевыми словами.

Тогда я присоединиться все entrys массив так:

var keywordRegex = new RegExp("\\b(("+cons.join(")|(")+"))\\b"); 

До там все работает отлично. Регулярное выражение, которое я получаю, работает в обычном javascript match(). Я даже извлек текст своего сайта с помощью jQuery, а затем использовал регулярное выражение и получил то, что хотел.

Но, когда я делаю:

if (stream.match(keywordRegex)) return 'keyword'; 

в CodeMirror, дата SESSIONDATE подобран тоже.

Вот весь мой режим CodeMirror:

(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) { 
    "use strict"; 
    CodeMirror.defineMode("testmode", function() { 
     var cons = ['Window', 'SELECT_MULTIPLE', 'NO_SIZE', 'PROMPT', 'Date', 'Button', 'Select', 'SystemObject', 'Call', 'PutObject']; 
     var keywordRegex = new RegExp("\\b(("+cons.join(")|(")+"))\\b"); 
     var numLiteral = /(-|\+)?([0-9]+(\.[0-9]*)?|0x[0-9a-f]+)/; 
     return { 
      token: function(stream, state) { 
       if (stream.match(/^('([^']|\\.)*'?|"([^"]|\\.)*"?)/)) 
        return "string"; 


       if (stream.match(keywordRegex)) return 'keyword'; 
       if (stream.match(/({|})/)) return "bracket"; 
       if (stream.match(numLiteral)) return "number"; 
       if (stream.match(/(->)/)) return "arrow"; 


       stream.next(); 
       return null; 
      }, 
      startState: function() { 
       return { 
       pair: false, 
       pairStart: false, 
       keyCol: 0, 
       inlinePairs: 0, 
       inlineList: 0, 
       literal: false, 
       escaped: false 
       }; 
      } 
     }; 
    }); 

    CodeMirror.defineMIME("application/testmode", "testmode"); 
}); 

Edit:

Как просили, вот рабочий plunker:

http://plnkr.co/edit/bPyuJd?p=preview

Там вы можете видеть, я дон «У вас есть ключевое слово« SessionDate », но из-за ключевого слова« Дата »также выделяется« Дата »SessionDate.

+0

Просто дикое предположение: вы потребляете char по символу для каждого токена. Не следует ли привязать 'keywordRegex' (и все остальные) к'^'? – Mariano

+0

Я добавил рабочий пример в соответствии с запросом. «^» для начала строки или строки тоже не решает мою проблему: /, но спасибо за попытку! : D – Griessbrei

+0

Попробуйте 'var keywordRegex = новый RegExp (" \\ b (("+ cons.join (") | (") +")) \\ b (?! [^()] * \\)) "); ', он просто избежит выделения внутри круглых скобок. Не уверен, что вам нужно именно это. –

ответ

2

Кажется, я нашел способ его решить. Существует no support for anchors in Code Mirror:

(^ регулярное_выражение маркер не работает, как и следовало ожидать в этот контекст из-за ограничений в RegExp API в JavaScript.)

Таким образом, использование 2 регэкспы для начала строки состояния и позиции в середине строки, и для позиции запуска из-строки, проверьте положение с stream.sol():

var keywordRegex = new RegExp("("+cons.join("|")+")(?=\\W)"); 
var midkeywordRegex = new RegExp("\\W("+cons.join("|")+")(?=\\W)"); 

... 

if (stream.sol() && stream.match(/('([^']|\\.)*'?|"([^"]|\\.)*"?)/)) 
    return "iv-string"; 

if (stream.sol() && stream.match(keywordRegex)) return 'keyword'; 
if (stream.match(midkeywordRegex)) return 'keyword'; 

См Updated plunker

+0

Единственный недостаток заключается в том, что начальный символ не-слова также будет выделен. Если это не пробел, это может быть не очень приятно, но я не вижу способа сделать это лучше на этом этапе. –

+0

Хороший улов! Еще один элемент в списке JavaScript dont. – Mariano

+0

Он работает в моем случае, спасибо вам большое! – Griessbrei