Upgraded to ace 1.1.2. Converted tokenization to use standard ace stacks. Integrated auto complete with ace standard.

Also:
Fixed history popup.
Better initialization of settings module
This commit is contained in:
Boaz Leskes 2014-01-12 18:25:03 +01:00
parent 17883e8d01
commit d0a7ca72ab
29 changed files with 12289 additions and 8557 deletions

View file

@ -25,7 +25,7 @@
</parent>
<properties>
<elasticsearch.version>0.90.8-SNAPSHOT</elasticsearch.version>
<elasticsearch.version>0.90.10</elasticsearch.version>
</properties>
<repositories>

View file

@ -1,5 +1,4 @@
define([
'ace',
'analytics',
'curl',
'help_popup',
@ -9,215 +8,216 @@ define([
'mappings',
'output',
'misc_inputs',
'settings',
'utils'
],
function (ace, _gaq, curl, $helpPopup, history, input, $, mappings, output, miscInputs, settings, utils) {
'use strict';
function (_gaq, curl, $helpPopup, history, input, $, mappings, output, miscInputs, utils) {
'use strict';
$(document.body).removeClass('fouc');
$(document.body).removeClass('fouc');
var $esServer = miscInputs.$esServer;
var $send = miscInputs.$send;
function submitCurrentRequestToES(cb) {
cb = typeof cb === 'function' ? cb : $.noop;
var $esServer = miscInputs.$esServer;
var $send = miscInputs.$send;
input.getCurrentRequest(function (req) {
if (!req) return;
function submitCurrentRequestToES(cb) {
cb = typeof cb === 'function' ? cb : $.noop;
$("#notification").text("Calling ES....").css("visibility", "visible");
input.getCurrentRequest(function (req) {
if (!req) return;
var es_server = $esServer.val();
var es_url = req.url;
var es_method = req.method;
var es_data = req.data.join("\n");
if (es_data) es_data += "\n"; //append a new line for bulk requests.
$("#notification").text("Calling ES....").css("visibility", "visible");
utils.callES(es_server, es_url, es_method, es_data, null, function (xhr, status) {
$("#notification").text("").css("visibility", "hidden");
if (typeof xhr.status == "number" &&
((xhr.status >= 400 && xhr.status < 600) ||
(xhr.status >= 200 && xhr.status < 300)
)) {
// we have someone on the other side. Add to history
history.addToHistory(es_server, es_url, es_method, es_data);
var es_server = $esServer.val();
var es_url = req.url;
var es_method = req.method;
var es_data = req.data.join("\n");
if (es_data) es_data += "\n"; //append a new line for bulk requests.
utils.callES(es_server, es_url, es_method, es_data, null, function (xhr, status) {
$("#notification").text("").css("visibility", "hidden");
if (typeof xhr.status == "number" &&
((xhr.status >= 400 && xhr.status < 600) ||
(xhr.status >= 200 && xhr.status < 300)
)) {
// we have someone on the other side. Add to history
history.addToHistory(es_server, es_url, es_method, es_data);
var value = xhr.responseText;
try {
value = JSON.stringify(JSON.parse(value), null, 3);
var value = xhr.responseText;
try {
value = JSON.stringify(JSON.parse(value), null, 3);
}
catch (e) {
}
cb(value);
}
catch (e) {
else {
cb("Request failed to get to the server (status code: " + xhr.status + "):" + xhr.responseText);
}
cb(value);
}
else {
cb("Request failed to get to the server (status code: " + xhr.status + "):" + xhr.responseText);
}
);
saveCurrentState();
}
);
saveCurrentState();
_gaq.push(['_trackEvent', "elasticsearch", 'query']);
});
}
// set the value of the server and/or the input and clear the output
function resetToValues(server, content) {
if (server != null) {
$esServer.val(server);
mappings.notifyServerChange(server);
}
if (content != null) {
input.update(content);
}
output.update("");
}
(function loadSavedState() {
var sourceLocation = utils.getUrlParam('load_from') || "stored";
var previousSaveState = history.getSavedEditorState();
if (sourceLocation == "stored") {
if (previousSaveState) {
resetToValues(previousSaveState.server, previousSaveState.content);
} else {
input.autoIndent();
}
} else if (/^https?:\/\//.exec(sourceLocation)) {
$.get(sourceLocation, null, function (data) {
resetToValues(null, data);
input.highlightCurrentRequestAndUpdateActionBar();
input.updateActionsBar();
_gaq.push(['_trackEvent', "elasticsearch", 'query']);
});
} else if (previousSaveState) {
resetToValues(previousSaveState.server);
}
if (document.location.pathname && document.location.pathname.indexOf("_plugin") == 1) {
// running as an ES plugin. Always assume we are using that elasticsearch
resetToValues(document.location.host);
}
}());
(function setupAutosave() {
var timer;
var saveDelay = 500;
function doSave() {
saveCurrentState();
}
input.getSession().on("change", function onChange(e) {
if (timer) {
timer = clearTimeout(timer);
// set the value of the server and/or the input and clear the output
function resetToValues(server, content) {
if (server != null) {
$esServer.val(server);
mappings.notifyServerChange(server);
}
if (content != null) {
input.update(content);
}
output.update("");
}
(function loadSavedState() {
var sourceLocation = utils.getUrlParam('load_from') || "stored";
var previousSaveState = history.getSavedEditorState();
if (sourceLocation == "stored") {
if (previousSaveState) {
resetToValues(previousSaveState.server, previousSaveState.content);
} else {
input.autoIndent();
}
} else if (/^https?:\/\//.exec(sourceLocation)) {
$.get(sourceLocation, null, function (data) {
resetToValues(null, data);
input.highlightCurrentRequestAndUpdateActionBar();
input.updateActionsBar();
});
} else if (previousSaveState) {
resetToValues(previousSaveState.server);
}
if (document.location.pathname && document.location.pathname.indexOf("_plugin") == 1) {
// running as an ES plugin. Always assume we are using that elasticsearch
resetToValues(document.location.host);
}
}());
(function setupAutosave() {
var timer;
var saveDelay = 500;
function doSave() {
saveCurrentState();
}
input.getSession().on("change", function onChange(e) {
if (timer) {
timer = clearTimeout(timer);
}
timer = setTimeout(doSave, saveDelay);
});
}());
function saveCurrentState() {
try {
var content = input.getValue();
var server = $esServer.val();
history.updateCurrentState(server, content);
}
catch (e) {
console.log("Ignoring saving error: " + e);
}
}
// stupid simple restore function, called when the user
// chooses to restore a request from the history
// PREVENTS history from needing to know about the input
history.restoreFromHistory = function applyHistoryElem(req) {
var session = input.getSession();
var pos = input.getCursorPosition();
var prefix = "";
var suffix = "\n";
if (input.parser.isStartRequestRow(pos.row)) {
pos.column = 0;
suffix += "\n";
}
else if (input.parser.isEndRequestRow(pos.row)) {
var line = session.getLine(pos.row);
pos.column = line.length;
prefix = "\n\n";
}
else if (input.parser.isInBetweenRequestsRow(pos.row)) {
pos.column = 0;
}
else {
pos = input.nextRequestEnd(pos);
prefix = "\n\n";
}
var s = prefix + req.method + " " + req.endpoint;
if (req.data) s += "\n" + req.data;
s += suffix;
session.insert(pos, s);
input.clearSelection();
input.moveCursorTo(pos.row + prefix.length, 0);
input.focus();
};
/**
* Make the editor resizeable
*/
input.$el.resizable({
autoHide: false,
handles: 'e',
start: function (e, ui) {
$(".ui-resizable-e").addClass("active");
},
stop: function (e, ui) {
$(".ui-resizable-e").removeClass("active");
var parent = ui.element.parent();
var editorSize = ui.element.outerWidth();
output.$el.css("left", editorSize + 20);
input.$actions.css("margin-right", -editorSize + 3);
input.resize(true);
output.resize(true);
}
timer = setTimeout(doSave, saveDelay);
});
}());
function saveCurrentState() {
try {
var content = input.getValue();
var server = $esServer.val();
history.updateCurrentState(server, content);
}
catch (e) {
console.log("Ignoring saving error: " + e);
}
}
/**
* Setup the "send" shortcut
*/
input.commands.addCommand({
name: 'send to elasticsearch',
bindKey: {win: 'Ctrl-Enter', mac: 'Command-Enter'},
exec: function () {
output.update('');
submitCurrentRequestToES(function (resp) {
output.update(resp);
});
}
});
// stupid simple restore function, called when the user
// chooses to restore a request from the history
// PREVENTS history from needing to know about the input
history.restoreFromHistory = function applyHistoryElem (req) {
var session = input.getSession();
var pos = input.getCursorPosition();
var prefix = "";
var suffix = "\n";
if (input.parser.isStartRequestRow(pos.row)) {
pos.column = 0;
suffix += "\n";
}
else if (input.parser.isEndRequestRow(pos.row)) {
var line = session.getLine(pos.row);
pos.column = line.length;
prefix = "\n\n";
}
else if (input.parser.isInBetweenRequestsRow(pos.row)) {
pos.column = 0;
}
else {
pos = input.nextRequestEnd(pos);
prefix = "\n\n";
}
var s = prefix + req.method + " " + req.endpoint;
if (req.data) s += "\n" + req.data;
s += suffix;
session.insert(pos, s);
input.clearSelection();
input.moveCursorTo(pos.row + prefix.length, 0);
input.focus();
};
/**
* Make the editor resizeable
*/
input.$el.resizable({
autoHide: false,
handles: 'e',
start: function (e, ui) {
$(".ui-resizable-e").addClass("active");
},
stop: function (e, ui) {
$(".ui-resizable-e").removeClass("active");
var parent = ui.element.parent();
var editorSize = ui.element.outerWidth();
output.$el.css("left", editorSize+20);
input.$actions.css("margin-right", -editorSize + 3);
input.resize(true);
output.resize(true);
}
});
/**
* Setup the "send" shortcut
*/
input.commands.addCommand({
name: 'send to elasticsearch',
bindKey: {win: 'Ctrl-Enter', mac: 'Command-Enter'},
exec: function () {
output.update('');
/**
*
*/
$send.click(function () {
submitCurrentRequestToES(function (resp) {
output.update(resp);
});
return false;
});
/**
* Display the welcome popul if it has not been shown yet
*/
if (!localStorage.getItem("version_welcome_shown")) {
require(['welcome_popup'], function ($welcomePopup) {
$welcomePopup.one('shown', function () {
localStorage.setItem("version_welcome_shown", SENSE_VERSION);
});
$welcomePopup.modal('show');
});
}
});
/**
*
*/
$send.click(function () {
submitCurrentRequestToES();
return false;
});
/**
* Display the welcome popul if it has not been shown yet
*/
if (!localStorage.getItem("version_welcome_shown")) {
require(['welcome_popup'], function ($welcomePopup) {
$welcomePopup.one('shown', function () {
localStorage.setItem("version_welcome_shown", SENSE_VERSION);
});
$welcomePopup.modal('show');
});
}
});

File diff suppressed because it is too large Load diff

View file

@ -1,10 +1,10 @@
define([
'ace',
'sense_editor/editor',
'analytics',
'jquery',
'bootstrap'
], function (ace, _gaq, $) {
], function (SenseEditor, _gaq, $) {
'use strict';
var $helpPopup = $("#help_popup");
@ -23,11 +23,8 @@ define([
$helpPopup.on('shown', function () {
_gaq.push(['_trackEvent', "help", 'shown']);
$(html).appendTo("#help_example_container");
var example_editor = ace.edit("help_example_editor");
example_editor.getSession().setMode("ace/mode/sense");
example_editor.getSession().setFoldStyle('markbeginend');
var example_editor = new SenseEditor($("#help_example_editor"));
example_editor.setReadOnly(true);
example_editor.renderer.setShowPrintMargin(false);
});
$helpPopup.on('hidden', function () {

View file

@ -3,13 +3,15 @@ define([
'sense_editor/editor',
'analytics',
'jquery',
'moment'
'moment',
'settings'
], function (_, SenseEditor, _gaq, $, moment) {
'use strict';
function History() {
var $historyPopup = $("#history_popup");
var historyViewer;
var self = this;
function restoreNotImplemented() {
// default method for history.restoreFromHistory
// replace externally to do something when the user chooses
@ -88,18 +90,12 @@ define([
}
$historyPopup.on('show', function () {
$historyPopup.find(".modal-body").append('<div id="history_viewer">No history available</div>');
$historyPopup.find("#history_viewer").append('<div id="history_viewer_editor">No history available</div>');
historyViewer = new SenseEditor($("#history_viewer"));
historyViewer = new SenseEditor($("#history_viewer_editor"));
historyViewer.setReadOnly(true);
historyViewer.renderer.setShowPrintMargin(false);
// historyViewer.setTheme("ace/theme/monokai");
(function setupHistoryViewerSession(session) {
session.setMode("ace/mode/sense");
session.setFoldStyle('markbeginend');
session.setUseWrapMode(true);
}(historyViewer.getSession()));
require('settings').applyCurrentSettings(historyViewer);
$.each(getHistory(), function (i, hist_elem) {
var li = $('<li><a href="#"><i class="icon-chevron-right"></i><span/></a></li>');
@ -134,7 +130,7 @@ define([
li.bind('apply', function () {
_gaq.push(['_trackEvent', "history", 'applied']);
this.restoreFromHistory(hist_elem);
self.restoreFromHistory(hist_elem);
});
li.appendTo($historyPopup.find(".modal-body .nav"));

View file

@ -1,26 +1,37 @@
define([
'ace',
'analytics',
'autocomplete',
'jquery',
'mappings',
'output',
'require',
'sense_editor/editor',
'settings',
'require',
'utils',
'zeroclip'
], function (_gaq, Autocomplete, $, mappings, output, require, SenseEditor, utils, ZeroClipboard) {
'zeroclip',
'ace_ext_language_tools'
], function (ace, _gaq, Autocomplete, $, mappings, output, SenseEditor, settings, require, utils, ZeroClipboard) {
'use strict';
var input = new SenseEditor($('#editor'));
input.autocomplete = new Autocomplete(input);
input.commands.addCommand({
name: 'autocomplete',
bindKey: {win: 'Ctrl-Space', mac: 'Ctrl-Space'},
exec: function () {
input.autocomplete.show();
// disable standard context based autocompletion.
ace.define('ace/autocomplete/text_completer', ['require', 'exports', 'module'], function(require, exports, module) {
exports.getCompletions = function(editor, session, pos, prefix, callback) {
callback(null, []);
}
});
ace.require('ace/ext/language_tools');
var input = new SenseEditor($('#editor'));
input.setOptions({
enableBasicAutocompletion: true
});
input.autocomplete = new Autocomplete(input);
ace.require('ace/ext/language_tools').addCompleter(input.autocomplete.completer);
input.commands.addCommand({
name: 'auto indent request',
bindKey: {win: 'Ctrl-I', mac: 'Command-I'},
@ -112,9 +123,12 @@ define([
/**
* Init the editor
*/
if (settings) {
settings.applyCurrentSettings(input);
}
input.focus();
input.highlightCurrentRequestAndUpdateActionBar();
input.updateActionsBar();
return input;
})
});

View file

@ -1,10 +1,12 @@
define([
'ace',
'settings',
'jquery'
], function (ace, $) {
], function (ace, settings, $) {
'use strict';
var output = ace.edit("output");
var $el = $("#output");
var output = ace.require('ace/ace').edit($el[0]);
output.update = function (val, cb) {
output.getSession().setValue(val);
@ -13,12 +15,14 @@ define([
}
};
output.$el = $('#output');
output.$el = $el;
output.getSession().setMode("ace/mode/json");
output.getSession().setFoldStyle('markbeginend');
output.getSession().setUseWrapMode(true);
output.setShowPrintMargin(false);
output.setReadOnly(true);
if (settings) {
settings.applyCurrentSettings(output);
}
return output;
})
});

View file

@ -8,12 +8,14 @@
baseUrl: 'app',
paths: {
_: '../vendor/lodash',
ace: '../vendor/ace/ace',
bootstrap: '../vendor/bootstrap/js/bootstrap',
jquery: '../vendor/jquery/jquery-1.8.3',
'jquery-ui': '../vendor/jquery/jquery-ui-1.9.2.custom.min',
moment: '../vendor/moment',
zeroclip: '../vendor/zero_clipboard/zero_clipboard',
'ace': '../vendor/ace/ace',
'ace_mode_json': '../vendor/ace/mode-json',
'ace_ext_language_tools': '../vendor/ace/ext-language_tools',
},
map: {
'*': {
@ -21,6 +23,15 @@
}
},
shim: {
ace: {
exports: 'ace'
},
ace_mode_json: {
deps: ['ace']
},
ace_ext_language_tools: {
deps: ['ace']
},
jquery: {
exports: 'jQuery'
},
@ -29,9 +40,6 @@
},
'jquery-ui': {
deps: ['jquery', 'css!../vendor/jquery/jquery-ui-1.9.2.custom.min.css']
},
ace: {
exports: 'ace'
}
},
waitSeconds: 60,

View file

@ -5,8 +5,9 @@ define([
'curl',
'jquery',
'sense_editor/row_parser',
'sense_editor/mode/sense',
'utils'
], function (_, ace, _gaq, curl, $, RowParser, utils) {
], function (_, ace, _gaq, curl, $, RowParser, SenseMode, utils) {
'use strict';
function isInt(x) {
@ -18,7 +19,8 @@ define([
// we must create a custom class for each instance, so that the prototype
// can be the unique aceEditor it extends
var CustomSenseEditor = function () {};
var CustomSenseEditor = function () {
};
CustomSenseEditor.prototype = {};
function bindProp(key) {
@ -74,7 +76,7 @@ define([
timer = clearTimeout(timer);
}
setTimeout(function check () {
setTimeout(function check() {
if (session.bgTokenizer.running) {
timer = setTimeout(check, checkInterval);
} else {
@ -82,16 +84,15 @@ define([
}
});
};
}
};
ace.require("ace/mode/sense");
editor.setShowPrintMargin(false);
(function (session) {
session.setMode("ace/mode/sense");
session.setMode(new SenseMode.Mode());
session.setFoldStyle('markbeginend');
session.setTabSize(2);
session.setUseWrapMode(true);
})(editor.getSession())
})(editor.getSession());
editor.prevRequestStart = function (pos) {
pos = pos || editor.getCursorPosition();
@ -118,23 +119,24 @@ define([
}
});
});
});
}, true);
editor.update = function (data, callback) {
callback = typeof callback === 'function' ? callback : null;
var session = editor.getSession();
session.setValue(data);
if (callback) {
session.on('tokenizerUpdate', function onTokenizerUpdate() {
session.removeListener('tokenizerUpdate', onTokenizerUpdate);
if (session.bgTokenizer.running) {
setTimeout(onTokenizerUpdate, 50); // poll until done
return;
// force update of tokens, but not on this thread to allow for ace rendering.
setTimeout(function () {
var i;
for (i = 0; i < session.getLength(); i++) {
session.getTokens(i);
}
callback();
});
}
session.setValue(data);
};
editor.replaceRequestRange = function (newRequest, requestRange) {
@ -204,10 +206,10 @@ define([
var dataEndPos;
while (bodyStartRow < currentReqRange.end.row
|| (
bodyStartRow == currentReqRange.end.row
bodyStartRow == currentReqRange.end.row
&& bodyStartColumn < currentReqRange.end.column
)
) {
) {
dataEndPos = editor.nextDataDocEnd({ row: bodyStartRow, column: bodyStartColumn});
var bodyRange = new (ace.require("ace/range").Range)(
bodyStartRow, bodyStartColumn,

View file

@ -0,0 +1,72 @@
define(['require', 'exports', 'module' , 'ace', 'ace_mode_json','./sense_highlight_rules'], function (require, exports, module, ace) {
'use strict';
var oop = ace.require("ace/lib/oop");
var TextMode = ace.require("ace/mode/text").Mode;
var HighlightRules = require("./sense_highlight_rules").SenseJsonHighlightRules;
var MatchingBraceOutdent = ace.require("ace/mode/matching_brace_outdent").MatchingBraceOutdent;
var CstyleBehaviour = ace.require("ace/mode/behaviour/cstyle").CstyleBehaviour;
var CStyleFoldMode = ace.require("ace/mode/folding/cstyle").FoldMode;
var WorkerClient = ace.require("ace/worker/worker_client").WorkerClient;
var AceTokenizer = ace.require("ace/tokenizer").Tokenizer;
ace.require("ace/config").setModuleUrl("sense_editor/mode/worker", require.toUrl("./worker.js"));
var Mode = function () {
this.$tokenizer = new AceTokenizer(new HighlightRules().getRules());
this.$outdent = new MatchingBraceOutdent();
this.$behaviour = new CstyleBehaviour();
this.foldingRules = new CStyleFoldMode();
};
oop.inherits(Mode, TextMode);
(function () {
this.getCompletions = function(editor, session, pos, prefix) {
// autocomplete is done by the autocomplete module.
return [];
};
this.getNextLineIndent = function (state, line, tab) {
var indent = this.$getIndent(line);
if (state != "double_q_string") {
var match = line.match(/^.*[\{\(\[]\s*$/);
if (match) {
indent += tab;
}
}
return indent;
};
this.checkOutdent = function (state, line, input) {
return this.$outdent.checkOutdent(line, input);
};
this.autoOutdent = function (state, doc, row) {
this.$outdent.autoOutdent(doc, row);
};
this.createWorker = function (session) {
var worker = new WorkerClient(["ace", "sense_editor"], "sense_editor/mode/worker", "SenseWorker");
worker.attachToDocument(session.getDocument());
worker.on("error", function (e) {
session.setAnnotations([e.data]);
});
worker.on("ok", function (anno) {
session.setAnnotations(anno.data);
});
return worker;
};
}).call(Mode.prototype);
exports.Mode = Mode;
});

View file

@ -0,0 +1,176 @@
/* jshint -W015 */
define(['require', 'exports', 'module' , 'ace'], function (require, exports, module, ace) {
'use strict';
var oop = ace.require("ace/lib/oop");
var TextHighlightRules = ace.require("ace/mode/text_highlight_rules").TextHighlightRules;
var SenseJsonHighlightRules = function () {
function mergeTokens(/* ... */) {
return [].concat.apply([], arguments);
}
function addEOL(tokens, reg, nextIfEOL, normalNext) {
if (typeof reg == "object") reg = reg.source;
return [
{ token: tokens.concat(["whitespace"]), regex: reg + "(\\s*)$", next: nextIfEOL },
{ token: tokens, regex: reg, next: normalNext }
];
}
// regexp must not have capturing parentheses. Use (?:) instead.
// regexps are ordered -> the first match is used
/*jshint -W015 */
this.$rules = {
"start": mergeTokens([
{ token: "comment", regex: /^#.*$/},
{ token: "paren.lparen", regex: "{", next: "json", push: true }
],
addEOL(["method"], /([a-zA-Z]+)/, "start", "method_sep")
,
[
{
token: "whitespace",
regex: "\\s+"
},
{
token: "text",
regex: ".+?"
}
]),
"method_sep": mergeTokens(
addEOL(["whitespace", "url.slash"], /(\s+)(\/)/, "start", "indices"),
addEOL(["whitespace"], /(\s+)/, "start", "indices")
),
"indices": mergeTokens(
addEOL(["url.scheme", "url.host", "url.slash"], /([^:]+:\/\/)([^?\/\s]*)(\/?)/, "start"),
addEOL(["url.index"], /(_all)/, "start"),
addEOL(["url.endpoint"], /(_[^\/?]+)/, "start", "urlRest"),
addEOL(["url.index"], /([^\/?,]+)/, "start"),
addEOL(["url.comma"], /(,)/, "start"),
addEOL(["url.slash"], /(\/)/, "start", "types"),
addEOL(["url.questionmark"], /(\?)/, "start", "urlParams")
),
"types": mergeTokens(
addEOL(["url.endpoint"], /(_[^\/?]+)/, "start", "urlRest"),
addEOL(["url.type"], /([^\/?,]+)/, "start"),
addEOL(["url.comma"], /(,)/, "start"),
addEOL(["url.slash"], /(\/)/, "start", "id"),
addEOL(["url.questionmark"], /(\?)/, "start", "urlParams")
),
"id": mergeTokens(
addEOL(["url.endpoint"], /(_[^\/?]+)/, "start", "urlRest"),
addEOL(["url.id"], /([^\/?]+)/, "start"),
addEOL(["url.slash"], /(\/)/, "start", "urlRest"),
addEOL(["url.questionmark"], /(\?)/, "start", "urlParams")
),
"urlRest": mergeTokens(
addEOL(["url.part"], /([^?\/]+)/, "start"),
addEOL(["url.slash"], /(\/)/, "start"),
addEOL(["url.questionmark"], /(\?)/, "start", "urlParams")
),
"urlParams": mergeTokens(
addEOL(["url.param", "url.equal", "url.value"], /([^&=]+)(=)([^&]*)/, "start"),
addEOL(["url.param"], /([^&=]+)/, "start"),
addEOL(["url.amp"], /(&)/, "start")
),
"json": [
{
token: "variable", // single line
regex: '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]\\s*(?=:)'
},
{
token: "string", // single line
regex: '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'
},
{
token: "constant.numeric", // hex
regex: "0[xX][0-9a-fA-F]+\\b"
},
{
token: "constant.numeric", // float
regex: "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"
},
{
token: "constant.language.boolean",
regex: "(?:true|false)\\b"
},
{
token: "invalid.illegal", // single quoted strings are not allowed
regex: "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"
},
{
token: "invalid.illegal", // comments are not allowed
regex: "\\/\\/.*$"
},
{
token: "paren.lparen",
merge: false,
regex: "{",
next: "json",
push: true
},
{
token: "paren.lparen",
merge: false,
regex: "[[(]"
},
{
token: "paren.rparen",
merge: false,
regex: "[\\])]"
},
{
token: "paren.rparen",
regex: "}",
merge: false,
next: "pop"
},
{
token: "punctuation.comma",
regex: ","
},
{
token: "punctuation.colon",
regex: ":"
},
{
token: "whitespace",
regex: "\\s+"
},
{
token: "text",
regex: ".+?"
}
],
"double_q_string": [
{
token: "string",
regex: '[^"]+'
},
{
token: "punctuation.end_quote",
regex: '"',
next: "json"
},
{
token: "string",
regex: "",
next: "json"
}
]
}
if (this.constructor === SenseJsonHighlightRules)
this.normalizeRules();
};
oop.inherits(SenseJsonHighlightRules, TextHighlightRules);
exports.SenseJsonHighlightRules = SenseJsonHighlightRules;
});

File diff suppressed because it is too large Load diff

View file

@ -9,12 +9,11 @@ define([], function () {
var session = editor.getSession();
if (row >= session.getLength()) return RowParser.MODE_BETWEEN_REQUESTS;
var mode = (session.getState(row) || {}).name;
var mode = session.getState(row);
if (!mode)
return RowParser.MODE_BETWEEN_REQUESTS; // shouldn't really happen
if (mode != "start") return RowParser.MODE_IN_REQUEST;
if (mode !== "start") return RowParser.MODE_IN_REQUEST;
var line = (session.getLine(row) || "").trim();
if (!line || line[0] === '#') return RowParser.MODE_BETWEEN_REQUESTS; // empty line or a comment waiting for a new req to start

View file

@ -1,38 +1,11 @@
/* ***** 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 ***** */
ace.define('ace/theme/sense-dark', ['require', 'exports', 'module' , 'ace/lib/dom'], function(require, exports, module) {
exports.isDark = true;
exports.cssClass = "ace-sense-dark";
exports.cssText = ".ace-sense-dark .ace_gutter {\
/* jshint -W101 */
define([ 'ace'], function (ace) {
"use strict";
ace.define("ace/theme/sense-dark", ['require', 'exports', 'module'],
function (require, exports, module) {
exports.isDark = true;
exports.cssClass = "ace-sense-dark";
exports.cssText = ".ace-sense-dark .ace_gutter {\
background: #2e3236;\
color: #bbbfc2;\
}\
@ -137,6 +110,7 @@ text-decoration: underline\
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNQ11D6z7Bq1ar/ABCKBG6g04U2AAAAAElFTkSuQmCC) right repeat-y\
}";
var dom = require("../lib/dom");
dom.importCssString(exports.cssText, exports.cssClass);
var dom = require("ace/lib/dom");
dom.importCssString(exports.cssText, exports.cssClass);
})
});

View file

@ -1,8 +1,8 @@
define([
'input',
'output',
'jquery'
], function (input, output, $) {
'jquery',
'exports',
'sense_editor/theme-sense-dark'
], function ($, exports) {
'use strict';
function getFontSize() {
@ -12,8 +12,7 @@ define([
function setFontSize(size) {
if (!/^([1-9]\d*)$/.test(size)) return false;
localStorage.setItem("font_size", size);
$("#editor").css("font-size", size + "px");
$("#output").css("font-size", size + "px");
applyCurrentSettings();
return true;
}
@ -25,54 +24,65 @@ define([
function setWrapMode(mode) {
if (typeof mode !== "boolean") return false;
localStorage.setItem("wrap_mode", mode);
input.getSession().setUseWrapMode(mode);
output.getSession().setUseWrapMode(mode);
applyCurrentSettings();
return true;
}
function getTheme() {
var mode = localStorage.getItem("theme") || "light";
return mode;
return localStorage.getItem("theme") || "light";
}
function getAceTheme(mode) {
mode = mode || localStorage.getItem("theme") || "light";
return mode === "light" ? "" : "ace/theme/sense-dark";
}
function setTheme(mode) {
localStorage.setItem("theme", mode);
$("#bootstrapThemeCss").attr("href", "vendor/bootstrap/css/bootstrap." + mode + ".min.css");
$("#senseThemeCss").attr("href", "css/sense." + mode + ".css");
var aceTheme = mode === "light" ? "" : "ace/theme/sense-dark";
input.setTheme(aceTheme);
output.setTheme(aceTheme);
applyCurrentSettings();
return true;
}
function applyCurrentSettings(editor) {
if (typeof editor === "undefined") {
applyCurrentSettings(require('input'));
applyCurrentSettings(require('output'));
}
if (editor) {
editor.setTheme(getAceTheme());
editor.getSession().setUseWrapMode(getWrapMode());
editor.$el.css("font-size", getFontSize() + "px");
}
}
var settings_popup = $("#settings_popup");
var font_size_ctl = settings_popup.find("#font_size");
var fs = getFontSize();
font_size_ctl.val(fs);
setFontSize(fs);
//setFontSize(fs);
var wrap_mode_ctl = settings_popup.find("#wrap_mode");
var wm = getWrapMode();
wrap_mode_ctl.prop('checked', wm);
setWrapMode(wm);
//setWrapMode(wm);
var theme_ctl = settings_popup.find("#theme");
var theme = getTheme();
theme_ctl.val(theme);
setTheme(theme);
//setTheme(theme);
function save() {
if (!setFontSize(font_size_ctl.val())) font_size_ctl.val(getFontSize());
if (!setWrapMode(wrap_mode_ctl.prop("checked"))) wrap_mode_ctl.prop('checked', getWrapMode());
if (!setTheme(theme_ctl.val())) theme_ctl.val(getTheme());
input.focus();
require('input').focus();
return true;
}
@ -84,5 +94,8 @@ define([
return false
});
return {};
exports.getTheme = getTheme;
exports.getAceTheme = getAceTheme;
exports.applyCurrentSettings = applyCurrentSettings;
});

View file

@ -1,7 +1,6 @@
define([
'ace',
'jquery'
], function (ace, $) {
], function ($) {
'use strict';
var utils = {};
@ -21,13 +20,17 @@ define([
return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
};
utils.jsonToString = function(data, indent) {
return JSON.stringify(data, null, indent ? 2 : 0);
};
utils.reformatData = function (data, indent) {
var changed = false;
var formatted_data = [];
for (var i = 0; i < data.length; i++) {
var cur_doc = data[i];
try {
var new_doc = JSON.stringify(JSON.parse(cur_doc), null, indent ? 2 : 0);
var new_doc = utils.jsonToString(JSON.parse(cur_doc), indent ? 2 : 0);
changed = changed || new_doc != cur_doc;
formatted_data.push(new_doc);
}
@ -41,7 +44,7 @@ define([
changed: changed,
data: formatted_data
};
}
};
utils.callES = function (server, url, method, data, successCallback, completeCallback) {
url = utils.constructESUrl(server, url);

View file

@ -1,10 +1,10 @@
define([
'ace',
'sense_editor/editor',
'analytics',
'jquery',
'bootstrap'
], function (ace, _gaq, $) {
], function (SenseEditor, _gaq, $) {
'use strict';
var $welcomePopup = $("#welcome_popup");
@ -20,17 +20,14 @@ define([
'# and get it ... ',
'GET index/type/1</div>'
].join('\n');
$welcomePopup.modal();
$welcomePopup.on('shown', function () {
$example = $(html)
.appendTo("#welcome_example_container");
var editor = ace.edit("welcome_example_editor");
editor.getSession().setMode("ace/mode/sense");
editor.getSession().setFoldStyle('markbeginend');
var editor = new SenseEditor($("#welcome_example_editor"));
editor.setReadOnly(true);
editor.renderer.setShowPrintMargin(false);
});
$welcomePopup.on('hidden', function () {

View file

@ -1,67 +1,68 @@
body {
margin: 0;
overflow: hidden;
margin: 0;
overflow: hidden;
}
body.fouc {
display: none;
display: none;
}
.pull-right-btn {
float: right;
margin-right: 5px;
float: right;
margin-right: 5px;
}
.pull-right-btn:first-of-type {
margin-right: 0;
margin-right: 0;
}
#es_method {
width: 100px;
width: 100px;
}
#editor_actions {
position: absolute;
top: 47px;
right: 100%;
line-height: 1;
margin-right: -468px;
z-index: 100;
position: absolute;
top: 47px;
right: 100%;
line-height: 1;
margin-right: -468px;
z-index: 100;
}
#editor_actions > .btn-group > a {
padding: 2px 4px;
padding: 2px 4px;
}
#editor_actions > .btn-group > a:hover {
padding: 2px 4px;
text-decoration: none;
}
.editor_position {
position: absolute;
top: 50px;
bottom: 5px;
left: 5px;
width: 468px;
padding: 2px 4px;
text-decoration: none;
}
.overlay {
background-color: #000;
opacity: 0.5;
z-index: 100;
background-color: #000;
opacity: 0.5;
z-index: 100;
}
#output {
position: absolute;
top: 50px;
bottom: 5px;
left: 488px;
right: 5px;
min-width: 700px;
#editor_container {
position: absolute;
top: 50px;
bottom: 5px;
left: 5px;
width: 468px;
}
#output_container {
position: absolute;
top: 50px;
bottom: 5px;
left: 488px;
right: 5px;
min-width: 700px;
}
#output, #editor {
height: 100%;
}
.ace_gutter {
@ -69,133 +70,140 @@ body.fouc {
}
#autocomplete {
visibility: hidden;
position: absolute;
z-index: 1000;
margin-top: 22px;
/*font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;*/
/*font-size: 12px;*/
/*max-height: 100px;*/
/*overflow-y: auto;*/
/* prevent horizontal scrollbar */
/*overflow-x: hidden;*/
visibility: hidden;
position: absolute;
z-index: 1000;
margin-top: 22px;
/*font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;*/
/*font-size: 12px;*/
/*max-height: 100px;*/
/*overflow-y: auto;*/
/* prevent horizontal scrollbar */
/*overflow-x: hidden;*/
}
.ui-state-focus {
margin: auto !important;
margin: auto !important;
}
#history_popup {
width: 90%;
margin-left: -45%;
height: 90%;
top: 5%;
margin-top: 0;
width: 90%;
margin-left: -45%;
height: 90%;
top: 5%;
margin-top: 0;
}
#history_popup .modal-body {
position: relative;
max-height: none;
height: 100%;
}
#history_popup .modal-header {
position: absolute;
top: 0;
left: 0;
right: 0;
position: absolute;
top: 0;
left: 0;
right: 0;
/* by pass body overlay*/
z-index: 10;
}
#history_popup .modal-footer {
position: absolute;
bottom: 0;
left: 0;
right: 0;
position: absolute;
bottom: 0;
left: 0;
right: 0;
/* by pass ace gutter */
z-index: 10;
}
#history_popup .nav {
position: absolute;
width: 400px;
left: 0;
top: 60px;
bottom: 70px;
overflow-y: auto;
position: absolute;
width: 400px;
left: 0;
top: 60px;
bottom: 70px;
overflow-y: auto;
}
#help_example_container,
#welcome_example_container {
width: 100%;
height: 10em;
margin: 10px 0;
position: relative;
width: 100%;
height: 10em;
margin: 10px 0;
position: relative;
}
#help_example_editor,
#welcome_example_editor {
top: 0;
bottom: 0;
right: 0;
left: 0;
height: 100%;
}
.icon-chevron-right {
position: absolute;
right: 10px;
margin-top: 2px;
margin-right: -6px;
opacity: .25;
position: absolute;
right: 10px;
margin-top: 2px;
margin-right: -6px;
opacity: .25;
}
#history_popup .nav a {
display: block;
margin: 0 0 -1px;
padding: 8px 14px;
border: 1px solid #e5e5e5;
white-space: nowrap;
position: relative;
overflow: hidden;
display: block;
margin: 0 0 -1px;
padding: 8px 14px;
border: 1px solid #e5e5e5;
white-space: nowrap;
position: relative;
overflow: hidden;
}
#history_popup .nav li:first-child > a {
-webkit-border-radius: 6px 6px 0 0;
-moz-border-radius: 6px 6px 0 0;
border-radius: 6px 6px 0 0;
-webkit-border-radius: 6px 6px 0 0;
-moz-border-radius: 6px 6px 0 0;
border-radius: 6px 6px 0 0;
}
#history_popup .nav li:last-child > a {
-webkit-border-radius: 0 0 6px 6px;
-moz-border-radius: 0 0 6px 6px;
border-radius: 0 0 6px 6px;
-webkit-border-radius: 0 0 6px 6px;
-moz-border-radius: 0 0 6px 6px;
border-radius: 0 0 6px 6px;
}
#history_viewer {
position: absolute;
left: 430px;
right: 0;
margin-right: 9px;
top: 60px;
bottom: 70px;
position: absolute;
left: 430px;
right: 0;
margin-right: 9px;
top: 60px;
bottom: 70px;
}
#history_viewer_editor {
height: 100%;
}
#welcome_popup {
top: 40%;
top: 40%;
}
#welcome_popup .modal-body {
max-height: 600px;
max-height: 600px;
}
.ui-autocomplete {
z-index: 400 !important;
z-index: 400 !important;
}
.ace_editor {
line-height: normal;
line-height: normal;
}
.out_of_screen {
width: 1px;
height: 1px;
overflow: hidden;
margin-left: -1000px;
width: 1px;
height: 1px;
overflow: hidden;
margin-left: -1000px;
}
.ace_layer.ace_marker-layer {
@ -203,41 +211,42 @@ body.fouc {
}
.ace_snippet-marker {
position: absolute;
width: 100% !important;
position: absolute;
width: 100% !important;
}
.ui-resizable-e {
cursor: ew-resize;
width: 10px;
right: -5px;
top: 0;
bottom: 0;
background-color: transparent;
position: absolute;
z-index: 50 !important;
cursor: ew-resize;
width: 10px;
right: -5px;
top: 0;
bottom: 0;
background-color: transparent;
position: absolute;
z-index: 50 !important;
}
.ui-resizable-e:hover {
background-color: rgba(194, 193, 208, 0.80);
background-color: rgba(194, 193, 208, 0.80);
}
.ui-resizable-e.active {
background-color: rgba(194, 193, 208, 100);
background-color: rgba(194, 193, 208, 100);
}
/** COPIED FROM BOOTSTRAP, MODIFIED SELECTORS **/
.dropdown-menu li>a.zeroclipboard-is-hover,
.dropdown-menu li>a.zeroclipboard-is-active {
color: #FFF;
text-decoration: none;
background-color: #0081C2;
background-image: -moz-linear-gradient(top,#08c,#0077b3);
background-image: -webkit-gradient(linear,0 0,0 100%,from(#08C),to(#0077B3));
background-image: -webkit-linear-gradient(top,#08C,#0077B3);
background-image: -o-linear-gradient(top,#08c,#0077b3);
background-image: linear-gradient(to bottom,#08C,#0077B3);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0);
.dropdown-menu li > a.zeroclipboard-is-hover,
.dropdown-menu li > a.zeroclipboard-is-active {
color: #FFF;
text-decoration: none;
background-color: #0081C2;
background-image: -moz-linear-gradient(top, #08c, #0077b3);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#08C), to(#0077B3));
background-image: -webkit-linear-gradient(top, #08C, #0077B3);
background-image: -o-linear-gradient(top, #08c, #0077b3);
background-image: linear-gradient(to bottom, #08C, #0077B3);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);
}
/** END COPIED **/

View file

@ -35,12 +35,16 @@
</div>
</div>
<div id="main" class="container-fluid">
<div id="editor" class="editor_position">GET _search
{
<div id="editor_container">
<div id="editor">GET _search
{
"query": { "match_all": {} }
}
</div>
</div>
<div id="output_container">
<div id="output">{}</div>
</div>
<div id="output">{}</div>
<div id="editor_actions">
<a id="send" href="#" data-toggle="tooltip" title="click to send request"><i
class="fa fa-play"></i></a>
@ -110,6 +114,9 @@
<ul class="nav nav-list">
<!--<li><a href="#"><i class="icon-chevron-right"></i><span></span></a></li>-->
</ul>
<div id="history_viewer">
</div>
</div>
<div class="modal-footer">
<a href="#" class="btn pull-left" id="hist_clear">Clear</a>
@ -181,8 +188,9 @@
<script src="vendor/require/require.js"></script>
<script src="app/require.config.js"></script>
<script>
var SENSE_VERSION = '0.9.0';
require(['app'], function () {});
var SENSE_VERSION = '1.0.0';
// make sure all of ace is loaded first.
require(['require','ace'], function (require) { require(['app'], function () {})});
</script>
</body>

View file

@ -5,7 +5,7 @@
<title>Sense unittests</title>
<link rel="stylesheet" href="lib/qunit-1.10.0.css">
<style type="text/css">
#editor {
#editor_container {
display: none;
position: absolute;
top: 20px;
@ -15,7 +15,7 @@
z-index: 200;
border: 1px solid #333;
}
#output {
#output_container {
display: none;
position: absolute;
height: 250px;
@ -25,26 +25,33 @@
z-index: 201;
border: 1px solid #333;
}
#editor, #output {
height: 100%;
width: 100%;
position: relative;
}
</style>
</head>
<body>
<div id="qunit"></div>
<div id="editor"></div>
<div id="output"></div>
<script src="lib/qunit-1.10.0.js"></script>
<div id="editor_container"><div id="editor"></div></div>
<div id="output_container"><div id="output"></div></div>
<script src="../vendor/require/require.js"></script>
<script src="../app/require.config.js"></script>
<script src="lib/qunit-1.10.0.js"></script>
<script>
var SENSE_VERSION = '0.9.0';
/* global QUnit */
QUnit.config.autostart = false;
var SENSE_VERSION = '0.9.0';
require.config({
baseUrl: '../app'
});
(function () {
require(["require","ace"], function (require) {
'use strict';
/* global QUnit */
QUnit.config.autostart = false;
var tests = [
'../tests/src/curl_tests.js',
'../tests/src/kb_tests.js',
@ -59,12 +66,12 @@ require.config({
if (tests.length) {
require(tests.splice(0, 1), next);
} else {
QUnit.start();
console.log('all tests loaded');
QUnit.start();
}
}());
}());
});
</script>
</body>
</html>

View file

@ -5,12 +5,16 @@ define([
], function (ace, input, $) {
'use strict';
var aceRange = ace.require("ace/range");
module("Editor", {
setup: function () {
input.$el.show();
input.autocomplete._test.removeChangeListener();
},
teardown: function () {
input.$el.hide();
input.autocomplete._test.addChangeListener();
}
});
@ -62,7 +66,7 @@ define([
utils_test("simple request range", simple_request.prefix, simple_request.data, function () {
input.getCurrentRequestRange(function (range) {
var expected = new (ace.require("ace/range").Range)(
var expected = new aceRange.Range(
0, 0,
3, 1
);
@ -86,7 +90,7 @@ define([
utils_test("single line request range", single_line_request.prefix, single_line_request.data, function () {
input.getCurrentRequestRange(function (range) {
var expected = new (ace.require("ace/range").Range)(
var expected = new aceRange.Range(
0, 0,
1, 32
);
@ -110,7 +114,7 @@ define([
utils_test("request with no data followed by a new line", get_request_no_data.prefix, "\n", function () {
input.getCurrentRequestRange(function (range) {
var expected = new (ace.require("ace/range").Range)(
var expected = new aceRange.Range(
0, 0,
0, 10
);
@ -135,7 +139,7 @@ define([
utils_test("request with no data", get_request_no_data.prefix, get_request_no_data.data, function () {
input.getCurrentRequestRange(function (range) {
var expected = new (ace.require("ace/range").Range)(
var expected = new aceRange.Range(
0, 0,
0, 10
);
@ -159,7 +163,7 @@ define([
utils_test("multi doc request range", multi_doc_request.prefix, multi_doc_request.data, function () {
input.getCurrentRequestRange(function (range) {
var expected = new (ace.require("ace/range").Range)(
var expected = new aceRange.Range(
0, 0,
2, 14
);

View file

@ -7,11 +7,13 @@ define([
'use strict';
module("Integration", {
editor: function () {
input.$el.show();
setup: function () {
$("#editor_container").show();
input.autocomplete._test.removeChangeListener();
},
teardown: function () {
input.$el.hide();
$("#editor_container").hide();
input.autocomplete._test.addChangeListener();
}
});
@ -29,6 +31,8 @@ define([
}
}
test.cursor.row += rowOffset;
mappings.clear();
mappings.loadMappings(mapping);
@ -45,63 +49,78 @@ define([
}
input.update(editorValue, function () {
input.moveCursorTo(test.cursor.row + rowOffset, test.cursor.column);
input.moveCursorTo(test.cursor.row, test.cursor.column);
// allow ace rendering to move cursor so it will be seen during test - handy for debugging.
setTimeout(function () {
input.completer = {}; // mimic auto complete
input.autocomplete.completer.getCompletions(input, input.getSession(), test.cursor, "",
function (err, terms) {
if (test.no_context) {
ok(!terms || terms.length === 0, "Expected no context bug got terms.");
}
else {
ok(terms && terms.length > 0, "failed to extract terms ...");
}
if (!terms || terms.length === 0) {
start();
return;
}
var context = input.autocomplete._test.getAutoCompleteContext();
if (test.no_context) {
ok(!context, "Expected no context bug got one.");
}
else {
ok(context, "failed to have a context ...");
}
if (test["autoCompleteSet"]) {
var expected_terms = _.map(test["autoCompleteSet"], function (t) {
if (typeof t !== "object") {
t = { "name": t };
}
return t;
});
if (terms.length != expected_terms.length) {
equal(_.pluck(terms, 'name'), _.pluck(expected_terms, 'name'), "list of completion terms is not of equal size");
} else {
var filtered_actual_terms = _.map(terms, function (actual_term,i) {
var expected_term = expected_terms[i];
var filtered_term = {};
_.each(expected_term, function (v,p) { filtered_term[p] = actual_term[p]; });
return filtered_term;
});
deepEqual(filtered_actual_terms, expected_terms);
}
}
var context = terms[0].context;
input.autocomplete._test.addReplacementInfoToContext(context, test.cursor, terms[0].value);
function ac(prop, prop_test) {
if (typeof test[prop] != "undefined")
if (prop_test)
prop_test(context[prop], test[prop], prop);
else
deepEqual(context[prop], test[prop], 'context.' + prop + ' should equal ' + JSON.stringify(test[prop]));
}
function pos_compare(actual, expected, name) {
equal(actual.row, expected.row + rowOffset, "row of " + name + " position is not as expected");
equal(actual.column, expected.column, "column of " + name + " position is not as expected");
}
function range_compare(actual, expected, name) {
pos_compare(actual.start, expected.start, name + ".start");
pos_compare(actual.end, expected.end, name + ".end");
}
ac("prefixToAdd");
ac("suffixToAdd");
ac("addTemplate");
ac("textBoxPosition", pos_compare);
ac("rangeToReplace", range_compare);
if (!context) {
start();
return;
}
context.initialValue = input.autocomplete._test.getAutoCompleteValueFromToken(context.updatedForToken);
function ac(prop, prop_test) {
if (typeof test[prop] != "undefined")
if (prop_test)
prop_test(context[prop], test[prop], prop);
else
deepEqual(context[prop], test[prop], 'context.' + prop + ' should equal ' + JSON.stringify(test[prop]));
}
function pos_compare(actual, expected, name) {
equal(actual.row, expected.row + rowOffset, "row of " + name + " position is not as expected");
equal(actual.column, expected.column, "column of " + name + " position is not as expected");
}
function range_compare(actual, expected, name) {
pos_compare(actual.start, expected.start, name + ".start");
pos_compare(actual.end, expected.end, name + ".end");
}
function autocompleteset_compare(actual, expected, name) {
if (typeof expected.completionTerms != "undefined")
deepEqual(actual.completionTerms, expected.completionTerms,
name + ".completionTerms are not equal");
if (typeof expected.templateByTerm != "undefined")
deepEqual(actual.templateByTerm, expected.templateByTerm,
name + ".templateByTerm are not equal");
}
ac("initialValue");
ac("prefixToAdd");
ac("suffixToAdd");
ac("addTemplate");
ac("textBoxPosition", pos_compare);
ac("rangeToReplace", range_compare);
ac("autoCompleteSet", autocompleteset_compare);
start();
});
});
});
})
@ -159,7 +178,7 @@ define([
prefixToAdd: "",
suffixToAdd: "",
rangeToReplace: { start: { row: 0, column: 1 }, end: { row: 0, column: 1 }},
autoCompleteSet: { completionTerms: ["facets", "query", "size"]}
autoCompleteSet: ["facets", "query", "size"]
}
]
);
@ -198,7 +217,7 @@ define([
prefixToAdd: "",
suffixToAdd: "",
rangeToReplace: { start: { row: 1, column: 3 }, end: { row: 1, column: 10 }},
autoCompleteSet: { completionTerms: ["facets", "query", "size"]}
autoCompleteSet: ["facets", "query", "size"]
},
{
name: "existing inner dictionary key",
@ -208,7 +227,7 @@ define([
prefixToAdd: "",
suffixToAdd: "",
rangeToReplace: { start: { row: 2, column: 6}, end: { row: 2, column: 13 }},
autoCompleteSet: { completionTerms: ["match_all", "term"]}
autoCompleteSet: ["match_all", "term"]
},
{
name: "existing dictionary key, yes template",
@ -218,7 +237,7 @@ define([
prefixToAdd: "",
suffixToAdd: "",
rangeToReplace: { start: { row: 4, column: 3 }, end: { row: 4, column: 15 }},
autoCompleteSet: { completionTerms: ["facets", "query", "size"]}
autoCompleteSet: ["facets", "query", "size"]
}
]
);
@ -237,13 +256,13 @@ define([
[
{
name: "trailing comma, end of line",
cursor: { row: 4, column: 18},
cursor: { row: 4, column: 16},
initialValue: "",
addTemplate: true,
prefixToAdd: "",
suffixToAdd: ", ",
rangeToReplace: { start: { row: 4, column: 16 }, end: { row: 4, column: 16 }},
autoCompleteSet: { completionTerms: ["facets", "query", "size"]}
autoCompleteSet: ["facets", "query", "size"]
},
{
name: "trailing comma, beginning of line",
@ -253,7 +272,7 @@ define([
prefixToAdd: "",
suffixToAdd: ", ",
rangeToReplace: { start: { row: 5, column: 1 }, end: { row: 5, column: 1 }},
autoCompleteSet: { completionTerms: ["facets", "query", "size"]}
autoCompleteSet: ["facets", "query", "size"]
},
{
name: "prefix comma, beginning of line",
@ -263,7 +282,7 @@ define([
prefixToAdd: ", ",
suffixToAdd: "",
rangeToReplace: { start: { row: 6, column: 0 }, end: { row: 6, column: 0 }},
autoCompleteSet: { completionTerms: ["facets", "query", "size"]}
autoCompleteSet: ["facets", "query", "size"]
},
{
name: "prefix comma, end of line",
@ -273,7 +292,7 @@ define([
prefixToAdd: ", ",
suffixToAdd: "",
rangeToReplace: { start: { row: 5, column: 14 }, end: { row: 5, column: 14 }},
autoCompleteSet: { completionTerms: ["facets", "query", "size"]}
autoCompleteSet: ["facets", "query", "size"]
}
]
@ -305,25 +324,25 @@ define([
name: "not matching object when { is not opened",
cursor: { row: 1, column: 12},
initialValue: "",
autoCompleteSet: { completionTerms: ["{"] }
autoCompleteSet: ["{"]
},
{
name: "not matching array when [ is not opened",
cursor: { row: 2, column: 12},
initialValue: "",
autoCompleteSet: { completionTerms: ["["] }
autoCompleteSet: ["["]
},
{
name: "matching value with one_of",
cursor: { row: 3, column: 19},
initialValue: "",
autoCompleteSet: { completionTerms: [ 1, 2] }
autoCompleteSet: [ 1, 2]
},
{
name: "matching value",
cursor: { row: 4, column: 12},
initialValue: "",
autoCompleteSet: { completionTerms: [ 3 ] }
autoCompleteSet: [ 3 ]
}
]
);
@ -343,25 +362,15 @@ define([
"POST _search",
[
{
name: "$FIELD$ matching",
name: "* matching everything",
cursor: { row: 5, column: 15},
initialValue: "",
addTemplate: true,
prefixToAdd: "",
suffixToAdd: "",
rangeToReplace: { start: { row: 5, column: 15 }, end: { row: 5, column: 15 }},
autoCompleteSet: { completionTerms: ["terms"] }
autoCompleteSet: [{ name: "terms", meta: "API" }]
}
// , made redundent by inline auto complete. Still need to find a solution for templates
// {
// name: "$FIELD$ options",
// cursor: { row: 5, column: 7},
// initialValue: "name",
// addTemplate: true,
// prefixToAdd: "",
// suffixToAdd: "",
// autoCompleteSet: { completionTerms: [] }
// }
]
);
@ -384,11 +393,15 @@ define([
{
name: "$INDEX$ matching",
cursor: { row: 1, column: 15},
autoCompleteSet: { completionTerms: ["index1", "index2"] }
autoCompleteSet: [{ name: "index1", meta: "index"}, { name: "index2", meta: "index"}]
}
]
);
function tt(term, template) {
return { name: term, template: template };
}
context_tests(
{
"array": [
@ -415,15 +428,14 @@ define([
{
name: "Templates 1",
cursor: { row: 1, column: 0},
autoCompleteSet: { completionTerms: ["array", "fixed", "number", "object", "oneof"],
templateByTerm: { array: [ "a" ], number: 1, object: {}, fixed: { a: 1}, oneof: "o1" }}
autoCompleteSet: [
tt("array", [ "a" ]), tt("fixed", { a: 1 }), tt("number",1), tt("object", {}), tt("oneof", "o1")
]
},
{
name: "Templates - one off",
cursor: { row: 4, column: 12},
autoCompleteSet: { completionTerms: ["o1", "o2"],
templateByTerm: { }
}
autoCompleteSet: [tt("o1"), tt("o2")]
}
]
);
@ -461,31 +473,22 @@ define([
{
name: "Any of - templates",
cursor: { row: 1, column: 0},
autoCompleteSet: {
completionTerms: ["any_of_numbers", "any_of_obj"],
templateByTerm: {
any_of_numbers: [ 1, 2 ],
any_of_obj: [
{ c: 1}
]
}
}
autoCompleteSet: [
tt("any_of_numbers", [ 1, 2 ]),
tt("any_of_obj", [ { c: 1} ])
]
},
{
name: "Any of - numbers",
cursor: { row: 2, column: 2},
autoCompleteSet: {
completionTerms: [1, 2, 3],
templateByTerm: { }
}
autoCompleteSet: [1, 2, 3]
},
{
name: "Any of - object",
cursor: { row: 6, column: 2},
autoCompleteSet: {
completionTerms: ["a", "b"],
templateByTerm: { a: 1, b: 2 }
}
autoCompleteSet: [
tt("a", 1),tt("b", 2 )
]
}
]
);
@ -507,10 +510,7 @@ define([
{
name: "Empty string as default",
cursor: { row: 0, column: 1},
autoCompleteSet: {
completionTerms: ["query"],
templateByTerm: { query: ""}
}
autoCompleteSet: [tt("query","")]
}
]
);
@ -574,33 +574,29 @@ define([
{
name: "Relative scope link test",
cursor: { row: 2, column: 12},
autoCompleteSet: { completionTerms: ["b", "c", "d", "e", "f"],
templateByTerm: { b: {}, c: {}, d: {}, e: {}, f: [{}] }
}
autoCompleteSet:[
tt("b", {}), tt("c", {}), tt("d", {}), tt("e", {}), tt("f", [ {} ])
]
},
{
name: "External scope link test",
cursor: { row: 3, column: 12},
autoCompleteSet: { completionTerms: ["t2"],
templateByTerm: { t2: 1}}
autoCompleteSet: [tt("t2", 1)]
},
{
name: "Global scope link test",
cursor: { row: 4, column: 12},
autoCompleteSet: { completionTerms: ["t1"],
templateByTerm: { t1: 2}}
autoCompleteSet: [tt("t1", 2)]
},
{
name: "Entire endpoint scope link test",
cursor: { row: 5, column: 12},
autoCompleteSet: { completionTerms: ["target"],
templateByTerm: { target: {}}}
autoCompleteSet: [tt("target", {})]
},
{
name: "A scope link within an array",
cursor: { row: 7, column: 10},
autoCompleteSet: { completionTerms: ["t2"],
templateByTerm: { t2: 1}}
autoCompleteSet: [tt("t2", 1)]
}
]
);
@ -625,7 +621,7 @@ define([
{
name: "Path after empty object",
cursor: { row: 1, column: 10},
autoCompleteSet: { completionTerms: ["a", "b"] }
autoCompleteSet: ["a", "b"]
}
]
);
@ -671,14 +667,14 @@ define([
{
name: "List of objects - internal autocomplete",
cursor: { row: 3, column: 10},
autoCompleteSet: { completionTerms: ["b"] }
autoCompleteSet: ["b"]
},
{
name: "List of objects - external template",
cursor: { row: 0, column: 1},
autoCompleteSet: { completionTerms: ["a"], templateByTerm: { a: [
autoCompleteSet: [tt("a", [
{}
]} }
])]
}
]
);
@ -706,12 +702,12 @@ define([
{
name: "Field completion as scope",
cursor: { row: 3, column: 10},
autoCompleteSet: { completionTerms: ["field1.1.1", "field1.1.2"]}
autoCompleteSet: ["field1.1.1", "field1.1.2"]
},
{
name: "Field completion as value",
cursor: { row: 9, column: 23},
autoCompleteSet: { completionTerms: ["field1.1.1", "field1.1.2"]}
autoCompleteSet: ["field1.1.1", "field1.1.2"]
}
]
);
@ -726,7 +722,7 @@ define([
{
name: "initial doc start",
cursor: { row: 1, column: 0},
autoCompleteSet: { completionTerms: ["{"]},
autoCompleteSet: ["{"],
prefixToAdd: "",
suffixToAdd: ""
}
@ -747,10 +743,8 @@ define([
{
name: "Cursor rows after request end",
cursor: { row: 4, column: 0},
autoCompleteSet: {
completionTerms: [ "GET", "PUT", "POST", "DELETE", "HEAD" ]
},
prefixToAdd: "",
autoCompleteSet: [ "GET", "PUT", "POST", "DELETE", "HEAD" ],
prefixToAdd: "",
suffixToAdd: " "
},
{
@ -790,7 +784,7 @@ define([
{
name: "Endpoints with slashes - no slash",
cursor: { row: 0, column: 8},
autoCompleteSet: { completionTerms: [ "_search", "_cluster/stats", "_cluster/nodes/stats" ]},
autoCompleteSet: [ "_cluster/nodes/stats", "_cluster/stats", "_search"],
prefixToAdd: "",
suffixToAdd: ""
}
@ -806,14 +800,14 @@ define([
{
name: "Endpoints with slashes - before slash",
cursor: { row: 0, column: 8},
autoCompleteSet: { completionTerms: [ "_search", "_cluster/stats", "_cluster/nodes/stats" ]},
autoCompleteSet: [ "_cluster/nodes/stats", "_cluster/stats", "_search"],
prefixToAdd: "",
suffixToAdd: ""
},
{
name: "Endpoints with slashes - on slash",
cursor: { row: 0, column: 13},
autoCompleteSet: { completionTerms: [ "_search", "_cluster/stats", "_cluster/nodes/stats" ]},
autoCompleteSet: [ "_cluster/nodes/stats", "_cluster/stats", "_search"],
prefixToAdd: "",
suffixToAdd: ""
}
@ -829,7 +823,7 @@ define([
{
name: "Endpoints with slashes - after slash",
cursor: { row: 0, column: 15},
autoCompleteSet: { completionTerms: [ "stats", "nodes/stats" ]},
autoCompleteSet: [ { name: "nodes/stats", meta: "endpoint" } , { name: "stats", meta: "endpoint" } ],
prefixToAdd: "",
suffixToAdd: "",
initialValue: "no"
@ -846,7 +840,7 @@ define([
{
name: "Endpoints with two slashes",
cursor: { row: 0, column: 21},
autoCompleteSet: { completionTerms: ["stats" ]},
autoCompleteSet: ["stats" ],
prefixToAdd: "",
suffixToAdd: "",
initialValue: "st"
@ -862,9 +856,15 @@ define([
[
{
name: "Endpoints by subpart",
cursor: { row: 0, column: 14},
autoCompleteSet: { completionTerms: [ "index1", "index2", "_search", "_cluster/stats", "_cluster/nodes/stats" ]},
prefixToAdd: "",
cursor: { row: 0, column: 7},
autoCompleteSet: [
{ name: "_cluster/nodes/stats", meta: "endpoint" },
{ name: "_cluster/stats", meta: "endpoint" },
{ name: "_search", meta: "endpoint" },
{ name: "index1", meta: "index" },
{ name: "index2", meta: "index" }
],
prefixToAdd: "",
suffixToAdd: "",
initialValue: "cl"
}

View file

@ -5,17 +5,21 @@ define([
], function (ace, input, $) {
'use strict';
var token_iterator = ace.require("ace/token_iterator");
module("Tokenization", {
setup: function () {
input.$el.show();
input.autocomplete._test.removeChangeListener();
},
teardown: function () {
input.$el.hide();
input.autocomplete._test.addChangeListener();
}
});
function tokensAsList() {
var iter = new (ace.require("ace/token_iterator").TokenIterator)(input.getSession(), 0, 0);
var iter = new token_iterator.TokenIterator(input.getSession(), 0, 0);
var ret = [];
var t = iter.getCurrentToken();
if (input.parser.isEmptyToken(t)) t = input.parser.nextNonEmptyToken(iter);
@ -187,6 +191,18 @@ define([
'}'
);
token_test(
[ "method", "POST", "url.endpoint", "_search", "paren.lparen", "{", "variable", '"q"', "punctuation.colon", ":",
"paren.lparen", "{", "variable", '"s"', "punctuation.colon", ":", "paren.lparen", "{", "paren.rparen", "}",
"paren.rparen", "}", "paren.rparen", "}"
],
'POST _search\n' +
'{\n' +
' "q": { "s": {}}\n' +
' \n' +
'}'
);
function statesAsList() {
var ret = [];
var session = input.getSession();
@ -215,18 +231,22 @@ define([
}
function n(name) {
return { name: name};
}
function nd(name, depth) {
return { name: name, depth: depth };
}
states_test(
[n("start"), nd("json", 1), nd("json", 1), nd("start", 0) ],
["start", "json", "json", "start" ],
'POST _search\n' +
'{\n' +
' "query": { "match_all": {} }\n' +
'}'
);
})
states_test(
["start", "json", ["json", "json"], ["json", "json"], "json", "start" ],
'POST _search\n' +
'{\n' +
' "query": { \n' +
' "match_all": {} \n' +
' }\n' +
'}'
);
});

8326
sense/vendor/ace/ace.js vendored

File diff suppressed because it is too large Load diff

1665
sense/vendor/ace/ext-language_tools.js vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -41,7 +41,7 @@ var CStyleFoldMode = require("./folding/cstyle").FoldMode;
var WorkerClient = require("../worker/worker_client").WorkerClient;
var Mode = function() {
this.$tokenizer = new Tokenizer(new HighlightRules().getRules());
this.HighlightRules = HighlightRules;
this.$outdent = new MatchingBraceOutdent();
this.$behaviour = new CstyleBehaviour();
this.foldingRules = new CStyleFoldMode();
@ -87,6 +87,7 @@ oop.inherits(Mode, TextMode);
};
this.$id = "ace/mode/json";
}).call(Mode.prototype);
exports.Mode = Mode;
@ -140,18 +141,15 @@ var JsonHighlightRules = function() {
regex : /\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|["\\\/bfnrt])/
}, {
token : "string",
regex : '[^"\\\\]+',
merge : true
regex : '[^"\\\\]+'
}, {
token : "string",
regex : '"',
next : "start",
merge : true
next : "start"
}, {
token : "string",
regex : "",
next : "start",
merge : true
next : "start"
}
]
};
@ -195,12 +193,7 @@ var MatchingBraceOutdent = function() {};
};
this.$getIndent = function(line) {
var match = line.match(/^(\s+)/);
if (match) {
return match[1];
}
return "";
return line.match(/^\s*/)[0];
};
}).call(MatchingBraceOutdent.prototype);
@ -208,30 +201,41 @@ var MatchingBraceOutdent = function() {};
exports.MatchingBraceOutdent = MatchingBraceOutdent;
});
ace.define('ace/mode/behaviour/cstyle', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/behaviour', 'ace/token_iterator'], function(require, exports, module) {
ace.define('ace/mode/behaviour/cstyle', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/behaviour', 'ace/token_iterator', 'ace/lib/lang'], function(require, exports, module) {
var oop = require("../../lib/oop");
var Behaviour = require("../behaviour").Behaviour;
var TokenIterator = require("../../token_iterator").TokenIterator;
var lang = require("../../lib/lang");
var SAFE_INSERT_IN_TOKENS =
["text", "paren.rparen", "punctuation.operator"];
var SAFE_INSERT_BEFORE_TOKENS =
["text", "paren.rparen", "punctuation.operator", "comment"];
var autoInsertedBrackets = 0;
var autoInsertedRow = -1;
var autoInsertedLineEnd = "";
var maybeInsertedBrackets = 0;
var maybeInsertedRow = -1;
var maybeInsertedLineStart = "";
var maybeInsertedLineEnd = "";
var CstyleBehaviour = function () {
CstyleBehaviour.isSaneInsertion = function(editor, session) {
var cursor = editor.getCursorPosition();
var iterator = new TokenIterator(session, cursor.row, cursor.column);
if (!this.$matchTokenType(iterator.getCurrentToken() || "text", ["text", "paren.rparen"])) {
iterator = new TokenIterator(session, cursor.row, cursor.column + 1);
if (!this.$matchTokenType(iterator.getCurrentToken() || "text", ["text", "paren.rparen"]))
if (!this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS)) {
var iterator2 = new TokenIterator(session, cursor.row, cursor.column + 1);
if (!this.$matchTokenType(iterator2.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS))
return false;
}
iterator.stepForward();
return iterator.getCurrentTokenRow() !== cursor.row ||
this.$matchTokenType(iterator.getCurrentToken() || "text", ["text", "comment", "paren.rparen"]);
this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_BEFORE_TOKENS);
};
CstyleBehaviour.$matchTokenType = function(token, types) {
@ -248,6 +252,17 @@ var CstyleBehaviour = function () {
autoInsertedBrackets++;
};
CstyleBehaviour.recordMaybeInsert = function(editor, session, bracket) {
var cursor = editor.getCursorPosition();
var line = session.doc.getLine(cursor.row);
if (!this.isMaybeInsertedClosing(cursor, line))
maybeInsertedBrackets = 0;
maybeInsertedRow = cursor.row;
maybeInsertedLineStart = line.substr(0, cursor.column) + bracket;
maybeInsertedLineEnd = line.substr(cursor.column);
maybeInsertedBrackets++;
};
CstyleBehaviour.isAutoInsertedClosing = function(cursor, line, bracket) {
return autoInsertedBrackets > 0 &&
cursor.row === autoInsertedRow &&
@ -255,30 +270,50 @@ var CstyleBehaviour = function () {
line.substr(cursor.column) === autoInsertedLineEnd;
};
CstyleBehaviour.isMaybeInsertedClosing = function(cursor, line) {
return maybeInsertedBrackets > 0 &&
cursor.row === maybeInsertedRow &&
line.substr(cursor.column) === maybeInsertedLineEnd &&
line.substr(0, cursor.column) == maybeInsertedLineStart;
};
CstyleBehaviour.popAutoInsertedClosing = function() {
autoInsertedLineEnd = autoInsertedLineEnd.substr(1);
autoInsertedBrackets--;
};
CstyleBehaviour.clearMaybeInsertedClosing = function() {
maybeInsertedBrackets = 0;
maybeInsertedRow = -1;
};
this.add("braces", "insertion", function (state, action, editor, session, text) {
var cursor = editor.getCursorPosition();
var line = session.doc.getLine(cursor.row);
if (text == '{') {
var selection = editor.getSelectionRange();
var selected = session.doc.getTextRange(selection);
if (selected !== "" && selected !== "{") {
if (selected !== "" && selected !== "{" && editor.getWrapBehavioursEnabled()) {
return {
text: '{' + selected + '}',
selection: false
};
} else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
CstyleBehaviour.recordAutoInsert(editor, session, "}");
return {
text: '{}',
selection: [1, 1]
};
if (/[\]\}\)]/.test(line[cursor.column]) || editor.inMultiSelectMode) {
CstyleBehaviour.recordAutoInsert(editor, session, "}");
return {
text: '{}',
selection: [1, 1]
};
} else {
CstyleBehaviour.recordMaybeInsert(editor, session, "{");
return {
text: '{',
selection: [1, 1]
};
}
}
} else if (text == '}') {
var cursor = editor.getCursorPosition();
var line = session.doc.getLine(cursor.row);
var rightChar = line.substring(cursor.column, cursor.column + 1);
if (rightChar == '}') {
var matching = session.$findOpeningBracket('}', {column: cursor.column + 1, row: cursor.row});
@ -291,22 +326,30 @@ var CstyleBehaviour = function () {
}
}
} else if (text == "\n" || text == "\r\n") {
var cursor = editor.getCursorPosition();
var line = session.doc.getLine(cursor.row);
var closing = "";
if (CstyleBehaviour.isMaybeInsertedClosing(cursor, line)) {
closing = lang.stringRepeat("}", maybeInsertedBrackets);
CstyleBehaviour.clearMaybeInsertedClosing();
}
var rightChar = line.substring(cursor.column, cursor.column + 1);
if (rightChar == '}') {
var openBracePos = session.findMatchingBracket({row: cursor.row, column: cursor.column + 1});
if (rightChar === '}') {
var openBracePos = session.findMatchingBracket({row: cursor.row, column: cursor.column+1}, '}');
if (!openBracePos)
return null;
var indent = this.getNextLineIndent(state, line.substring(0, line.length - 1), session.getTabString());
var next_indent = this.$getIndent(session.doc.getLine(openBracePos.row));
return {
text: '\n' + indent + '\n' + next_indent,
selection: [1, indent.length, 1, indent.length]
};
var next_indent = this.$getIndent(session.getLine(openBracePos.row));
} else if (closing) {
var next_indent = this.$getIndent(line);
} else {
return;
}
var indent = next_indent + session.getTabString();
return {
text: '\n' + indent + '\n' + next_indent + closing,
selection: [1, indent.length, 1, indent.length]
};
} else {
CstyleBehaviour.clearMaybeInsertedClosing();
}
});
@ -318,6 +361,8 @@ var CstyleBehaviour = function () {
if (rightChar == '}') {
range.end.column++;
return range;
} else {
maybeInsertedBrackets--;
}
}
});
@ -326,7 +371,7 @@ var CstyleBehaviour = function () {
if (text == '(') {
var selection = editor.getSelectionRange();
var selected = session.doc.getTextRange(selection);
if (selected !== "") {
if (selected !== "" && editor.getWrapBehavioursEnabled()) {
return {
text: '(' + selected + ')',
selection: false
@ -371,7 +416,7 @@ var CstyleBehaviour = function () {
if (text == '[') {
var selection = editor.getSelectionRange();
var selected = session.doc.getTextRange(selection);
if (selected !== "") {
if (selected !== "" && editor.getWrapBehavioursEnabled()) {
return {
text: '[' + selected + ']',
selection: false
@ -417,7 +462,7 @@ var CstyleBehaviour = function () {
var quote = text;
var selection = editor.getSelectionRange();
var selected = session.doc.getTextRange(selection);
if (selected !== "") {
if (selected !== "" && selected !== "'" && selected != '"' && editor.getWrapBehavioursEnabled()) {
return {
text: quote + selected + quote,
selection: false
@ -446,6 +491,8 @@ var CstyleBehaviour = function () {
col += tokens[x].value.length;
}
if (!token || (quotepos < 0 && token.type !== "comment" && (token.type !== "string" || ((selection.start.column !== token.value.length+col-1) && token.value.lastIndexOf(quote) === token.value.length-1)))) {
if (!CstyleBehaviour.isSaneInsertion(editor, session))
return;
return {
text: quote + quote,
selection: [1,1]
@ -468,7 +515,7 @@ var CstyleBehaviour = function () {
if (!range.isMultiLine() && (selected == '"' || selected == "'")) {
var line = session.doc.getLine(range.start.row);
var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
if (rightChar == '"') {
if (rightChar == selected) {
range.end.column++;
return range;
}
@ -489,7 +536,16 @@ var oop = require("../../lib/oop");
var Range = require("../../range").Range;
var BaseFoldMode = require("./fold_mode").FoldMode;
var FoldMode = exports.FoldMode = function() {};
var FoldMode = exports.FoldMode = function(commentRegex) {
if (commentRegex) {
this.foldingStartMarker = new RegExp(
this.foldingStartMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.start)
);
this.foldingStopMarker = new RegExp(
this.foldingStopMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.end)
);
}
};
oop.inherits(FoldMode, BaseFoldMode);
(function() {
@ -497,7 +553,7 @@ oop.inherits(FoldMode, BaseFoldMode);
this.foldingStartMarker = /(\{|\[)[^\}\]]*$|^\s*(\/\*)/;
this.foldingStopMarker = /^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/;
this.getFoldWidgetRange = function(session, foldStyle, row) {
this.getFoldWidgetRange = function(session, foldStyle, row, forceMultiline) {
var line = session.getLine(row);
var match = line.match(this.foldingStartMarker);
if (match) {
@ -505,11 +561,20 @@ oop.inherits(FoldMode, BaseFoldMode);
if (match[1])
return this.openingBracketBlock(session, match[1], row, i);
return session.getCommentFoldRange(row, i + match[0].length, 1);
var range = session.getCommentFoldRange(row, i + match[0].length, 1);
if (range && !range.isMultiLine()) {
if (forceMultiline) {
range = this.getSectionRange(session, row);
} else if (foldStyle != "all")
range = null;
}
return range;
}
if (foldStyle !== "markbeginend")
if (foldStyle === "markbegin")
return;
var match = line.match(this.foldingStopMarker);
@ -522,6 +587,38 @@ oop.inherits(FoldMode, BaseFoldMode);
return session.getCommentFoldRange(row, i, -1);
}
};
this.getSectionRange = function(session, row) {
var line = session.getLine(row);
var startIndent = line.search(/\S/);
var startRow = row;
var startColumn = line.length;
row = row + 1;
var endRow = row;
var maxRow = session.getLength();
while (++row < maxRow) {
line = session.getLine(row);
var indent = line.search(/\S/);
if (indent === -1)
continue;
if (startIndent > indent)
break;
var subRange = this.getFoldWidgetRange(session, "all", row);
if (subRange) {
if (subRange.start.row <= startRow) {
break;
} else if (subRange.isMultiLine()) {
row = subRange.end.row;
} else if (startIndent == indent) {
break;
}
}
endRow = row;
}
return new Range(startRow, startColumn, endRow, session.getLine(endRow).length);
};
}).call(FoldMode.prototype);

View file

@ -1,742 +0,0 @@
ace.define('ace/mode/sense', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/text', 'ace/tokenizer', 'ace/mode/sense_json_highlight_rules', 'ace/mode/matching_brace_outdent', 'ace/mode/behaviour/cstyle', 'ace/mode/folding/cstyle', 'ace/worker/worker_client'], function (require, exports, module) {
var oop = require("../lib/oop");
var TextMode = require("./text").Mode;
var HighlightRules = require("./sense_json_highlight_rules").SenseJsonHighlightRules;
var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;
var CStyleFoldMode = require("./folding/cstyle").FoldMode;
var WorkerClient = require("../worker/worker_client").WorkerClient;
var Tokenizer = function (rules, flag) {
this.constructor(rules, flag);
};
(function () {
this.constructor = require("../tokenizer").Tokenizer;
this.prototype = this.constructor.prototype;
this.getLineTokens = function (line, startState) {
var currentState;
if (!startState) {
currentState = { name: "start"};
} else if (typeof startState === "string") {
currentState = { name: startState };
}
else {
currentState = startState;
}
var state = this.rules[currentState.name];
var mapping = this.matchMappings[currentState.name];
var re = this.regExps[currentState.name];
re.lastIndex = 0;
var match, tokens = [];
var lastIndex = 0;
var token = {
type: null,
value: ""
};
while (match = re.exec(line)) {
var type = "text";
var rule = null;
var value = [match[0]];
for (var i = 0; i < match.length - 2; i++) {
if (match[i + 1] === undefined)
continue;
rule = state[mapping[i].rule];
if (mapping[i].len > 1)
value = match.slice(i + 2, i + 1 + mapping[i].len);
if (typeof rule.token == "function")
type = rule.token.apply(this, value);
else
type = rule.token;
var next = rule.next;
if (typeof next == "function") {
next = next.call(this, currentState, type, value);
}
if (typeof next == "string") next = { name: next };
if (next) {
currentState = next;
state = this.rules[currentState.name];
mapping = this.matchMappings[currentState.name];
lastIndex = re.lastIndex;
re = this.regExps[currentState.name];
if (re === undefined) {
throw new Error("You indicated a state of " + next + " to go to, but it doesn't exist!");
}
re.lastIndex = lastIndex;
}
break;
}
if (value[0]) {
if (typeof type == "string") {
value = [value.join("")];
type = [type];
}
for (var i = 0; i < value.length; i++) {
if (!value[i])
continue;
if ((!rule || rule.merge || type[i] === "text") && token.type === type[i]) {
token.value += value[i];
} else {
if (token.type)
tokens.push(token);
token = {
type: type[i],
value: value[i]
};
}
}
}
if (lastIndex == line.length)
break;
lastIndex = re.lastIndex;
}
if (token.type)
tokens.push(token);
return {
tokens: tokens,
state: currentState
};
};
return this;
}).call(Tokenizer.prototype);
var Mode = function () {
this.$tokenizer = new Tokenizer(new HighlightRules().getRules());
this.$outdent = new MatchingBraceOutdent();
this.$behaviour = new CstyleBehaviour();
this.foldingRules = new CStyleFoldMode();
};
oop.inherits(Mode, TextMode);
(function () {
this.getNextLineIndent = function (state, line, tab) {
var indent = this.$getIndent(line);
if (state != "double_q_string") {
var match = line.match(/^.*[\{\(\[]\s*$/);
if (match) {
indent += tab;
}
}
return indent;
};
this.checkOutdent = function (state, line, input) {
return this.$outdent.checkOutdent(line, input);
};
this.autoOutdent = function (state, doc, row) {
this.$outdent.autoOutdent(doc, row);
};
this.createWorker = function (session) {
var worker = new WorkerClient(["ace"], "ace/mode/sense_worker", "SenseWorker");
worker.attachToDocument(session.getDocument());
worker.on("error", function (e) {
session.setAnnotations([e.data]);
});
worker.on("ok", function (anno) {
session.setAnnotations(anno.data);
});
return worker;
};
}).call(Mode.prototype);
exports.Mode = Mode;
});
ace.define('ace/mode/sense_json_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/text_highlight_rules'], function (require, exports, module) {
var oop = require("../lib/oop");
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
var SenseJsonHighlightRules = function () {
function mergeTokens(/* ... */) {
return [].concat.apply([], arguments);
}
function addEOL(tokens, reg, nextIfEOL, normalNext) {
if (typeof reg == "object") reg = reg.source;
return [
{ token: tokens.concat(["whitespace"]), regex: reg + "(\\s*)$", next: nextIfEOL },
{ token: tokens, regex: reg, next: normalNext }
];
}
function scopeIncrement(next) {
return function (state) {
state = { name: next, depth: state.depth };
if (!state.depth) {
state.depth = 1;
}
else {
state.depth++;
}
return state;
}
}
function scopeDecrement(next, nextIfZero) {
return function (state) {
state = { name: state.name, depth: state.depth };
if (!state.depth) {
state.name = next;
}
else {
state.depth--;
state.name = state.depth == 0 ? nextIfZero : next;
}
return state;
};
}
// regexp must not have capturing parentheses. Use (?:) instead.
// regexps are ordered -> the first match is used
this.$rules = {
"start": mergeTokens([
{ token: "comment", regex: /^#.*$/},
{ token: "paren.lparen", regex: "{", next: scopeIncrement("json") },
],
addEOL(["method"], /([a-zA-Z]+)/, "start", "method_sep")
,
[
{
token: "whitespace",
regex: "\\s+"
},
{
token: "text",
regex: ".+?"
}
]),
"method_sep": mergeTokens(
addEOL(["whitespace", "url.slash"], /(\s+)(\/)/, "start", "indices"),
addEOL(["whitespace"], /(\s+)/, "start", "indices")
),
"indices": mergeTokens(
addEOL(["url.scheme", "url.host", "url.slash"], /([^:]+:\/\/)([^?\/\s]*)(\/?)/, "start"),
addEOL(["url.index"], /(_all)/, "start"),
addEOL(["url.endpoint"], /(_[^\/?]+)/, "start", "urlRest"),
addEOL(["url.index"], /([^\/?,]+)/, "start"),
addEOL(["url.comma"], /(,)/, "start"),
addEOL(["url.slash"], /(\/)/, "start", "types"),
addEOL(["url.questionmark"], /(\?)/, "start", "urlParams")
),
"types": mergeTokens(
addEOL(["url.endpoint"], /(_[^\/?]+)/, "start", "urlRest"),
addEOL(["url.type"], /([^\/?,]+)/, "start"),
addEOL(["url.comma"], /(,)/, "start"),
addEOL(["url.slash"], /(\/)/, "start", "id"),
addEOL(["url.questionmark"], /(\?)/, "start", "urlParams")
),
"id": mergeTokens(
addEOL(["url.endpoint"], /(_[^\/?]+)/, "start", "urlRest"),
addEOL(["url.id"], /([^\/?]+)/, "start"),
addEOL(["url.slash"], /(\/)/, "start", "urlRest"),
addEOL(["url.questionmark"], /(\?)/, "start", "urlParams")
),
"urlRest": mergeTokens(
addEOL(["url.part"], /([^?\/]+)/, "start"),
addEOL(["url.slash"], /(\/)/, "start"),
addEOL(["url.questionmark"], /(\?)/, "start", "urlParams")
),
"urlParams": mergeTokens(
addEOL(["url.param", "url.equal", "url.value"], /([^&=]+)(=)([^&]*)/, "start"),
addEOL(["url.param"], /([^&=]+)/, "start"),
addEOL(["url.amp"], /(&)/, "start")
),
"json": [
{
token: "variable", // single line
regex: '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]\\s*(?=:)'
},
{
token: "string", // single line
regex: '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'
},
{
token: "constant.numeric", // hex
regex: "0[xX][0-9a-fA-F]+\\b"
},
{
token: "constant.numeric", // float
regex: "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"
},
{
token: "constant.language.boolean",
regex: "(?:true|false)\\b"
},
{
token: "invalid.illegal", // single quoted strings are not allowed
regex: "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"
},
{
token: "invalid.illegal", // comments are not allowed
regex: "\\/\\/.*$"
},
{
token: "paren.lparen",
regex: "{",
next: scopeIncrement("json")
},
{
token: "paren.lparen",
regex: "[[(]"
},
{
token: "paren.rparen",
regex: "[\\])]"
},
{
token: "paren.rparen",
regex: "}",
next: scopeDecrement("json", "start")
},
{
token: "punctuation.comma",
regex: ","
},
{
token: "punctuation.colon",
regex: ":"
},
{
token: "whitespace",
regex: "\\s+"
},
{
token: "text",
regex: ".+?"
}
],
"double_q_string": [
{
token: "string",
regex: '[^"]+'
},
{
token: "punctuation.end_quote",
regex: '"',
next: "json"
},
{
token: "string",
regex: "",
next: "json"
}
]
}
};
oop.inherits(SenseJsonHighlightRules, TextHighlightRules);
exports.SenseJsonHighlightRules = SenseJsonHighlightRules;
});
ace.define('ace/mode/matching_brace_outdent', ['require', 'exports', 'module' , 'ace/range'], function (require, exports, module) {
var Range = require("../range").Range;
var MatchingBraceOutdent = function () {
};
(function () {
this.checkOutdent = function (line, input) {
if (!/^\s+$/.test(line))
return false;
return /^\s*\}/.test(input);
};
this.autoOutdent = function (doc, row) {
var line = doc.getLine(row);
var match = line.match(/^(\s*\})/);
if (!match) return 0;
var column = match[1].length;
var openBracePos = doc.findMatchingBracket({row: row, column: column});
if (!openBracePos || openBracePos.row == row) return 0;
var indent = this.$getIndent(doc.getLine(openBracePos.row));
doc.replace(new Range(row, 0, row, column - 1), indent);
};
this.$getIndent = function (line) {
var match = line.match(/^(\s+)/);
if (match) {
return match[1];
}
return "";
};
}).call(MatchingBraceOutdent.prototype);
exports.MatchingBraceOutdent = MatchingBraceOutdent;
});
ace.define('ace/mode/behaviour/cstyle', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/behaviour', 'ace/token_iterator'], function (require, exports, module) {
var oop = require("../../lib/oop");
var Behaviour = require("../behaviour").Behaviour;
var TokenIterator = require("../../token_iterator").TokenIterator;
var autoInsertedBrackets = 0;
var autoInsertedRow = -1;
var autoInsertedLineEnd = "";
var CstyleBehaviour = function () {
CstyleBehaviour.isSaneInsertion = function (editor, session) {
var cursor = editor.getCursorPosition();
var iterator = new TokenIterator(session, cursor.row, cursor.column);
if (!this.$matchTokenType(iterator.getCurrentToken() || "text", ["text", "paren.rparen"])) {
iterator = new TokenIterator(session, cursor.row, cursor.column + 1);
if (!this.$matchTokenType(iterator.getCurrentToken() || "text", ["text", "paren.rparen"]))
return false;
}
iterator.stepForward();
return iterator.getCurrentTokenRow() !== cursor.row ||
this.$matchTokenType(iterator.getCurrentToken() || "text", ["text", "comment", "paren.rparen"]);
};
CstyleBehaviour.$matchTokenType = function (token, types) {
return types.indexOf(token.type || token) > -1;
};
CstyleBehaviour.recordAutoInsert = function (editor, session, bracket) {
var cursor = editor.getCursorPosition();
var line = session.doc.getLine(cursor.row);
if (!this.isAutoInsertedClosing(cursor, line, autoInsertedLineEnd[0]))
autoInsertedBrackets = 0;
autoInsertedRow = cursor.row;
autoInsertedLineEnd = bracket + line.substr(cursor.column);
autoInsertedBrackets++;
};
CstyleBehaviour.isAutoInsertedClosing = function (cursor, line, bracket) {
return autoInsertedBrackets > 0 &&
cursor.row === autoInsertedRow &&
bracket === autoInsertedLineEnd[0] &&
line.substr(cursor.column) === autoInsertedLineEnd;
};
CstyleBehaviour.popAutoInsertedClosing = function () {
autoInsertedLineEnd = autoInsertedLineEnd.substr(1);
autoInsertedBrackets--;
};
this.add("braces", "insertion", function (state, action, editor, session, text) {
if (text == '{') {
var selection = editor.getSelectionRange();
var selected = session.doc.getTextRange(selection);
if (selected !== "" && selected !== "{") {
return {
text: '{' + selected + '}',
selection: false
};
} else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
CstyleBehaviour.recordAutoInsert(editor, session, "}");
return {
text: '{}',
selection: [1, 1]
};
}
} else if (text == '}') {
var cursor = editor.getCursorPosition();
var line = session.doc.getLine(cursor.row);
var rightChar = line.substring(cursor.column, cursor.column + 1);
if (rightChar == '}') {
var matching = session.$findOpeningBracket('}', {column: cursor.column + 1, row: cursor.row});
if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
CstyleBehaviour.popAutoInsertedClosing();
return {
text: '',
selection: [1, 1]
};
}
}
} else if (text == "\n" || text == "\r\n") {
var cursor = editor.getCursorPosition();
var line = session.doc.getLine(cursor.row);
var rightChar = line.substring(cursor.column, cursor.column + 1);
if (rightChar == '}') {
var openBracePos = session.findMatchingBracket({row: cursor.row, column: cursor.column + 1});
if (!openBracePos)
return null;
var indent = this.getNextLineIndent(state, line.substring(0, line.length - 1), session.getTabString());
var next_indent = this.$getIndent(session.doc.getLine(openBracePos.row));
return {
text: '\n' + indent + '\n' + next_indent,
selection: [1, indent.length, 1, indent.length]
};
}
}
});
this.add("braces", "deletion", function (state, action, editor, session, range) {
var selected = session.doc.getTextRange(range);
if (!range.isMultiLine() && selected == '{') {
var line = session.doc.getLine(range.start.row);
var rightChar = line.substring(range.end.column, range.end.column + 1);
if (rightChar == '}') {
range.end.column++;
return range;
}
}
});
this.add("parens", "insertion", function (state, action, editor, session, text) {
if (text == '(') {
var selection = editor.getSelectionRange();
var selected = session.doc.getTextRange(selection);
if (selected !== "") {
return {
text: '(' + selected + ')',
selection: false
};
} else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
CstyleBehaviour.recordAutoInsert(editor, session, ")");
return {
text: '()',
selection: [1, 1]
};
}
} else if (text == ')') {
var cursor = editor.getCursorPosition();
var line = session.doc.getLine(cursor.row);
var rightChar = line.substring(cursor.column, cursor.column + 1);
if (rightChar == ')') {
var matching = session.$findOpeningBracket(')', {column: cursor.column + 1, row: cursor.row});
if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
CstyleBehaviour.popAutoInsertedClosing();
return {
text: '',
selection: [1, 1]
};
}
}
}
});
this.add("parens", "deletion", function (state, action, editor, session, range) {
var selected = session.doc.getTextRange(range);
if (!range.isMultiLine() && selected == '(') {
var line = session.doc.getLine(range.start.row);
var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
if (rightChar == ')') {
range.end.column++;
return range;
}
}
});
this.add("brackets", "insertion", function (state, action, editor, session, text) {
if (text == '[') {
var selection = editor.getSelectionRange();
var selected = session.doc.getTextRange(selection);
if (selected !== "") {
return {
text: '[' + selected + ']',
selection: false
};
} else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
CstyleBehaviour.recordAutoInsert(editor, session, "]");
return {
text: '[]',
selection: [1, 1]
};
}
} else if (text == ']') {
var cursor = editor.getCursorPosition();
var line = session.doc.getLine(cursor.row);
var rightChar = line.substring(cursor.column, cursor.column + 1);
if (rightChar == ']') {
var matching = session.$findOpeningBracket(']', {column: cursor.column + 1, row: cursor.row});
if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
CstyleBehaviour.popAutoInsertedClosing();
return {
text: '',
selection: [1, 1]
};
}
}
}
});
this.add("brackets", "deletion", function (state, action, editor, session, range) {
var selected = session.doc.getTextRange(range);
if (!range.isMultiLine() && selected == '[') {
var line = session.doc.getLine(range.start.row);
var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
if (rightChar == ']') {
range.end.column++;
return range;
}
}
});
this.add("string_dquotes", "insertion", function (state, action, editor, session, text) {
if (text == '"' || text == "'") {
var quote = text;
var selection = editor.getSelectionRange();
var selected = session.doc.getTextRange(selection);
if (selected !== "") {
return {
text: quote + selected + quote,
selection: false
};
} else {
var cursor = editor.getCursorPosition();
var line = session.doc.getLine(cursor.row);
var leftChar = line.substring(cursor.column - 1, cursor.column);
if (leftChar == '\\') {
return null;
}
var tokens = session.getTokens(selection.start.row);
var col = 0, token;
var quotepos = -1; // Track whether we're inside an open quote.
for (var x = 0; x < tokens.length; x++) {
token = tokens[x];
if (token.type == "string") {
quotepos = -1;
} else if (quotepos < 0) {
quotepos = token.value.indexOf(quote);
}
if ((token.value.length + col) > selection.start.column) {
break;
}
col += tokens[x].value.length;
}
if (!token || (quotepos < 0 && token.type !== "comment" && (token.type !== "string" || ((selection.start.column !== token.value.length + col - 1) && token.value.lastIndexOf(quote) === token.value.length - 1)))) {
return {
text: quote + quote,
selection: [1, 1]
};
} else if (token && token.type === "string") {
var rightChar = line.substring(cursor.column, cursor.column + 1);
if (rightChar == quote) {
return {
text: '',
selection: [1, 1]
};
}
}
}
}
});
this.add("string_dquotes", "deletion", function (state, action, editor, session, range) {
var selected = session.doc.getTextRange(range);
if (!range.isMultiLine() && (selected == '"' || selected == "'")) {
var line = session.doc.getLine(range.start.row);
var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
if (rightChar == '"') {
range.end.column++;
return range;
}
}
});
};
oop.inherits(CstyleBehaviour, Behaviour);
exports.CstyleBehaviour = CstyleBehaviour;
});
ace.define('ace/mode/folding/cstyle', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/range', 'ace/mode/folding/fold_mode'], function (require, exports, module) {
var oop = require("../../lib/oop");
var Range = require("../../range").Range;
var BaseFoldMode = require("./fold_mode").FoldMode;
var FoldMode = exports.FoldMode = function () {
};
oop.inherits(FoldMode, BaseFoldMode);
(function () {
this.foldingStartMarker = /(\{|\[)[^\}\]]*$|^\s*(\/\*)/;
this.foldingStopMarker = /^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/;
this.getFoldWidgetRange = function (session, foldStyle, row) {
var line = session.getLine(row);
var match = line.match(this.foldingStartMarker);
if (match) {
var i = match.index;
if (match[1])
return this.openingBracketBlock(session, match[1], row, i);
return session.getCommentFoldRange(row, i + match[0].length, 1);
}
if (foldStyle !== "markbeginend")
return;
var match = line.match(this.foldingStopMarker);
if (match) {
var i = match.index + match[0].length;
if (match[1])
return this.closingBracketBlock(session, match[1], row, i);
return session.getCommentFoldRange(row, i, -1);
}
};
}).call(FoldMode.prototype);
});

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff