First pass at Haurtyun UI + C9 doc parsing
This commit is contained in:
parent
e43bee07e2
commit
ef19fdbcb5
7 changed files with 511 additions and 39 deletions
|
|
@ -38,6 +38,7 @@ var UndoManager = require("ace/undomanager").UndoManager;
|
|||
var dom = require("ace/lib/dom");
|
||||
var HashHandler = require("ace/keyboard/hash_handler").HashHandler;
|
||||
var TextMode = require("ace/mode/text").Mode;
|
||||
var WorkerClient = require("./worker/worker_client").WorkerClient;
|
||||
|
||||
var mode = new TextMode();
|
||||
mode.$tokenizer = {
|
||||
|
|
@ -45,6 +46,8 @@ mode.$tokenizer = {
|
|||
|
||||
}
|
||||
};
|
||||
var worker = new WorkerClient(["ace"], "ace/autocomplete/autocomplete_worker", "AutocompleteWorker");
|
||||
|
||||
var Autocomplete = function() {
|
||||
this.keyboardHandler = new HashHandler();
|
||||
this.keyboardHandler.bindKeys(this.commands);
|
||||
|
|
@ -68,28 +71,28 @@ var Autocomplete = function() {
|
|||
el.style.display = "none"
|
||||
popup.renderer.content.style.cursor="default"
|
||||
|
||||
var nop = function(){};
|
||||
var noop = function(){};
|
||||
|
||||
popup.focus = nop;
|
||||
popup.focus = noop;
|
||||
popup.$isFocused = true;
|
||||
|
||||
popup.renderer.$cursorLayer.restartTimer = nop
|
||||
popup.renderer.$cursorLayer.update = nop
|
||||
popup.renderer.$cursorLayer.restartTimer = noop;
|
||||
popup.renderer.$cursorLayer.update = noop;
|
||||
popup.renderer.$cursorLayer.element.style.display = "none";
|
||||
|
||||
popup.renderer.maxLines = 6
|
||||
popup.renderer.$keepTextAreaAtCursor=false
|
||||
|
||||
|
||||
popup.setHighlightActiveLine(true)
|
||||
popup.setSession(new EditSession(""))
|
||||
popup.setHighlightActiveLine(true);
|
||||
popup.setSession(new EditSession(""));
|
||||
|
||||
popup.on("mousedown", function(e) {
|
||||
var pos = e.getDocumentPosition();
|
||||
popup.moveCursorToPosition(pos);
|
||||
popup.selection.clearSelection();
|
||||
e.stop();
|
||||
})
|
||||
});
|
||||
|
||||
/* popup.session.setMode({
|
||||
$
|
||||
|
|
@ -158,20 +161,6 @@ var Autocomplete = function() {
|
|||
el.style.display = "";
|
||||
};
|
||||
|
||||
this.attachToEditor = function(editor) {
|
||||
if (this.editor)
|
||||
this.detach();
|
||||
this.editor = editor;
|
||||
if (editor.Autocomplete != this) {
|
||||
if (editor.Autocomplete)
|
||||
editor.Autocomplete.detach();
|
||||
editor.Autocomplete = this;
|
||||
}
|
||||
editor.keyBinding.addKeyboardHandler(this.keyboardHandler)
|
||||
editor.on("changeSelection", this.$changeListener)
|
||||
editor.on("blur", this.$blurListener)
|
||||
};
|
||||
|
||||
this.detach = function() {
|
||||
this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler);
|
||||
this.editor.removeEventListener("changeSelection", this.changeListener);
|
||||
|
|
@ -232,20 +221,38 @@ var Autocomplete = function() {
|
|||
};
|
||||
|
||||
this.complete = function(editor) {
|
||||
this.attachToEditor(editor);
|
||||
var data = this.gatherCompletions(editor);
|
||||
this.completions = new FilteredList(data);
|
||||
this.completions.setFilter("a")
|
||||
if (data) {
|
||||
if (data.length == 1)
|
||||
this.insertMatch(0);
|
||||
else
|
||||
this.openPopup(editor);
|
||||
if (this.editor)
|
||||
this.detach();
|
||||
|
||||
var _self = this;
|
||||
this.editor = editor;
|
||||
if (editor.Autocomplete != this) {
|
||||
if (editor.Autocomplete)
|
||||
editor.Autocomplete.detach();
|
||||
editor.Autocomplete = this;
|
||||
}
|
||||
};
|
||||
|
||||
this.gatherCompletions = function() {
|
||||
return ["asdaf", "foo", "bar", "baz"];
|
||||
|
||||
editor.keyBinding.addKeyboardHandler(this.keyboardHandler);
|
||||
editor.on("changeSelection", this.$changeListener);
|
||||
editor.on("blur", this.$blurListener);
|
||||
|
||||
worker.attachToDocument(editor.session.getDocument(), {cursor: editor.getCursorPosition()});
|
||||
|
||||
worker.on("complete", function(data) {
|
||||
_self.completions = new FilteredList(data.data.matches);
|
||||
_self.completions.setFilter("a");
|
||||
|
||||
if (data) {
|
||||
if (data.length == 1)
|
||||
_self.insertMatch(0);
|
||||
else
|
||||
_self.openPopup(editor);
|
||||
}
|
||||
});
|
||||
|
||||
worker.on("terminate", function() {
|
||||
console.log("term");
|
||||
});
|
||||
};
|
||||
|
||||
this.$singleLineEditor = function(el) {
|
||||
|
|
|
|||
128
lib/ace/autocomplete/autocomplete_worker.js
Normal file
128
lib/ace/autocomplete/autocomplete_worker.js
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Distributed under the BSD license:
|
||||
*
|
||||
* Copyright (c) 2010, Ajax.org B.V.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Ajax.org B.V. nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
define(function(require, exports, module) {
|
||||
"use strict";
|
||||
|
||||
var oop = require("../lib/oop");
|
||||
var Mirror = require("../worker/mirror").Mirror;
|
||||
|
||||
var SyntaxDetector = require("./syntax_detector");
|
||||
var completer = require("./text_completer");
|
||||
|
||||
var AutocompleteWorker = exports.AutocompleteWorker = function(sender) {
|
||||
Mirror.call(this, sender);
|
||||
};
|
||||
|
||||
oop.inherits(AutocompleteWorker, Mirror);
|
||||
|
||||
(function() {
|
||||
// For code completion
|
||||
function removeDuplicateMatches(matches) {
|
||||
// First sort
|
||||
matches.sort(function(a, b) {
|
||||
if (a.name < b.name)
|
||||
return 1;
|
||||
else if (a.name > b.name)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
});
|
||||
for (var i = 0; i < matches.length - 1; i++) {
|
||||
var a = matches[i];
|
||||
var b = matches[i + 1];
|
||||
if (a.name === b.name) {
|
||||
// Duplicate!
|
||||
if (a.priority < b.priority)
|
||||
matches.splice(i, 1);
|
||||
else if (a.priority > b.priority)
|
||||
matches.splice(i+1, 1);
|
||||
else if (a.score < b.score)
|
||||
matches.splice(i, 1);
|
||||
else if (a.score > b.score)
|
||||
matches.splice(i+1, 1);
|
||||
else
|
||||
matches.splice(i, 1);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.onUpdate = function() {
|
||||
var _self = this;
|
||||
|
||||
var doc = this.doc.getValue();
|
||||
var pos = this.data.cursor;
|
||||
var part = SyntaxDetector.getContextSyntaxPart(this.doc, this.data.cursor, "javascript");
|
||||
var language = part.language;
|
||||
|
||||
var currentPos = { line: pos.row, col: pos.column };
|
||||
var currentNode = null;
|
||||
var matches = [], ast = null;
|
||||
|
||||
completer.complete(_self.doc, ast, this.data.cursor, currentNode, function(completions) {
|
||||
if (completions)
|
||||
matches = matches.concat(completions);
|
||||
removeDuplicateMatches(matches);
|
||||
// Sort by priority, score
|
||||
matches.sort(function(a, b) {
|
||||
if (a.priority < b.priority)
|
||||
return 1;
|
||||
else if (a.priority > b.priority)
|
||||
return -1;
|
||||
else if (a.score < b.score)
|
||||
return 1;
|
||||
else if (a.score > b.score)
|
||||
return -1;
|
||||
else if (a.id && a.id === b.id) {
|
||||
if (a.isFunction)
|
||||
return -1;
|
||||
else if (b.isFunction)
|
||||
return 1;
|
||||
}
|
||||
if (a.name < b.name)
|
||||
return -1;
|
||||
else if(a.name > b.name)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
});
|
||||
_self.sender.emit("complete", {
|
||||
pos: pos,
|
||||
matches: matches,
|
||||
line: _self.doc.getLine(pos.row)
|
||||
});
|
||||
return;
|
||||
});
|
||||
};
|
||||
|
||||
}).call(AutocompleteWorker.prototype);
|
||||
|
||||
});
|
||||
85
lib/ace/autocomplete/complete_util.js
Normal file
85
lib/ace/autocomplete/complete_util.js
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
define(function(require, exports, module) {
|
||||
|
||||
var ID_REGEX = /[a-zA-Z_0-9\$]/;
|
||||
|
||||
function retrievePrecedingIdentifier(text, pos, regex) {
|
||||
regex = regex || ID_REGEX;
|
||||
var buf = [];
|
||||
for (var i = pos-1; i >= 0; i--) {
|
||||
if (regex.test(text[i]))
|
||||
buf.push(text[i]);
|
||||
else
|
||||
break;
|
||||
}
|
||||
return buf.reverse().join("");
|
||||
}
|
||||
|
||||
function retrieveFollowingIdentifier(text, pos, regex) {
|
||||
regex = regex || ID_REGEX;
|
||||
var buf = [];
|
||||
for (var i = pos; i < text.length; i++) {
|
||||
if (regex.test(text[i]))
|
||||
buf.push(text[i]);
|
||||
else
|
||||
break;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
function prefixBinarySearch(items, prefix) {
|
||||
var startIndex = 0;
|
||||
var stopIndex = items.length - 1;
|
||||
var middle = Math.floor((stopIndex + startIndex) / 2);
|
||||
|
||||
while (stopIndex > startIndex && middle >= 0 && items[middle].indexOf(prefix) !== 0) {
|
||||
if (prefix < items[middle]) {
|
||||
stopIndex = middle - 1;
|
||||
}
|
||||
else if (prefix > items[middle]) {
|
||||
startIndex = middle + 1;
|
||||
}
|
||||
middle = Math.floor((stopIndex + stopIndex) / 2);
|
||||
}
|
||||
|
||||
// Look back to make sure we haven't skipped any
|
||||
while (middle > 0 && items[middle-1].indexOf(prefix) === 0)
|
||||
middle--;
|
||||
return middle >= 0 ? middle : 0; // ensure we're not returning a negative index
|
||||
}
|
||||
|
||||
function findCompletions(prefix, allIdentifiers) {
|
||||
allIdentifiers.sort();
|
||||
var startIdx = prefixBinarySearch(allIdentifiers, prefix);
|
||||
var matches = [];
|
||||
for (var i = startIdx; i < allIdentifiers.length && allIdentifiers[i].indexOf(prefix) === 0; i++)
|
||||
matches.push(allIdentifiers[i]);
|
||||
return matches;
|
||||
}
|
||||
|
||||
function fetchText(staticPrefix, path) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', staticPrefix + "/" + path, false);
|
||||
try {
|
||||
xhr.send();
|
||||
}
|
||||
// Likely we got a cross-script error (equivalent with a 404 in our cloud setup)
|
||||
catch(e) {
|
||||
return false;
|
||||
}
|
||||
if (xhr.status === 200)
|
||||
return xhr.responseText;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @deprecated Use retrievePrecedingIdentifier */
|
||||
exports.retrievePreceedingIdentifier = function() {
|
||||
console.error("Deprecated: 'retrievePreceedingIdentifier' - use 'retrievePrecedingIdentifier' instead");
|
||||
return retrievePrecedingIdentifier.apply(null, arguments);
|
||||
};
|
||||
exports.retrievePrecedingIdentifier = retrievePrecedingIdentifier;
|
||||
exports.retrieveFollowingIdentifier = retrieveFollowingIdentifier;
|
||||
exports.findCompletions = findCompletions;
|
||||
exports.fetchText = fetchText;
|
||||
|
||||
});
|
||||
176
lib/ace/autocomplete/syntax_detector.js
Normal file
176
lib/ace/autocomplete/syntax_detector.js
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
/**
|
||||
* Cloud9 Language Foundation
|
||||
*
|
||||
* @copyright 2011, Ajax.org B.V.
|
||||
* @license GPLv3 <http://www.gnu.org/licenses/gpl.txt>
|
||||
*/
|
||||
define(function(require, exports, module) {
|
||||
|
||||
var mixedLanguages = {
|
||||
php: {
|
||||
"default": "html",
|
||||
"php-start": /<\?(?:php|\=)?/,
|
||||
"php-end": /\?>/,
|
||||
"css-start": /<style[^>]*>/,
|
||||
"css-end": /<\/style>/,
|
||||
"javascript-start": /<script(?:\"[^\"]*\"|'[^']*'|[^'">\/])*>/,
|
||||
"javascript-end": /<\/script>/
|
||||
},
|
||||
html: {
|
||||
"css-start": /<style[^>]*>/,
|
||||
"css-end": /<\/style>/,
|
||||
"javascript-start": /<script(?:\"[^\"]*\"|'[^']*'|[^'">\/])*>/,
|
||||
"javascript-end": /<\/script>/
|
||||
}
|
||||
};
|
||||
|
||||
/* Now:
|
||||
* - One level syntax nesting supported
|
||||
* Future: (if worth it)
|
||||
* - Have a stack to repesent it
|
||||
* - Maintain a syntax tree for an opened file
|
||||
*/
|
||||
function getSyntaxRegions(doc, originalSyntax) {
|
||||
if (! mixedLanguages[originalSyntax])
|
||||
return [{
|
||||
syntax: originalSyntax,
|
||||
sl: 0,
|
||||
sc: 0,
|
||||
el: doc.getLength()-1,
|
||||
ec: doc.getLine(doc.getLength()-1).length
|
||||
}];
|
||||
|
||||
var lines = doc.getAllLines();
|
||||
var type = mixedLanguages[originalSyntax];
|
||||
var defaultSyntax = type["default"] || originalSyntax;
|
||||
var starters = Object.keys(type).filter(function (m) {
|
||||
return m.indexOf("-start") === m.length - 6;
|
||||
});
|
||||
var syntax = defaultSyntax;
|
||||
var regions = [{syntax: syntax, sl: 0, sc: 0}];
|
||||
var starter, endLang;
|
||||
var tempS, tempM;
|
||||
var i, m, cut, inLine = 0;
|
||||
|
||||
for (var row = 0; row < lines.length; row++) {
|
||||
var line = lines[row];
|
||||
m = null;
|
||||
if (endLang) {
|
||||
m = endLang.exec(line);
|
||||
if (m) {
|
||||
endLang = null;
|
||||
syntax = defaultSyntax;
|
||||
regions[regions.length-1].el = row;
|
||||
regions[regions.length-1].ec = m.index + inLine;
|
||||
regions.push({
|
||||
syntax: syntax,
|
||||
sl: row,
|
||||
sc: m.index + inLine
|
||||
});
|
||||
cut = m.index + m[0].length;
|
||||
lines[row] = line.substring(cut);
|
||||
inLine += cut;
|
||||
row--; // continue processing of the line
|
||||
}
|
||||
else {
|
||||
inLine = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < starters.length; i++) {
|
||||
tempS = starters[i];
|
||||
tempM = type[tempS].exec(line);
|
||||
if (tempM && (!m || m.index > tempM.index)) {
|
||||
m = tempM;
|
||||
starter = tempS;
|
||||
}
|
||||
}
|
||||
if (m) {
|
||||
syntax = starter.replace("-start", "");
|
||||
endLang = type[syntax+"-end"];
|
||||
regions[regions.length-1].el = row;
|
||||
regions[regions.length-1].ec = inLine + m.index + m[0].length;
|
||||
regions.push({
|
||||
syntax: syntax,
|
||||
sl: row,
|
||||
sc: inLine + m.index + m[0].length
|
||||
});
|
||||
cut = m.index + m[0].length;
|
||||
lines[row] = line.substring(m.index + m[0].length);
|
||||
row--; // continue processing of the line
|
||||
inLine += cut;
|
||||
}
|
||||
else {
|
||||
inLine = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
regions[regions.length-1].el = lines.length;
|
||||
regions[regions.length-1].ec = lines[lines.length-1].length;
|
||||
return regions;
|
||||
}
|
||||
|
||||
function getContextSyntaxPart(doc, pos, originalSyntax) {
|
||||
if (! mixedLanguages[originalSyntax])
|
||||
return {
|
||||
language: originalSyntax,
|
||||
value: doc.getValue(),
|
||||
region: getSyntaxRegions(doc, originalSyntax)[0],
|
||||
index: 0
|
||||
};
|
||||
var regions = getSyntaxRegions(doc, originalSyntax);
|
||||
for (var i = 0; i < regions.length; i++) {
|
||||
var region = regions[i];
|
||||
if ((pos.row > region.sl && pos.row < region.el) ||
|
||||
(pos.row === region.sl && pos.column >= region.sc) ||
|
||||
(pos.row === region.el && pos.column <= region.ec))
|
||||
return regionToCodePart(doc, region, i);
|
||||
}
|
||||
return null; // should never happen
|
||||
}
|
||||
|
||||
function getContextSyntax(doc, pos, originalSyntax) {
|
||||
var part = getContextSyntaxPart(doc, pos, originalSyntax);
|
||||
return part && part.language; // should never happen
|
||||
}
|
||||
|
||||
function regionToCodePart (doc, region, index) {
|
||||
var lines = doc.getLines(region.sl, region.el);
|
||||
return {
|
||||
value: region.sl === region.el ? lines[0].substring(region.sc, region.ec) :
|
||||
[lines[0].substring(region.sc)].concat(lines.slice(1, lines.length-1)).concat([lines[lines.length-1].substring(0, region.ec)]).join(doc.getNewLineCharacter()),
|
||||
language: region.syntax,
|
||||
region: region,
|
||||
index: index
|
||||
};
|
||||
}
|
||||
|
||||
function getCodeParts (doc, originalSyntax) {
|
||||
var regions = getSyntaxRegions(doc, originalSyntax);
|
||||
return regions.map(function (region, i) {
|
||||
return regionToCodePart(doc, region, i);
|
||||
});
|
||||
}
|
||||
|
||||
function posToRegion (region, pos) {
|
||||
return {
|
||||
row: pos.row - region.sl,
|
||||
column: pos.column
|
||||
};
|
||||
}
|
||||
|
||||
function regionToPos (region, pos) {
|
||||
return {
|
||||
row: pos.row + region.sl,
|
||||
column: pos.column
|
||||
};
|
||||
}
|
||||
|
||||
exports.getContextSyntax = getContextSyntax;
|
||||
exports.getContextSyntaxPart = getContextSyntaxPart;
|
||||
exports.getSyntaxRegions = getSyntaxRegions;
|
||||
exports.getCodeParts = getCodeParts;
|
||||
exports.posToRegion = posToRegion;
|
||||
exports.regionToPos = regionToPos;
|
||||
|
||||
});
|
||||
74
lib/ace/autocomplete/text_completer.js
Normal file
74
lib/ace/autocomplete/text_completer.js
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
define(function(require, exports, module) {
|
||||
var completeUtil = require("./complete_util");
|
||||
var SPLIT_REGEX = /[^a-zA-Z_0-9\$]+/;
|
||||
|
||||
var completer = module.exports;
|
||||
|
||||
this.handlesLanguage = function(language) {
|
||||
return true;
|
||||
};
|
||||
|
||||
// For the current document, gives scores to identifiers not on frequency, but on distance from the current prefix
|
||||
function wordDistanceAnalyzer(doc, pos, prefix) {
|
||||
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 100000 to force descending ordering
|
||||
if (Object.prototype.hasOwnProperty.call(identDict, ident))
|
||||
identDict[ident] = Math.max(1000000-distance, identDict[ident]);
|
||||
else
|
||||
identDict[ident] = 1000000-distance;
|
||||
|
||||
}
|
||||
return identDict;
|
||||
}
|
||||
|
||||
function analyze(doc, pos) {
|
||||
var line = doc.getLine(pos.row);
|
||||
var identifier = completeUtil.retrievePrecedingIdentifier(line, pos.column);
|
||||
|
||||
var analysisCache = wordDistanceAnalyzer(doc, pos, identifier);
|
||||
return analysisCache;
|
||||
}
|
||||
|
||||
completer.complete = function(doc, fullAst, pos, currentNode, callback) {
|
||||
var identDict = analyze(doc, pos);
|
||||
var line = doc.getLine(pos.row);
|
||||
var identifier = completeUtil.retrievePrecedingIdentifier(line, pos.column);
|
||||
|
||||
var allIdentifiers = [];
|
||||
for (var ident in identDict) {
|
||||
allIdentifiers.push(ident);
|
||||
}
|
||||
var matches = completeUtil.findCompletions(identifier, allIdentifiers);
|
||||
|
||||
callback(matches);
|
||||
/*callback(matches.map(function(m) {
|
||||
return {
|
||||
name : m,
|
||||
replaceText : m,
|
||||
icon : null,
|
||||
score : identDict[m],
|
||||
meta : "",
|
||||
priority : 1
|
||||
};
|
||||
}));*/
|
||||
};
|
||||
});
|
||||
|
|
@ -7,7 +7,8 @@ var lang = require("../lib/lang");
|
|||
var Mirror = exports.Mirror = function(sender) {
|
||||
this.sender = sender;
|
||||
var doc = this.doc = new Document("");
|
||||
|
||||
this.data = {};
|
||||
|
||||
var deferredUpdate = this.deferredUpdate = lang.delayedCall(this.onUpdate.bind(this));
|
||||
|
||||
var _self = this;
|
||||
|
|
@ -25,8 +26,9 @@ var Mirror = exports.Mirror = function(sender) {
|
|||
this.$timeout = timeout;
|
||||
};
|
||||
|
||||
this.setValue = function(value) {
|
||||
this.setValue = function(value, data) {
|
||||
this.doc.setValue(value);
|
||||
this.data = data;
|
||||
this.deferredUpdate.schedule(this.$timeout);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -144,12 +144,12 @@ var WorkerClient = function(topLevelNamespaces, mod, classname) {
|
|||
catch(ex) {}
|
||||
};
|
||||
|
||||
this.attachToDocument = function(doc) {
|
||||
if(this.$doc)
|
||||
this.attachToDocument = function(doc, data) {
|
||||
if (this.$doc)
|
||||
this.terminate();
|
||||
|
||||
this.$doc = doc;
|
||||
this.call("setValue", [doc.getValue()]);
|
||||
this.call("setValue", [doc.getValue(), data]);
|
||||
doc.on("change", this.changeListener);
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue