Improve UX, drop dead code

This commit is contained in:
Garen Torikian 2013-01-03 23:44:54 -08:00 committed by nightwing
commit cd19233b31
9 changed files with 72 additions and 246 deletions

View file

@ -55,6 +55,7 @@ var Autocomplete = function() {
this.$blurListener = this.blurListener.bind(this);
this.$changeListener = this.changeListener.bind(this);
this.$mousedownListener = this.mousedownListener.bind(this);
};
@ -127,8 +128,10 @@ var Autocomplete = function() {
};
popup.setHighlight = function(re) {
ace.session.highlight(re)
ace.session._emit("changeFrontMarker")
ace.session.highlight(re);
ace.session._emit("changeFrontMarker");
// select first item
dom.addCssClass(_self.popup.container.getElementsByClassName("ace_autocomplete")[0].childNodes[0], "autocomplete_selected");
};
this.popup = popup;
@ -166,6 +169,7 @@ var Autocomplete = function() {
this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler);
this.editor.removeEventListener("changeSelection", this.changeListener);
this.editor.removeEventListener("blur", this.changeListener);
this.editor.removeEventListener("mousedown", this.changeListener);
if (this.popup)
this.popup.container.style.display = "none";
@ -179,6 +183,16 @@ var Autocomplete = function() {
if (document.activeElement != this.editor.textInput.getElement())
this.detach();
};
this.mousedownListener = function(e) {
var mouseX = e.clientX, mouseY = e.clientY;
var newRow = this.editor.renderer.pixelToScreenCoordinates(mouseX, mouseY).row;
var currentRow = e.editor.getCursorPosition().row;
if (newRow !== currentRow) {
this.detach();
}
};
this.goTo = function(where) {
var row = this.popup.getRow();
@ -189,8 +203,8 @@ var Autocomplete = function() {
dom.removeCssClass(choices[row], "autocomplete_selected");
switch(where) {
case "up": row = row < 0 ? max : row-1; break;
case "down": row = row >= max ? -1 : row+1; break;
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
}
@ -224,7 +238,15 @@ var Autocomplete = function() {
"Return": function(editor) { editor.Autocomplete.insertMatch(); },
"Shift-Return": function(editor) { editor.Autocomplete.insertMatch(true); },
"Tab": function(editor) { editor.Autocomplete.insertMatch(); },
"Shift-Tab": function(editor) {},
"backspace": function(editor) {
var doc = editor.session.getDocument(),
cursor = editor.getCursorPosition();
editor.Autocomplete.detach();
// delete one char, and reevaluate
editor.remove("left");
editor.Autocomplete.complete(editor);
}
};
this.complete = function(editor) {
@ -242,16 +264,17 @@ var Autocomplete = function() {
editor.keyBinding.addKeyboardHandler(this.keyboardHandler);
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().$keywordList}, true);
worker.attachToDocument(editor.session.getDocument(), {cursor: editor.getCursorPosition(), keywords: editor.session.getMode().getKeywords(true)}, true);
worker.on("complete", function(data) {
var matches = data.data.matches;
_self.completions = new FilteredList(matches);
_self.completions.setFilter("a");
if (matches.length)
_self.openPopup(editor);
if (matches.length) {
_self.openPopup(editor); }
});
};
@ -328,7 +351,7 @@ var Autocomplete = function() {
};
renderer.isScrollableBy=function(){return false};
renderer.setStyle("ace_one-line");
renderer.setStyle("ace_autocomplete");
var Editor = require("ace/editor").Editor;
var editor = new Editor(renderer);

View file

@ -34,7 +34,6 @@ define(function(require, exports, module) {
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) {
@ -72,16 +71,13 @@ oop.inherits(AutocompleteWorker, Mirror);
this.onUpdate = function() {
var _self = this;
var doc = this.doc.getValue();
var doc = this.doc.getValue();
var pos = this.data.cursor;
var part = SyntaxDetector.getContextSyntaxPart(this.doc, this.data.cursor);
var language = part.language;
var currentPos = { line: pos.row, col: pos.column };
var currentNode = null;
var matches = [], ast = null;
var matches = [];
completer.complete(_self.doc, ast, this.data.cursor, this.data.keywords, currentNode, function(identifier, completions) {
completer.complete(_self.doc, this.data.cursor, this.data.keywords, function(identifier, completions) {
if (completions)
matches = matches.concat(completions);
removeDuplicateMatches(matches);

View file

@ -56,30 +56,8 @@ function findCompletions(prefix, allIdentifiers) {
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;
});

View file

@ -1,176 +0,0 @@
/**
* 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;
});

View file

@ -4,10 +4,6 @@ define(function(require, exports, module) {
var MAX_SCORE = 1000000;
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, keywords) {
@ -42,6 +38,7 @@ define(function(require, exports, module) {
for (var k = 0, l = keywords.length; k < l; k++) {
identDict[keywords[k]] = MAX_SCORE;
}
return identDict;
}
@ -53,30 +50,24 @@ define(function(require, exports, module) {
return analysisCache;
}
completer.complete = function(doc, fullAst, pos, keywords, currentNode, callback) {
var identDict = analyze(doc, pos, keywords);
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 = analyze(doc, pos, keywords);
var allIdentifiers = [];
for (var ident in identDict) {
allIdentifiers.push(ident);
}
// find matches based on text in doc
var matches = completeUtil.findCompletions(identifier, allIdentifiers);
callback(identifier, matches);
/*callback(matches.map(function(m) {
return {
name : m,
replaceText : m,
icon : null,
score : identDict[m],
meta : "",
priority : 1
};
}));*/
};
});

View file

@ -168,7 +168,7 @@ var JavaScriptHighlightRules = function() {
next : "start"
}, {
token : ["punctuation.operator", "support.function"],
regex : /(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:opzzzz|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/
regex : /(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/
}, {
token : ["punctuation.operator", "support.function.dom"],
regex : /(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/

View file

@ -326,22 +326,35 @@ var Mode = function() {
}
};
this.getKeywords = function() {
var rules = this.$tokenizer.rules;
var keywords = [];
for (var rule in rules) {
var ruleItr = rules[rule];
for (var r = 0, l = ruleItr.length; r < l; r++) {
if (typeof ruleItr[r].token === "string") {
if (/keyword/.test(ruleItr[r].token))
keywords.push(ruleItr[r].regex);
else if (/support/.test(ruleItr[r].token))
keywords.push(ruleItr[r].regex);
}
this.getKeywords = function(append) {
// this is for autocompletion to pick up regexp'ed keywords
if (!this.completionKeywords) {
var rules = this.$tokenizer.rules;
var completionKeywords = [];
for (var rule in rules) {
var ruleItr = rules[rule];
for (var r = 0, l = ruleItr.length; r < l; r++) {
if (typeof ruleItr[r].token === "string") {
if (/keyword|support|storage/.test(ruleItr[r].token))
completionKeywords.push(ruleItr[r].regex);
}
else if (typeof ruleItr[r].token === "object") {
for (var a = 0, aLength = ruleItr[r].token.length; a < aLength; a++) {
if (/keyword|support|storage/.test(ruleItr[r].token[a])) {
// drop surrounding parens
var rule = ruleItr[r].regex.match(/\(.+?\)/g)[a];
completionKeywords.push(rule.substr(1, rule.length - 2));
}
}
}
}
}
this.completionKeywords = completionKeywords;
}
return keywords.concat(this.$keywordList || []);
// this is for highlighting embed rules, like HAML/Ruby or Obj-C/C
if (!append)
return this.$keywordList;
return completionKeywords.concat(this.$keywordList || []);
};
}).call(Mode.prototype);

View file

@ -374,7 +374,7 @@ var Editor = require("./editor").Editor;
/**
* Removes the selection marker.
* @param {Range} The selection range added with [[Editor.addSelectionMarker `addSelectionMarker()`]].
* @param {Range} range The selection range added with [[Editor.addSelectionMarker `addSelectionMarker()`]].
* @method Editor.removeSelectionMarker
**/
this.removeSelectionMarker = function(range) {

View file

@ -51,6 +51,7 @@ var Mode = function() {
var highlighter = new %language%HighlightRules();
this.foldingRules = new FoldMode();
this.$tokenizer = new Tokenizer(highlighter.getRules());
this.$keywordList = highlighter.$keywordList;
};
oop.inherits(Mode, TextMode);