From f6f475747b09a6fd865e8d83941079739b3828af Mon Sep 17 00:00:00 2001 From: nightwing Date: Wed, 29 May 2013 00:30:05 +0400 Subject: [PATCH] style improvements --- demo/kitchen-sink/demo.js | 6 +- lib/ace/autocomplete.js | 117 ++++++++++++------ lib/ace/autocomplete/popup.js | 102 +++++++-------- lib/ace/autocomplete/text_completer.js | 106 ++++++++-------- .../{complete_util.js => util.js} | 88 +++---------- lib/ace/config.js | 4 +- lib/ace/ext/language_tools.js | 40 +++++- lib/ace/keyboard/textinput.js | 10 +- lib/ace/mode/abap.js | 2 +- tool/tmtheme.js | 1 + 10 files changed, 243 insertions(+), 233 deletions(-) rename lib/ace/autocomplete/{complete_util.js => util.js} (56%) diff --git a/demo/kitchen-sink/demo.js b/demo/kitchen-sink/demo.js index 1db21a9e..41ed5b19 100644 --- a/demo/kitchen-sink/demo.js +++ b/demo/kitchen-sink/demo.js @@ -155,7 +155,7 @@ env.editor.commands.addCommands([{ bindKey: "ctrl+enter", exec: function(editor) { try { - var r = eval(editor.getCopyText()||editor.getValue()); + var r = window.eval(editor.getCopyText()||editor.getValue()); } catch(e) { r = e; } @@ -559,7 +559,7 @@ ace.commands.bindKey("Tab", function(editor) { editor.execCommand("indent"); }) -var Autocompleter = require("ace/autocomplete").Autocomplete; -Autocompleter.addTo(env.editor) +require("ace/ext/language_tools"); + }); diff --git a/lib/ace/autocomplete.js b/lib/ace/autocomplete.js index d6ec8641..d2e8b4c7 100644 --- a/lib/ace/autocomplete.js +++ b/lib/ace/autocomplete.js @@ -31,17 +31,18 @@ define(function(require, exports, module) { "use strict"; -var Range = require("./range").Range; var HashHandler = require("./keyboard/hash_handler").HashHandler; var AcePopup = require("./autocomplete/popup").AcePopup; +var util = require("./autocomplete/util"); +var event = require("./lib/event"); var Autocomplete = function() { this.keyboardHandler = new HashHandler(); this.keyboardHandler.bindKeys(this.commands); - this.$blurListener = this.blurListener.bind(this); - this.$changeListener = this.changeListener.bind(this); - this.$mousedownListener = this.mousedownListener.bind(this); + this.blurListener = this.blurListener.bind(this); + this.changeListener = this.changeListener.bind(this); + this.mousedownListener = this.mousedownListener.bind(this); }; (function() { @@ -49,6 +50,7 @@ var Autocomplete = function() { this.popup = new AcePopup(document.body || document.documentElement); this.popup.on("click", function(e) { this.insertMatch(); + e.stop(); }.bind(this)); }; @@ -56,12 +58,12 @@ var Autocomplete = function() { if (!this.popup) this.$init(); - this.popup.setData(this.completions.filtered) + this.popup.setData(this.completions.filtered); var renderer = editor.renderer; var lineHeight = renderer.layerConfig.lineHeight; - var pos = renderer.$cursorLayer.getPixelPosition(null, true) - var rect = editor.container.getBoundingClientRect() + var pos = renderer.$cursorLayer.getPixelPosition(null, true); + var rect = editor.container.getBoundingClientRect(); pos.top += rect.top - renderer.layerConfig.offset; pos.left += rect.left; pos.left += renderer.$gutterLayer.gutterWidth; @@ -113,24 +115,26 @@ var Autocomplete = function() { case "up": row = row <= 0 ? max : row - 1; break; case "down": row = row >= max ? 0 : row + 1; break; case "start": row = 0; break; - case "end": row = max; break + case "end": row = max; break; } this.popup.setRow(row); }; - this.insertMatch = function(row) { + this.insertMatch = function(data) { this.detach(); - - if (row == undefined) - row = this.popup.getRow(); - var text = this.completions.filtered[row]; - if (text.value) - text = text.value; - - // should be good enough, otherwise we can use getDocument().removeInLine - this.editor.removeWordLeft(); - this.editor.insert(text); + if (!data) + data = this.popup.getData(this.popup.getRow()); + if (!data) + return false; + if (data.completer && data.completer.insertMatch) { + data.completer.insertMatch(this.editor); + } else { + if (data.value) + data = data.value; + this.editor.removeWordLeft(); + this.editor.insert(data); + } }; this.commands = { @@ -149,11 +153,36 @@ var Autocomplete = function() { "PageDown": function(editor) { editor.completer.popup.gotoPageUp(); } }; + this.getCompletions = function(editor, callback) { + var session = editor.getSession(); + var pos = editor.getCursorPosition(); + + var line = session.getLine(pos.row); + var prefix = util.retrievePrecedingIdentifier(line, pos.column); + + var matches = []; + util.parForEach(editor.completers, function(completer, next) { + completer.getCompletions(session, pos, prefix, function(err, results) { + if (!err) + matches = matches.concat(results); + next(); + }); + }, function() { + matches.sort(function(a, b) { + return b.score - a.score; + }); + callback(null, { + prefix: prefix, + matches: matches + }); + }); + return true; + }; + this.complete = function(editor) { if (this.editor) this.detach(); - var _self = this; this.editor = editor; if (editor.completer != this) { if (editor.completer) @@ -162,25 +191,35 @@ var Autocomplete = function() { } editor.keyBinding.addKeyboardHandler(this.keyboardHandler); - editor.on("changeSelection", this.$changeListener); - editor.on("blur", this.$blurListener); - editor.on("mousedown", this.$mousedownListener); + editor.on("changeSelection", this.changeListener); + editor.on("blur", this.blurListener); + editor.on("mousedown", this.mousedownListener); - //worker.attachToDocument(editor.session.getDocument(), {cursor: editor.getCursorPosition(), keywords: editor.session.getMode().getKeywords()}, true); - - - var matches = data.data.matches; - - if (matches.length) { - _self.completions = new FilteredList(matches); - _self.completions.setFilter("a"); - _self.openPopup(editor); - } - else { - _self.detach(); - } + this.getCompletions(this.editor, function(err, results) { + var matches = results && results.matches; + if (!matches || !matches.length) + return this.detach(); + if (matches.length == 1) + return this.insertMatch(matches[0]); + this.completions = new FilteredList(matches); + this.completions.setFilter(results.prefix); + this.openPopup(editor); + this.popup.setHighlight(results.prefix); + }.bind(this)); }; + + this.cancelContextMenu = function() { + var stop = function(e) { + this.editor.off("nativecontextmenu", stop); + if (e && e.domEvent) + event.stopEvent(e.domEvent); + }.bind(this); + setTimeout(stop, 10); + this.editor.on("nativecontextmenu", stop); + }; + + this.completers = []; }).call(Autocomplete.prototype); @@ -191,12 +230,14 @@ Autocomplete.startCommand = { editor.completer = new Autocomplete(); editor.completer.complete(editor); editor.completer.activated = true; + // needed for firefox on mac + editor.completer.cancelContextMenu(); }, bindKey: "Ctrl-Space|Shift-Space|Alt-Space" -} +}; Autocomplete.addTo = function(editor) { editor.commands.addCommand(Autocomplete.startCommand); -} +}; var FilteredList = function(array, mutateData) { this.all = array; diff --git a/lib/ace/autocomplete/popup.js b/lib/ace/autocomplete/popup.js index 374f4334..c6b401b2 100644 --- a/lib/ace/autocomplete/popup.js +++ b/lib/ace/autocomplete/popup.js @@ -33,34 +33,22 @@ define(function(require, exports, module) { var EditSession = require("../edit_session").EditSession; var Renderer = require("../virtual_renderer").VirtualRenderer; +var Editor = require("../editor").Editor; +var Range = require("../range").Range; var event = require("../lib/event"); var lang = require("../lib/lang"); var dom = require("../lib/dom"); var $singleLineEditor = function(el) { var renderer = new Renderer(el); - el.style.overflow = "hidden"; - renderer.scrollBar.element.style.top = "0"; - renderer.scrollBar.element.style.display = "none"; - renderer.scrollBar.orginalWidth = renderer.scrollBar.width; - renderer.scrollBar.width = 0; - renderer.content.style.height = "auto"; - - renderer.screenToTextCoordinates = function(x, y) { - var pos = this.pixelToScreenCoordinates(x, y); - return this.session.screenToDocumentPosition( - Math.min(this.session.getScreenLength() - 1, Math.max(pos.row, 0)), - Math.max(pos.column, 0) - ); - }; renderer.maxLines = 4; renderer.$computeLayerConfigWithScroll = renderer.$computeLayerConfig; + renderer.scrollBar.orginalWidth = renderer.scrollBar.getWidth(); renderer.$computeLayerConfig = function() { - var config = this.layerConfig; var height = this.session.getScreenLength() * this.lineHeight; - var maxHeight = this.maxLines * this.lineHeight - var desiredHeight = Math.max(this.lineHeight, Math.min(maxHeight, height)) + var maxHeight = this.maxLines * this.lineHeight; + var desiredHeight = Math.max(this.lineHeight, Math.min(maxHeight, height)); var vScroll = height > maxHeight; if (desiredHeight != this.desiredHeight || vScroll != this.$vScroll) { if (vScroll != this.$vScroll) { @@ -83,15 +71,13 @@ var $singleLineEditor = function(el) { this.container.style.height = desiredHeight + "px"; this.onResize(); - this.$loop.changes = 0 + this.$loop.changes = 0; this.desiredHeight = desiredHeight; - this.scroller.style.overflowX="hidden" + this.scroller.style.overflowX = "hidden"; } return renderer.$computeLayerConfigWithScroll(); }; - - var Editor = require("ace/editor").Editor; var editor = new Editor(renderer); editor.setHighlightActiveLine(false); @@ -121,7 +107,7 @@ var AcePopup = function(parentNode) { popup.renderer.$cursorLayer.restartTimer = noop; popup.renderer.$cursorLayer.element.style.opacity = 0; - popup.renderer.maxLines = 8 + popup.renderer.maxLines = 8; popup.renderer.$keepTextAreaAtCursor = false; popup.setHighlightActiveLine(true); @@ -134,19 +120,6 @@ var AcePopup = function(parentNode) { e.stop(); }); - popup.getRow = function() { - var line = this.getCursorPosition().row; - if (line == 0 && !this.getHighlightActiveLine()) - line = -1; - return line; - }; - - popup.setRow = function(line) { - popup.setHighlightActiveLine(line != -1); - popup.selection.clearSelection(); - popup.moveCursorTo(line, 0 || 0); - }; - var hoverMarker = new Range(-1,0,-1,Infinity); hoverMarker.id = popup.session.addMarker(hoverMarker, "ace_line-hover", "fullLine"); popup.on("mousemove", function(e) { @@ -165,14 +138,9 @@ var AcePopup = function(parentNode) { popup.on("mousewheel", function(e) { setTimeout(function() { popup._signal("mousemove", e); - }) + }); }); - popup.data = [] - popup.setData = function(list) { - popup.data = list || []; - popup.setValue(lang.stringRepeat("\n", list.length), -1); - }; popup.session.doc.getLength = function() { return popup.data.length; }; @@ -183,26 +151,51 @@ var AcePopup = function(parentNode) { return (data && data.value) || ""; }; - var bgTokenizer = popup.session.bgTokenizer + var bgTokenizer = popup.session.bgTokenizer; bgTokenizer.$tokenizeRow = function(i) { var data = popup.data[i]; var tokens = []; if (!data) return tokens; if (typeof data == "string") - data = {type: data, value: data}//return [{type: "", value: data}]; + data = {value: data}; - tokens.push({type: "", value: data.value}); - if (data.type) { + tokens.push({type: data.className || "", value: data.value}); + if (data.meta) { var maxW = popup.renderer.$size.scrollerWidth / popup.renderer.layerConfig.characterWidth; - if (data.type.length + data.value.length < maxW - 2) - tokens.push({type: "rightAlignedText", value: data.type}); + if (data.meta.length + data.value.length < maxW - 2) + tokens.push({type: "rightAlignedText", value: data.meta}); } return tokens; }; - bgTokenizer.$updateOnChange = noop + bgTokenizer.$updateOnChange = noop; + + popup.session.$computeWidth = function() { + return this.screenWidth = 0; + } + + // public + popup.data = []; + popup.setData = function(list) { + popup.data = list || []; + popup.setValue(lang.stringRepeat("\n", list.length), -1); + }; + popup.getData = function(row) { + return popup.data[row]; + }; + + popup.getRow = function() { + var line = this.getCursorPosition().row; + if (line == 0 && !this.getHighlightActiveLine()) + line = -1; + return line; + }; + popup.setRow = function(line) { + popup.setHighlightActiveLine(line != -1); + popup.selection.clearSelection(); + popup.moveCursorTo(line, 0 || 0); + }; - // highlight popup.setHighlight = function(re) { popup.session.highlight(re); popup.session._emit("changeFrontMarker"); @@ -211,24 +204,24 @@ var AcePopup = function(parentNode) { popup.hide = function() { this.container.style.display = "none"; this._signal("hide"); - } - + }; popup.show = function(pos, lineHeight) { var el = this.container; if (pos.top > window.innerHeight / 2 + lineHeight) { - el.style.top = "" + el.style.top = ""; el.style.bottom = window.innerHeight - pos.top + "px"; } else { pos.top += lineHeight; el.style.top = pos.top + "px"; - el.style.bottom = "" + el.style.bottom = ""; } el.style.left = pos.left + "px"; el.style.display = ""; this._signal("show"); - } + }; + return popup; }; @@ -257,6 +250,7 @@ dom.importCssString("\ background: #f8f8f8;\ border: 1px lightgray solid;\ position: fixed;\ + box-shadow: 2px 3px 5px rgba(0,0,0,.2);\ }"); exports.AcePopup = AcePopup; diff --git a/lib/ace/autocomplete/text_completer.js b/lib/ace/autocomplete/text_completer.js index d8d5673f..30b9352f 100644 --- a/lib/ace/autocomplete/text_completer.js +++ b/lib/ace/autocomplete/text_completer.js @@ -29,69 +29,61 @@ * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { - var completeUtil = require("./complete_util"); - var SPLIT_REGEX = /[^a-zA-Z_0-9\$]+/; - var MAX_SCORE = 1000000; + var Range = require("ace/range").Range; + + var splitRegex = /[^a-zA-Z_0-9\$\-]+/; - var completer = module.exports; - - // For the current document, gives scores to identifiers not on frequency, but on distance from the current prefix - function wordDistanceAnalyzer(doc, pos, prefix, keywords) { - var text = doc.getValue().trim(); - - // Determine cursor's word index - var textBefore = doc.getLines(0, pos.row - 1).join("\n") + "\n"; - var currentLine = doc.getLine(pos.row); - textBefore += currentLine.substr(0, pos.column); - var prefixPosition = textBefore.trim().split(SPLIT_REGEX).length - 1; - - // Split entire document into words - var identifiers = text.split(SPLIT_REGEX); - var identDict = {}; - - // Find prefix to find other identifiers close it - for (var i = 0; i < identifiers.length; i++) { - if (i === prefixPosition) - continue; - var ident = identifiers[i]; - if (ident.length === 0) - continue; - var distance = Math.max(prefixPosition, i) - Math.min(prefixPosition, i); - // Score substracted from MAX to force descending ordering - if (Object.prototype.hasOwnProperty.call(identDict, ident)) - identDict[ident] = Math.max(MAX_SCORE - distance, identDict[ident]); - else - identDict[ident] = MAX_SCORE - distance; - - } - - for (var k = 0, l = keywords.length; k < l; k++) { - identDict[keywords[k]] = MAX_SCORE; - } - - return identDict; + function getWordIndex(doc, pos) { + var textBefore = doc.getTextRange(Range.fromPoints({row: 0, column:0}, pos)); + return textBefore.split(splitRegex).length - 1; } - completer.complete = function(doc, pos, keywords, callback) { - var line = doc.getLine(pos.row); - var identifier = completeUtil.retrievePrecedingIdentifier(line, pos.column); - - // there's nothing to autocomplete - if (identifier === "") - return callback(null); - - var identDict = wordDistanceAnalyzer(doc, pos, identifier, keywords); - - var allIdentifiers = []; - for (var ident in identDict) { - allIdentifiers.push(ident); + // NOTE: Naive implementation O(n), can be O(log n) with binary search + function filterPrefix(prefix, words) { + var results = []; + for (var i = 0; i < words.length; i++) { + if (words[i].indexOf(prefix) === 0) { + results.push(words[i]); + } } + return results; + } - allIdentifiers = completeUtil.removeDuplicateWords(allIdentifiers); + /** + * Does a distance analysis of the word `prefix` at position `pos` in `doc`. + * @return Map + */ + function wordDistance(doc, pos) { + var prefixPos = getWordIndex(doc, pos); + var words = doc.getValue().split(splitRegex); + var wordScores = Object.create(null); + + var currentWord = words[prefixPos]; - // find fuzzy matches based on text in doc, as well as mode keywords - var matches = completeUtil.findCompletions(identifier, identDict, allIdentifiers); + words.forEach(function(word, idx) { + if (!word || word === currentWord) return; - callback(identifier, matches); + var distance = Math.abs(prefixPos - idx); + var score = words.length - distance; + if (wordScores[word]) { + wordScores[word] = Math.max(score, wordScores[word]); + } else { + wordScores[word] = score; + } + }); + return wordScores; + } + + exports.getCompletions = function(session, pos, prefix, callback) { + var wordScore = wordDistance(session, pos, prefix); + var wordList = filterPrefix(prefix, Object.keys(wordScore)); + callback(null, wordList.map(function(word) { + return { + name: word, + value: word, + score: wordScore[word], + meta: "local" + }; + })); }; }); \ No newline at end of file diff --git a/lib/ace/autocomplete/complete_util.js b/lib/ace/autocomplete/util.js similarity index 56% rename from lib/ace/autocomplete/complete_util.js rename to lib/ace/autocomplete/util.js index ad62393e..ae9ece5d 100644 --- a/lib/ace/autocomplete/complete_util.js +++ b/lib/ace/autocomplete/util.js @@ -29,10 +29,25 @@ * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { +"use strict"; + +exports.parForEach = function(array, fn, callback) { + var completed = 0; + var arLength = array.length; + if (arLength === 0) + callback(); + for (var i = 0; i < arLength; i++) { + fn(array[i], function(result, err) { + completed++; + if (completed === arLength) + callback(result, err); + }); + } +} var ID_REGEX = /[a-zA-Z_0-9\$]/; -function retrievePrecedingIdentifier(text, pos, regex) { +exports.retrievePrecedingIdentifier = function(text, pos, regex) { regex = regex || ID_REGEX; var buf = []; for (var i = pos-1; i >= 0; i--) { @@ -44,7 +59,7 @@ function retrievePrecedingIdentifier(text, pos, regex) { return buf.reverse().join(""); } -function retrieveFollowingIdentifier(text, pos, regex) { +exports.retrieveFollowingIdentifier = function(text, pos, regex) { regex = regex || ID_REGEX; var buf = []; for (var i = pos; i < text.length; i++) { @@ -56,73 +71,4 @@ function retrieveFollowingIdentifier(text, pos, regex) { return buf; } -// filched from jQuery -function grep( elems, callback, inv ) { - var retVal, - ret = [], - i = 0, - length = elems.length; - inv = !!inv; - - // Go through the array, only saving the items - // that pass the validator function - for ( ; i < length; i++ ) { - retVal = !!callback( elems[ i ], i ); - if ( inv !== retVal ) { - ret.push( elems[ i ] ); - } - } - - return ret; -}; - -function sortByScore(items, identDict) { - - return items.sort(function(a, b) { - var scoreA = identDict[a], - scoreB = identDict[b]; - - if (a < b) - return 1; - else if (a > b) - return -1; - else - return 0; - }); -}; - -function findCompletions(prefix, identDict, allIdentifiers) { - var _self = this, - fuzzyMatcher = function (prefix, item) { - return ~item.toLowerCase().indexOf(prefix.toLowerCase()); - }; - - var matches = grep(allIdentifiers, function (item) { - return fuzzyMatcher(prefix, item); - }); - - matches = sortByScore(matches, identDict); - - return matches; -} - -exports.removeDuplicateWords = function(matches) { - // First, sort - matches = matches.sort(); - - for (var i = 1; i < matches.length; ){ - if (matches[i - 1] == matches[i]){ - matches.splice(i, 1); - } else { - i++; - } - } - - return matches; -}; - -exports.retrievePrecedingIdentifier = retrievePrecedingIdentifier; -exports.retrieveFollowingIdentifier = retrieveFollowingIdentifier; -exports.findCompletions = findCompletions; - }); diff --git a/lib/ace/config.js b/lib/ace/config.js index db36d59f..605abe1e 100644 --- a/lib/ace/config.js +++ b/lib/ace/config.js @@ -208,7 +208,7 @@ var optionsProvider = { return; var opt = this.$options[name]; if (!opt) - return undefined; + return false; if (opt.forwardTo) return this[opt.forwardTo] && this[opt.forwardTo].setOption(name, value); @@ -220,7 +220,7 @@ var optionsProvider = { getOption: function(name) { var opt = this.$options[name]; if (!opt) - return undefined; + return false; if (opt.forwardTo) return this[opt.forwardTo] && this[opt.forwardTo].getOption(name); return opt && opt.get ? opt.get.call(this) : this["$" + name]; diff --git a/lib/ace/ext/language_tools.js b/lib/ace/ext/language_tools.js index 3aa000f1..05e00129 100644 --- a/lib/ace/ext/language_tools.js +++ b/lib/ace/ext/language_tools.js @@ -34,11 +34,47 @@ define(function(require, exports, module) { var snippetManager = require("../snippets").snippetManager; var Autocomplete = require("../autocomplete").Autocomplete; -var completers = []; +var textCompleter = require("../autocomplete/text_completer"); + +var completers = [textCompleter]; exports.addCompleter = function(completer) { completers.push(completer); }; -exports.completers = {} +var expandSnippet = { + name: "expandSnippet", + exec: function(editor) { + var success = snippetManager.expandWithTab(editor); + if (!success) + editor.execCommand("indent"); + }, + bindKey: "tab" +} + + +var Editor = require("../editor").Editor; +require("../config").defineOptions(Editor.prototype, "editor", { + enableBasicAutocompletion: { + set: function(val) { + if (val) { + this.completers = completers + this.commands.addCommand(Autocomplete.startCommand); + } else { + this.commands.removeCommand(Autocomplete.startCommand); + } + }, + value: true + }, + enableSnippets: { + set: function(val) { + if (val) { + this.commands.addCommand(expandSnippet); + } else { + this.commands.removeCommand(expandSnippet); + } + }, + value: true + } +}); }); \ No newline at end of file diff --git a/lib/ace/keyboard/textinput.js b/lib/ace/keyboard/textinput.js index e7fbab5b..1309c295 100644 --- a/lib/ace/keyboard/textinput.js +++ b/lib/ace/keyboard/textinput.js @@ -40,8 +40,8 @@ var BROKEN_SETDATA = useragent.isChrome < 18; var TextInput = function(parentNode, host) { var text = dom.createElement("textarea"); text.className = "ace_text-input"; - /*/ debug - text.style.cssText = "opacity:1;background:rgba(0, 250, 0, 0.3);outline:rgba(0, 250, 0, 0.8) solid 1px;outline-offset:3px;width:5em;z-index:500"; + // debug + text.style.cssText = "opacity:1;background:rgba(0, 250, 0, 0.3);outline:rgba(0, 250, 0, 0.8) solid 1px;outline-offset:3px;width:5em;z-pindex:500"; /**/ if (useragent.isTouchPad) text.setAttribute("x-palm-disable-auto-cap", true); @@ -436,10 +436,10 @@ var TextInput = function(parentNode, host) { tempStyle = text.style.cssText; text.style.cssText = "z-index:100000;" + (useragent.isIE ? "opacity:0.1;" : ""); - // text.style.cssText += "background:rgba(250, 0, 0, 0.3); opacity:1;"; + text.style.cssText += "background:rgba(250, 0, 0, 0.3); opacity:1;"; resetSelection(host.selection.isEmpty()); - host._emit("nativecontextmenu", {target: host}); + host._emit("nativecontextmenu", {target: host, domEvent: e}); var rect = host.container.getBoundingClientRect(); var style = dom.computedStyle(host.container); var top = rect.top + (parseInt(style.borderTopWidth) || 0); @@ -477,7 +477,7 @@ var TextInput = function(parentNode, host) { } // firefox fires contextmenu event after opening it - if (!useragent.isGecko) { + if (!useragent.isGecko || useragent.isMac) { event.addListener(text, "contextmenu", function(e) { host.textInput.onContextMenu(e); onContextMenuClose(); diff --git a/lib/ace/mode/abap.js b/lib/ace/mode/abap.js index 53cd9532..fbd8066a 100644 --- a/lib/ace/mode/abap.js +++ b/lib/ace/mode/abap.js @@ -41,7 +41,7 @@ var oop = require("../lib/oop"); function Mode() { var highlighter = new Rules(); this.$tokenizer = new Tokenizer(highlighter.getRules()); - this.$keywordList = new Rules(rules.$keywordList); + this.$keywordList = new Rules(highlighter.$keywordList); this.foldingRules = new FoldMode(); } diff --git a/tool/tmtheme.js b/tool/tmtheme.js index 7bfc07ea..c01fb16f 100755 --- a/tool/tmtheme.js +++ b/tool/tmtheme.js @@ -247,6 +247,7 @@ var themes = { "pastel_on_dark": "Pastels on Dark", "solarized_dark": "Solarized-dark", "solarized_light": "Solarized-light", + "katzenmilch": "Katzenmilch", //"textmate": "Textmate (Mac Classic)", "tomorrow": "Tomorrow", "tomorrow_night": "Tomorrow-Night",