wide/static/js/editor.js

310 lines
10 KiB
JavaScript
Raw Normal View History

2014-08-19 13:07:35 +04:00
var editors = {
data: [],
2014-09-23 17:03:44 +04:00
tabs: {},
2014-09-17 06:04:41 +04:00
init: function () {
2014-08-19 13:07:35 +04:00
editors._initAutocomplete();
2014-08-29 13:24:08 +04:00
editors.tabs = new Tabs({
id: ".edit-panel",
2014-09-17 06:04:41 +04:00
clickAfter: function (id) {
2014-08-29 13:24:08 +04:00
// set tree node selected
var node = tree.fileTree.getNodeByTId(id);
tree.fileTree.selectNode(node);
wide.curNode = node;
for (var i = 0, ii = editors.data.length; i < ii; i++) {
if (editors.data[i].id === id) {
wide.curEditor = editors.data[i].editor;
break;
}
}
2014-09-13 09:05:50 +04:00
wide.curEditor.focus();
2014-08-29 13:24:08 +04:00
},
2014-09-17 06:04:41 +04:00
removeAfter: function (id, nextId) {
2014-08-29 13:24:08 +04:00
for (var i = 0, ii = editors.data.length; i < ii; i++) {
if (editors.data[i].id === id) {
editors.data.splice(i, 1);
break;
}
}
if (!nextId) {
// 不存在打开的编辑器
// remove selected tree node
tree.fileTree.cancelSelectedNode();
wide.curNode = undefined;
wide.curEditor = undefined;
2014-09-24 08:07:20 +04:00
$(".toolbars").hide();
2014-08-29 13:24:08 +04:00
return false;
}
2014-08-30 08:54:46 +04:00
2014-08-29 13:24:08 +04:00
if (nextId === editors.tabs.getCurrentId()) {
return false;
}
// set tree node selected
var node = tree.fileTree.getNodeByTId(nextId);
tree.fileTree.selectNode(node);
wide.curNode = node;
for (var i = 0, ii = editors.data.length; i < ii; i++) {
if (editors.data[i].id === nextId) {
wide.curEditor = editors.data[i].editor;
break;
}
}
}
});
2014-09-06 17:24:28 +04:00
2014-09-17 06:04:41 +04:00
$(".edit-header .tabs").on("dblclick", "div", function () {
2014-09-03 13:23:42 +04:00
editors.fullscreen();
});
2014-08-19 13:07:35 +04:00
},
2014-09-17 06:04:41 +04:00
fullscreen: function () {
2014-08-30 08:54:46 +04:00
wide.curEditor.setOption("fullScreen", true);
2014-09-13 20:07:03 +04:00
wide.curEditor.focus();
2014-08-30 08:54:46 +04:00
},
2014-09-17 06:04:41 +04:00
_initAutocomplete: function () {
CodeMirror.registerHelper("hint", "go", function (editor) {
2014-08-27 14:10:12 +04:00
var word = /[\w$]+/;
2014-08-22 05:44:41 +04:00
var cur = editor.getCursor(), curLine = editor.getLine(cur.line);
2014-08-27 14:10:12 +04:00
var start = cur.ch, end = start;
2014-08-31 17:49:27 +04:00
while (end < curLine.length && word.test(curLine.charAt(end))) {
2014-08-27 14:10:12 +04:00
++end;
2014-09-02 20:05:05 +04:00
}
2014-08-31 17:49:27 +04:00
while (start && word.test(curLine.charAt(start - 1))) {
2014-08-27 14:10:12 +04:00
--start;
2014-09-02 20:05:05 +04:00
}
2014-09-17 06:04:41 +04:00
var request = newWideRequest();
request.path = $(".edit-header .current > span:eq(0)").attr("title");
request.code = editor.getValue();
request.cursorLine = cur.line;
request.cursorCh = cur.ch;
2014-08-18 17:45:43 +04:00
2014-08-19 13:07:35 +04:00
var autocompleteHints = [];
2014-08-18 17:45:43 +04:00
2014-08-19 13:07:35 +04:00
$.ajax({
async: false, // 同步执行
type: 'POST',
url: '/autocomplete',
data: JSON.stringify(request),
dataType: "json",
2014-09-17 06:04:41 +04:00
success: function (data) {
2014-08-19 13:07:35 +04:00
var autocompleteArray = data[1];
2014-08-27 14:10:12 +04:00
if (autocompleteArray) {
for (var i = 0; i < autocompleteArray.length; i++) {
autocompleteHints[i] = autocompleteArray[i].name;
}
}
2014-08-18 17:45:43 +04:00
}
2014-08-19 13:07:35 +04:00
});
2014-08-22 05:44:41 +04:00
return {list: autocompleteHints, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end)};
});
2014-08-27 14:10:12 +04:00
2014-09-17 06:04:41 +04:00
CodeMirror.commands.autocompleteAfterDot = function (cm) {
setTimeout(function () {
2014-08-27 14:10:12 +04:00
if (!cm.state.completionActive) {
cm.showHint({hint: CodeMirror.hint.go, completeSingle: false});
}
}, 50);
return CodeMirror.Pass;
};
2014-09-17 06:04:41 +04:00
CodeMirror.commands.autocompleteAnyWord = function (cm) {
2014-08-27 14:10:12 +04:00
cm.showHint({hint: CodeMirror.hint.auto});
};
2014-09-02 20:05:05 +04:00
2014-09-17 06:04:41 +04:00
CodeMirror.commands.gotoLine = function (cm) {
2014-09-24 07:35:03 +04:00
$("#dialogGoLinePrompt").dialog("open");
2014-08-31 18:45:19 +04:00
};
2014-09-02 20:05:05 +04:00
2014-09-17 06:04:41 +04:00
CodeMirror.commands.doNothing = function (cm) {
2014-09-02 20:05:05 +04:00
};
2014-09-11 20:22:24 +04:00
2014-09-17 06:04:41 +04:00
CodeMirror.commands.jumpToDecl = function (cm) {
2014-09-11 20:22:24 +04:00
var cur = wide.curEditor.getCursor();
2014-09-17 06:04:41 +04:00
var request = newWideRequest();
request.path = $(".edit-header .current > span:eq(0)").attr("title");
request.code = wide.curEditor.getValue();
request.cursorLine = cur.line;
request.cursorCh = cur.ch;
2014-09-11 20:22:24 +04:00
$.ajax({
type: 'POST',
2014-09-12 11:55:52 +04:00
url: '/find/decl',
2014-09-11 20:22:24 +04:00
data: JSON.stringify(request),
dataType: "json",
2014-09-17 06:04:41 +04:00
success: function (data) {
2014-09-12 06:10:21 +04:00
if (!data.succ) {
return;
}
2014-09-13 09:05:50 +04:00
var cursorLine = data.cursorLine;
var cursorCh = data.cursorCh;
2014-09-17 06:04:41 +04:00
var request = newWideRequest();
request.path = data.path;
2014-09-12 06:10:21 +04:00
$.ajax({
type: 'POST',
url: '/file',
data: JSON.stringify(request),
dataType: "json",
2014-09-17 06:04:41 +04:00
success: function (data) {
2014-09-12 06:10:21 +04:00
if (!data.succ) {
2014-09-24 07:35:03 +04:00
$("#dialogAlert").dialog("open", data.msg);
2014-09-12 06:10:21 +04:00
return false;
}
2014-09-13 09:05:50 +04:00
var tId = tree.getTIdByPath(data.path);
wide.curNode = tree.fileTree.getNodeByTId(tId);
tree.fileTree.selectNode(wide.curNode);
data.cursorLine = cursorLine;
data.cursorCh = cursorCh;
2014-09-12 06:10:21 +04:00
editors.newEditor(data);
}
});
2014-09-11 20:22:24 +04:00
}
});
};
2014-09-12 11:55:52 +04:00
2014-09-17 06:04:41 +04:00
CodeMirror.commands.findUsages = function (cm) {
2014-09-12 11:55:52 +04:00
var cur = wide.curEditor.getCursor();
2014-09-17 06:04:41 +04:00
var request = newWideRequest();
request.file = wide.curNode.path;
request.code = wide.curEditor.getValue();
request.cursorLine = cur.line;
request.cursorCh = cur.ch;
2014-09-12 11:55:52 +04:00
$.ajax({
type: 'POST',
url: '/find/usages',
data: JSON.stringify(request),
dataType: "json",
2014-09-17 06:04:41 +04:00
success: function (data) {
2014-09-12 11:55:52 +04:00
console.log(data);
if (!data.succ) {
return;
}
}
});
};
2014-08-19 13:07:35 +04:00
},
2014-09-13 09:05:50 +04:00
// 新建一个编辑器 Tab如果已经存在 Tab 则切换到该 Tab.
2014-09-17 06:04:41 +04:00
newEditor: function (data) {
2014-09-24 08:07:20 +04:00
$(".toolbars").show();
2014-08-19 13:07:35 +04:00
var id = wide.curNode.tId;
2014-09-13 09:05:50 +04:00
// 光标位置
var cursor = CodeMirror.Pos(0, 0);
if (data.cursorLine && data.cursorCh) {
cursor = CodeMirror.Pos(data.cursorLine - 1, data.cursorCh - 1);
}
2014-08-19 13:07:35 +04:00
for (var i = 0, ii = editors.data.length; i < ii; i++) {
if (editors.data[i].id === id) {
2014-08-29 13:24:08 +04:00
editors.tabs.setCurrent(id);
2014-09-03 13:23:42 +04:00
wide.curEditor = editors.data[i].editor;
2014-09-13 09:05:50 +04:00
wide.curEditor.setCursor(cursor);
wide.curEditor.focus();
2014-08-19 13:07:35 +04:00
return false;
}
}
2014-08-29 13:24:08 +04:00
editors.tabs.add({
id: id,
2014-09-12 11:55:52 +04:00
title: '<span title="' + wide.curNode.path + '"><span class="'
2014-09-12 08:01:45 +04:00
+ wide.curNode.iconSkin + 'ico"></span>' + wide.curNode.name + '</span>',
2014-08-29 13:24:08 +04:00
content: '<textarea id="editor' + id + '"></textarea>'
});
2014-09-06 18:18:53 +04:00
2014-09-13 09:05:50 +04:00
var rulers = [];
2014-09-06 17:24:28 +04:00
rulers.push({color: "#ccc", column: 120, lineStyle: "dashed"});
2014-08-18 17:45:43 +04:00
2014-08-19 13:07:35 +04:00
var editor = CodeMirror.fromTextArea(document.getElementById("editor" + id), {
lineNumbers: true,
2014-09-13 09:05:50 +04:00
autofocus: true,
2014-09-06 18:23:46 +04:00
autoCloseBrackets: true,
2014-09-11 10:13:09 +04:00
matchBrackets: true,
2014-09-06 17:24:28 +04:00
highlightSelectionMatches: {showToken: /\w/},
rulers: rulers,
2014-09-02 20:05:05 +04:00
styleActiveLine: true,
2014-08-19 13:07:35 +04:00
theme: 'lesser-dark',
2014-08-27 14:10:12 +04:00
indentUnit: 4,
2014-09-06 19:42:29 +04:00
foldGutter: true,
2014-08-19 13:07:35 +04:00
extraKeys: {
2014-08-22 08:29:54 +04:00
"Ctrl-\\": "autocompleteAnyWord",
2014-08-30 08:54:46 +04:00
".": "autocompleteAfterDot",
2014-09-17 06:04:41 +04:00
"Esc": function (cm) {
2014-08-30 08:54:46 +04:00
if (cm.getOption("fullScreen")) {
cm.setOption("fullScreen", false);
}
},
2014-09-17 06:04:41 +04:00
"F11": function (cm) {
2014-08-30 08:54:46 +04:00
cm.setOption("fullScreen", !cm.getOption("fullScreen"));
2014-08-31 17:49:27 +04:00
},
2014-09-02 20:05:05 +04:00
"Ctrl-G": "gotoLine",
"Ctrl-E": "deleteLine",
2014-09-11 20:22:24 +04:00
"Ctrl-D": "doNothing", // 取消默认的 deleteLine
2014-09-12 11:55:52 +04:00
"Ctrl-B": "jumpToDecl",
"Ctrl-S": function () {
2014-09-17 06:04:41 +04:00
wide.saveFile();
},
2014-09-20 07:54:33 +04:00
"Shift-Ctrl-S": function () {
wide.saveAllFiles();
},
2014-09-16 18:39:22 +04:00
"Shift-Alt-F": function () {
2014-09-17 06:04:41 +04:00
wide.fmt();
},
2014-09-12 11:55:52 +04:00
"Alt-F7": "findUsages"
2014-08-19 13:07:35 +04:00
}
});
2014-09-11 11:15:29 +04:00
2014-09-17 06:04:41 +04:00
editor.on('cursorActivity', function (cm) {
2014-09-11 11:15:29 +04:00
var cursor = cm.getCursor();
$("#footer-cursor").text('| ' + (cursor.line + 1) + ':' + (cursor.ch + 1) + ' |');
// TODO: 关闭 tab 的时候要重置
});
2014-09-02 14:09:01 +04:00
editor.setSize('100%', $(".edit-panel").height() - $(".edit-header").height());
2014-08-19 13:07:35 +04:00
editor.setValue(data.content);
editor.setOption("mode", data.mode);
2014-09-06 18:33:09 +04:00
2014-09-13 09:05:50 +04:00
editor.setCursor(cursor);
2014-09-06 19:42:29 +04:00
editor.setOption("gutters", ["CodeMirror-lint-markers", "CodeMirror-foldgutter"]);
2014-09-06 18:33:09 +04:00
2014-09-09 09:53:25 +04:00
if ("text/x-go" === data.mode || "application/json" === data.mode) {
2014-09-06 18:18:53 +04:00
editor.setOption("lint", true);
}
2014-09-11 11:15:29 +04:00
2014-09-06 19:42:29 +04:00
if ("application/xml" === data.mode || "text/html" === data.mode) {
editor.setOption("autoCloseTags", true);
}
2014-08-18 17:45:43 +04:00
2014-08-19 13:07:35 +04:00
wide.curEditor = editor;
editors.data.push({
"editor": editor,
"id": id
});
}
};
2014-08-18 17:45:43 +04:00
2014-08-19 13:07:35 +04:00
editors.init();