wide/static/js/editors.js

826 lines
32 KiB
JavaScript
Raw Normal View History

2014-11-12 18:13:14 +03:00
/*
* Copyright (c) 2014, B3log
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
2014-09-25 05:46:24 +04:00
var editors = {
data: [],
tabs: {},
close: function () {
$(".edit-panel .tabs > div[data-index=" + $(".edit-panel .frame").data("index") + "]").find(".ico-close").click();
},
closeOther: function () {
var currentIndex = $(".edit-panel .frame").data("index");
// 设置全部关闭标识
var removeData = [];
$(".edit-panel .tabs > div").each(function (i) {
if (currentIndex !== $(this).data("index")) {
removeData.push($(this).data("index"));
}
});
2014-11-06 09:41:46 +03:00
if (removeData.length === 0) {
return false;
}
var firstIndex = removeData.splice(0, 1);
$("#dialogCloseEditor").data("removeData", removeData);
// 开始关闭
$(".edit-panel .tabs > div[data-index=" + firstIndex + "]").find(".ico-close").click();
},
2014-11-01 16:28:18 +03:00
_removeAllMarker: function () {
var removeData = $("#dialogCloseEditor").data("removeData");
if (removeData && removeData.length > 0) {
2014-11-01 16:49:41 +03:00
var removeIndex = removeData.splice(0, 1);
2014-11-01 16:28:18 +03:00
$("#dialogCloseEditor").data("removeData", removeData);
2014-11-01 16:49:41 +03:00
$(".edit-panel .tabs > div[data-index=" + removeIndex + "] .ico-close").click();
2014-11-01 16:28:18 +03:00
}
},
_initClose: function () {
// 关闭、关闭其他、关闭所有
$(".edit-panel").on("mousedown", '.tabs > div', function (event) {
event.stopPropagation();
if (event.button === 0) { // 左键
$(".edit-panel .frame").hide();
return false;
}
// event.button === 2 右键
var left = event.screenX;
if ($(".side").css("left") === "auto" || $(".side").css("left") === "0px") {
left = event.screenX - $(".side").width();
}
$(".edit-panel .frame").show().css({
"left": left + "px",
"top": "21px"
}).data('index', $(this).data("index"));
return false;
});
},
2014-09-25 05:46:24 +04:00
init: function () {
2014-11-01 07:05:52 +03:00
$("#dialogCloseEditor").dialog({
"modal": true,
2014-11-01 07:36:42 +03:00
"height": 66,
2014-11-01 07:05:52 +03:00
"width": 260,
"title": config.label.tip,
"hideFooter": true,
2014-11-01 07:36:42 +03:00
"afterOpen": function (fileName) {
2014-11-01 16:28:18 +03:00
$("#dialogCloseEditor > div:eq(0)").html(config.label.file
2014-11-01 07:36:42 +03:00
+ ' <b>' + fileName + '</b>. ' + config.label.confirm_save + '?');
$("#dialogCloseEditor button:eq(0)").focus();
},
2014-11-01 07:05:52 +03:00
"afterInit": function () {
$("#dialogCloseEditor button.save").click(function () {
var i = $("#dialogCloseEditor").data("index");
wide.fmt(tree.fileTree.getNodeByTId(editors.data[i].id).path, editors.data[i].editor);
editors.tabs.del(editors.data[i].id);
$("#dialogCloseEditor").dialog("close");
2014-11-01 16:28:18 +03:00
editors._removeAllMarker();
2014-11-01 07:05:52 +03:00
});
$("#dialogCloseEditor button.discard").click(function () {
$("#dialogCloseEditor").dialog("close");
2014-11-01 16:28:18 +03:00
editors._removeAllMarker();
2014-11-01 07:05:52 +03:00
});
$("#dialogCloseEditor button.cancel").click(function () {
var i = $("#dialogCloseEditor").data("index");
editors.tabs.del(editors.data[i].id);
$("#dialogCloseEditor").dialog("close");
2014-11-01 16:28:18 +03:00
editors._removeAllMarker();
2014-11-01 07:05:52 +03:00
});
}
});
2014-09-25 05:46:24 +04:00
editors.tabs = new Tabs({
id: ".edit-panel",
clickAfter: function (id) {
2014-10-17 10:47:29 +04:00
if (id === 'startPage') {
return false;
}
2014-09-25 05:46:24 +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;
}
}
wide.curEditor.focus();
},
2014-11-01 07:05:52 +03:00
removeBefore: function (id) {
2014-10-27 18:02:15 +03:00
if (id === 'startPage') { // 当前关闭的 tab 是起始页
2014-11-01 16:49:41 +03:00
editors._removeAllMarker();
2014-11-01 16:28:18 +03:00
return true;
2014-10-17 10:47:29 +04:00
}
// 移除编辑器
2014-09-25 05:46:24 +04:00
for (var i = 0, ii = editors.data.length; i < ii; i++) {
if (editors.data[i].id === id) {
2014-11-01 07:05:52 +03:00
if (editors.data[i].editor.doc.isClean()) {
2014-11-01 16:49:41 +03:00
editors._removeAllMarker();
2014-11-01 07:05:52 +03:00
return true;
} else {
2014-11-01 07:36:42 +03:00
$("#dialogCloseEditor").dialog("open", $(".edit-panel .tabs > div[data-index="
+ editors.data[i].id + "] > span:eq(0)").text());
2014-11-01 07:05:52 +03:00
$("#dialogCloseEditor").data("index", i);
return false;
}
break;
}
}
},
removeAfter: function (id, nextId) {
2014-11-01 16:28:18 +03:00
if ($(".edit-panel .tabs > div").length === 0) {
// 全部 tab 都关闭时才 disables 菜单中“全部关闭”的按钮
menu.disabled(['close-all']);
}
2014-11-01 07:05:52 +03:00
if (id === 'startPage') { // 当前关闭的 tab 是起始页
return false;
}
2014-11-01 07:05:52 +03:00
// 移除编辑器
for (var i = 0, ii = editors.data.length; i < ii; i++) {
if (editors.data[i].id === id) {
2014-10-13 13:01:44 +04:00
editors.data.splice(i, 1);
2014-09-25 05:46:24 +04:00
break;
}
}
2014-10-27 18:02:15 +03:00
if (editors.data.length === 0) { // 起始页可能存在,所以用编辑器数据判断
2014-11-01 16:28:18 +03:00
menu.disabled(['save-all', 'build', 'run', 'go-test', 'go-get', 'go-install']);
2014-10-27 18:02:15 +03:00
$(".toolbars").hide();
}
2014-09-25 05:46:24 +04:00
if (!nextId) {
// 不存在打开的编辑器
// remove selected tree node
tree.fileTree.cancelSelectedNode();
wide.curNode = undefined;
wide.curEditor = undefined;
return false;
}
if (nextId === editors.tabs.getCurrentId()) {
// 关闭的不是当前编辑器
2014-09-25 05:46:24 +04:00
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-26 11:39:13 +04:00
$(".edit-panel .tabs").on("dblclick", function () {
if ($(".toolbars .ico-max").length === 1) {
windows.maxEditor();
} else {
windows.restoreEditor();
}
2014-09-25 05:46:24 +04:00
});
2014-10-17 10:47:29 +04:00
this._initCodeMirrorHotKeys();
2014-11-01 07:05:52 +03:00
this.openStartPage();
this._initClose();
2014-10-17 10:47:29 +04:00
},
2014-10-20 13:32:06 +04:00
openStartPage: function () {
2014-10-21 12:46:09 +04:00
var dateFormat = function (time, fmt) {
var date = new Date(time);
var dateObj = {
"M+": date.getMonth() + 1, //月份
"d+": date.getDate(), //日
"h+": date.getHours(), //小时
"m+": date.getMinutes(), //分
"s+": date.getSeconds(), //秒
"q+": Math.floor((date.getMonth() + 3) / 3), //季度
"S": date.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt))
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in dateObj)
if (new RegExp("(" + k + ")").test(fmt)) {
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1)
? (dateObj[k]) : (("00" + dateObj[k]).substr(("" + dateObj[k]).length)));
}
return fmt;
};
2014-10-17 10:47:29 +04:00
editors.tabs.add({
id: "startPage",
2014-10-21 18:48:33 +04:00
title: '<span title="' + config.label.start_page + '">' + config.label.start_page + '</span>',
2014-10-20 13:32:06 +04:00
content: '<div id="startPage"></div>',
after: function () {
2014-11-02 10:44:24 +03:00
$("#startPage").load('/start?sid=' + config.wideSessionId);
2014-10-20 13:32:06 +04:00
$.ajax({
url: "http://symphony.b3log.org/apis/articles?tags=wide,golang&p=1&size=30",
type: "GET",
dataType: "jsonp",
jsonp: "callback",
success: function (data, textStatus) {
var articles = data.articles;
if (0 === articles.length) {
return;
}
// 按 size = 30 取,但只保留最多 10 篇
var length = articles.length;
if (length > 10) {
length = 10;
}
2014-10-21 13:29:11 +04:00
var listHTML = "<ul><li class='title'>" + config.label.community + "</li>";
2014-10-20 13:32:06 +04:00
for (var i = 0; i < length; i++) {
var article = articles[i];
2014-10-21 12:46:09 +04:00
listHTML += "<li>"
+ "<a target='_blank' href='http://symphony.b3log.org"
+ article.articlePermalink + "'>"
+ article.articleTitle + "</a>&nbsp; <span class='date'>"
+ dateFormat(article.articleCreateTime, 'yyyy-MM-dd hh:mm');
2014-11-01 07:05:52 +03:00
+"</span></li>";
2014-10-20 13:32:06 +04:00
}
2014-10-21 12:46:09 +04:00
$("#startPage .news").html(listHTML + "</ul>");
2014-10-20 13:32:06 +04:00
}
});
2014-10-19 14:41:01 +04:00
}
2014-10-17 10:47:29 +04:00
});
2014-09-25 05:46:24 +04:00
},
2014-09-26 11:39:13 +04:00
getCurrentId: function () {
2014-10-17 10:47:29 +04:00
var currentId = editors.tabs.getCurrentId();
if (currentId === 'startPage') {
currentId = null;
}
return currentId;
2014-09-26 11:39:13 +04:00
},
getCurrentPath: function () {
2014-10-17 10:47:29 +04:00
var currentPath = $(".edit-panel .tabs .current span:eq(0)").attr("title");
2014-10-21 18:48:33 +04:00
if (currentPath === config.label.start_page) {
2014-10-17 10:47:29 +04:00
currentPath = null;
}
return currentPath;
2014-09-25 05:46:24 +04:00
},
2014-10-17 10:47:29 +04:00
_initCodeMirrorHotKeys: function () {
2014-09-25 05:46:24 +04:00
CodeMirror.registerHelper("hint", "go", function (editor) {
var word = /[\w$]+/;
var cur = editor.getCursor(), curLine = editor.getLine(cur.line);
var start = cur.ch, end = start;
while (end < curLine.length && word.test(curLine.charAt(end))) {
++end;
}
while (start && word.test(curLine.charAt(start - 1))) {
--start;
}
var request = newWideRequest();
2014-09-25 12:40:05 +04:00
request.path = $(".edit-panel .tabs .current > span:eq(0)").attr("title");
2014-09-25 05:46:24 +04:00
request.code = editor.getValue();
request.cursorLine = cur.line;
request.cursorCh = cur.ch;
var autocompleteHints = [];
$.ajax({
async: false, // 同步执行
type: 'POST',
url: '/autocomplete',
data: JSON.stringify(request),
dataType: "json",
success: function (data) {
var autocompleteArray = data[1];
if (autocompleteArray) {
for (var i = 0; i < autocompleteArray.length; i++) {
2014-10-09 19:04:02 +04:00
var displayText = '';
2014-10-10 07:18:52 +04:00
switch (autocompleteArray[i].class) {
case "type":
case "const":
case "var":
case "package":
displayText = '<span class="fn-clear">'// + autocompleteArray[i].class
+ '<b class="fn-left">' + autocompleteArray[i].name + '</b> '
+ autocompleteArray[i].type + '</span>';
break;
case "func":
displayText = '<span>'// + autocompleteArray[i].class
+ '<b>' + autocompleteArray[i].name + '</b>'
+ autocompleteArray[i].type.substring(4) + '</span>';
break;
default:
console.warn("Can't handle autocomplete [" + autocompleteArray[i].class + "]");
2014-10-10 14:04:03 +04:00
2014-10-10 07:18:52 +04:00
break;
2014-10-09 19:04:02 +04:00
}
2014-10-10 07:18:52 +04:00
2014-10-09 13:14:15 +04:00
autocompleteHints[i] = {
2014-10-09 19:04:02 +04:00
displayText: displayText,
2014-10-09 13:14:15 +04:00
text: autocompleteArray[i].name
};
2014-09-25 05:46:24 +04:00
}
}
2014-10-31 10:54:54 +03:00
// 清除未保存状态
2014-10-31 10:54:54 +03:00
editor.doc.markClean();
$(".edit-panel .tabs > div.current > span").removeClass("changed");
2014-09-25 05:46:24 +04:00
}
});
return {list: autocompleteHints, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end)};
});
CodeMirror.commands.autocompleteAfterDot = function (cm) {
setTimeout(function () {
if (!cm.state.completionActive) {
cm.showHint({hint: CodeMirror.hint.go, completeSingle: false});
}
}, 50);
return CodeMirror.Pass;
};
CodeMirror.commands.autocompleteAnyWord = function (cm) {
cm.showHint({hint: CodeMirror.hint.auto});
};
CodeMirror.commands.gotoLine = function (cm) {
$("#dialogGoLinePrompt").dialog("open");
};
2014-10-10 07:27:17 +04:00
// 用于覆盖 cm 默认绑定的某些快捷键功能.
2014-09-25 05:46:24 +04:00
CodeMirror.commands.doNothing = function (cm) {
};
2014-10-10 14:04:03 +04:00
2014-10-10 07:18:52 +04:00
CodeMirror.commands.exprInfo = function (cm) {
var cur = wide.curEditor.getCursor();
var request = newWideRequest();
request.path = $(".edit-panel .tabs .current > span:eq(0)").attr("title");
request.code = wide.curEditor.getValue();
request.cursorLine = cur.line;
request.cursorCh = cur.ch;
$.ajax({
type: 'POST',
url: '/exprinfo',
data: JSON.stringify(request),
dataType: "json",
success: function (data) {
if (!data.succ) {
return;
}
2014-10-10 14:04:03 +04:00
var position = wide.curEditor.cursorCoords();
$("body").append('<div style="top:'
+ (position.top + 15) + 'px;left:' + position.left
+ 'px" class="edit-exprinfo">' + data.info + '</div>');
2014-10-10 07:18:52 +04:00
}
});
};
2014-09-25 05:46:24 +04:00
CodeMirror.commands.jumpToDecl = function (cm) {
var cur = wide.curEditor.getCursor();
var request = newWideRequest();
2014-09-25 12:40:05 +04:00
request.path = $(".edit-panel .tabs .current > span:eq(0)").attr("title");
2014-09-25 05:46:24 +04:00
request.code = wide.curEditor.getValue();
request.cursorLine = cur.line;
request.cursorCh = cur.ch;
$.ajax({
type: 'POST',
url: '/find/decl',
data: JSON.stringify(request),
dataType: "json",
success: function (data) {
if (!data.succ) {
return;
}
var cursorLine = data.cursorLine;
var cursorCh = data.cursorCh;
var request = newWideRequest();
request.path = data.path;
$.ajax({
type: 'POST',
url: '/file',
data: JSON.stringify(request),
dataType: "json",
success: function (data) {
if (!data.succ) {
$("#dialogAlert").dialog("open", data.msg);
return false;
}
var tId = tree.getTIdByPath(data.path);
wide.curNode = tree.fileTree.getNodeByTId(tId);
tree.fileTree.selectNode(wide.curNode);
data.cursorLine = cursorLine;
data.cursorCh = cursorCh;
editors.newEditor(data);
}
});
}
});
};
CodeMirror.commands.findUsages = function (cm) {
var cur = wide.curEditor.getCursor();
var request = newWideRequest();
2014-10-10 07:18:52 +04:00
request.path = $(".edit-panel .tabs .current > span:eq(0)").attr("title");
2014-09-25 05:46:24 +04:00
request.code = wide.curEditor.getValue();
request.cursorLine = cur.line;
request.cursorCh = cur.ch;
$.ajax({
type: 'POST',
url: '/find/usages',
data: JSON.stringify(request),
dataType: "json",
success: function (data) {
if (!data.succ) {
return;
}
2014-10-12 18:00:26 +04:00
editors.appendSearch(data.founds, 'usages', '');
2014-09-25 05:46:24 +04:00
}
});
};
},
2014-10-12 18:00:26 +04:00
appendSearch: function (data, type, key) {
var searcHTML = '<ul>';
for (var i = 0, ii = data.length; i < ii; i++) {
var contents = data[i].contents[0],
index = contents.indexOf(key);
contents = contents.substring(0, index)
+ '<b>' + key + '</b>'
+ contents.substring(index + key.length);
searcHTML += '<li title="' + data[i].path + '">'
+ contents + "&nbsp;&nbsp;&nbsp;&nbsp;<span class='path'>" + data[i].path
+ '<i class="position" data-line="'
+ data[i].line + '" data-ch="' + data[i].ch + '"> (' + data[i].line + ':'
+ data[i].ch + ')</i></span></li>';
}
searcHTML += '</ul>';
var $search = $('.bottom-window-group .search'),
2014-10-23 06:05:05 +04:00
title = config.label.find_usages;
2014-10-12 18:00:26 +04:00
if (type === "founds") {
title = config.label.search_text;
}
if ($search.find("ul").length === 0) {
2014-11-06 06:58:55 +03:00
bottomGroup.searchTab = new Tabs({
2014-10-12 09:40:07 +04:00
id: ".bottom-window-group .search",
removeAfter: function (id, prevId) {
2014-10-12 18:00:26 +04:00
if ($search.find("ul").length === 1) {
$search.find(".tabs").hide();
2014-10-12 09:40:07 +04:00
}
}
});
2014-10-12 18:00:26 +04:00
$search.on("click", "li", function () {
$search.find("li").removeClass("selected");
$(this).addClass("selected");
});
$search.on("dblclick", "li", function () {
var $it = $(this),
tId = tree.getTIdByPath($it.attr("title"));
tree.openFile(tree.fileTree.getNodeByTId(tId));
tree.fileTree.selectNode(wide.curNode);
2014-11-05 08:49:11 +03:00
var line = $it.find(".position").data("line") - 1;
var cursor = CodeMirror.Pos(line, $it.find(".position").data("ch") - 1);
2014-11-05 08:49:11 +03:00
var editor = wide.curEditor;
editor.setCursor(cursor);
var half = Math.floor(editor.getScrollInfo().clientHeight / editor.defaultTextHeight() / 2);
var cursorCoords = editor.cursorCoords({line: cursor.line - half, ch: 0}, "local");
editor.scrollTo(0, cursorCoords.top);
2014-11-05 08:49:11 +03:00
2014-10-12 18:00:26 +04:00
wide.curEditor.focus();
});
$search.find(".tabs-panel > div").append(searcHTML);
$search.find(".tabs .first").text(title);
} else {
$search.find(".tabs").show();
2014-11-06 06:58:55 +03:00
bottomGroup.searchTab.add({
2014-10-12 18:00:26 +04:00
"id": "search" + (new Date()).getTime(),
"title": title,
"content": searcHTML
2014-10-12 09:40:07 +04:00
});
}
// focus
2014-11-06 06:58:55 +03:00
bottomGroup.tabs.setCurrent("search");
2014-10-12 09:40:07 +04:00
windows.flowBottom();
$(".bottom-window-group .search").focus();
},
2014-09-25 05:46:24 +04:00
// 新建一个编辑器 Tab如果已经存在 Tab 则切换到该 Tab.
newEditor: function (data) {
$(".toolbars").show();
var id = wide.curNode.tId;
var cursor = CodeMirror.Pos(0, 0);
if (data.cursorLine && data.cursorCh) {
cursor = CodeMirror.Pos(data.cursorLine - 1, data.cursorCh - 1);
}
for (var i = 0, ii = editors.data.length; i < ii; i++) {
if (editors.data[i].id === id) {
editors.tabs.setCurrent(id);
wide.curEditor = editors.data[i].editor;
2014-11-04 19:27:43 +03:00
var editor = wide.curEditor;
editor.setCursor(cursor);
var half = Math.floor(editor.getScrollInfo().clientHeight / editor.defaultTextHeight() / 2);
var cursorCoords = editor.cursorCoords({line: cursor.line - half, ch: 0}, "local");
editor.scrollTo(0, cursorCoords.top);
2014-11-04 19:27:43 +03:00
editor.focus();
2014-09-25 05:46:24 +04:00
return false;
}
}
editors.tabs.add({
id: id,
title: '<span title="' + wide.curNode.path + '"><span class="'
+ wide.curNode.iconSkin + 'ico"></span>' + wide.curNode.name + '</span>',
content: '<textarea id="editor' + id + '"></textarea>'
});
2014-10-17 10:47:29 +04:00
2014-10-27 18:02:15 +03:00
menu.undisabled(['save-all', 'close-all', 'build', 'run', 'go-test', 'go-get', 'go-install']);
2014-09-25 05:46:24 +04:00
var rulers = [];
rulers.push({color: "#ccc", column: 120, lineStyle: "dashed"});
2014-10-27 09:42:33 +03:00
var textArea = document.getElementById("editor" + id);
textArea.value = data.content;
var editor = CodeMirror.fromTextArea(textArea, {
2014-09-25 05:46:24 +04:00
lineNumbers: true,
autofocus: true,
autoCloseBrackets: true,
matchBrackets: true,
highlightSelectionMatches: {showToken: /\w/},
rulers: rulers,
styleActiveLine: true,
2014-10-21 12:48:45 +04:00
theme: 'wide',
2014-09-25 05:46:24 +04:00
indentUnit: 4,
foldGutter: true,
2014-11-02 18:04:43 +03:00
path: data.path,
2014-09-25 05:46:24 +04:00
extraKeys: {
"Ctrl-\\": "autocompleteAnyWord",
".": "autocompleteAfterDot",
2014-10-10 07:18:52 +04:00
"Ctrl-I": "exprInfo",
2014-10-23 06:05:05 +04:00
"Ctrl-L": "gotoLine",
2014-09-25 05:46:24 +04:00
"Ctrl-E": "deleteLine",
"Ctrl-D": "doNothing", // 取消默认的 deleteLine
"Ctrl-B": "jumpToDecl",
"Ctrl-S": function () {
wide.saveFile();
},
"Shift-Ctrl-S": function () {
wide.saveAllFiles();
},
"Shift-Alt-F": function () {
2014-10-17 10:47:29 +04:00
var currentPath = editors.getCurrentPath();
if (!currentPath) {
return false;
}
wide.fmt(currentPath, wide.curEditor);
2014-09-25 05:46:24 +04:00
},
2014-10-22 09:38:52 +04:00
"Alt-F7": "findUsages",
"Shift-Alt-Enter": function () {
if (windows.isMaxEditor) {
windows.restoreEditor();
} else {
windows.maxEditor();
}
2014-11-05 06:36:13 +03:00
},
"Shift-Ctrl-Up": function (cm) {
2014-11-08 09:28:41 +03:00
var content = '',
2014-11-09 14:26:47 +03:00
selectoion = cm.listSelections()[0];
2014-11-08 09:28:41 +03:00
2014-11-09 14:26:47 +03:00
var from = selectoion.anchor,
to = selectoion.head;
2014-11-09 18:01:42 +03:00
if (from.line > to.line) {
2014-11-09 14:26:47 +03:00
from = selectoion.head;
to = selectoion.anchor;
2014-11-08 09:28:41 +03:00
}
2014-11-05 06:36:13 +03:00
2014-11-09 14:26:47 +03:00
for (var i = from.line, max = to.line; i <= max; i++) {
2014-11-10 12:19:30 +03:00
if (to.ch !== 0 || i !== max) { // 下一行选中为0时不应添加内容
content += '\n' + cm.getLine(i);
}
2014-11-05 06:36:13 +03:00
}
2014-11-10 12:19:30 +03:00
// 下一行选中为0时应添加到上一行末
var replaceToLine = to.line;
if (to.ch === 0) {
replaceToLine = to.line - 1;
}
cm.replaceRange(content, CodeMirror.Pos(replaceToLine));
2014-11-09 14:26:47 +03:00
2014-11-10 13:03:26 +03:00
cm.setSelection(CodeMirror.Pos(from.line, from.ch),
CodeMirror.Pos(to.line, to.ch));
2014-11-05 06:36:13 +03:00
},
"Shift-Ctrl-Down": function (cm) {
2014-11-08 09:28:41 +03:00
var content = '',
2014-11-09 14:26:47 +03:00
selectoion = cm.listSelections()[0];
2014-11-08 09:28:41 +03:00
2014-11-09 14:26:47 +03:00
var from = selectoion.anchor,
to = selectoion.head;
2014-11-09 18:01:42 +03:00
if (from.line > to.line) {
2014-11-09 14:26:47 +03:00
from = selectoion.head;
to = selectoion.anchor;
2014-11-08 09:28:41 +03:00
}
2014-11-09 14:26:47 +03:00
for (var i = from.line, max = to.line; i <= max; i++) {
2014-11-10 12:19:30 +03:00
if (to.ch !== 0 || i !== max) { // 下一行选中为0时不应添加内容
content += '\n' + cm.getLine(i);
}
2014-11-08 09:28:41 +03:00
}
2014-11-10 12:19:30 +03:00
// 下一行选中为0时应添加到上一行末
var replaceToLine = to.line;
if (to.ch === 0) {
replaceToLine = to.line - 1;
}
cm.replaceRange(content, CodeMirror.Pos(replaceToLine));
2014-11-05 06:36:13 +03:00
2014-11-10 12:19:30 +03:00
var offset = replaceToLine - from.line + 1;
cm.setSelection(CodeMirror.Pos(from.line + offset, from.ch),
CodeMirror.Pos(to.line + offset, to.ch));
2014-11-09 18:01:42 +03:00
},
"Shift-Alt-Up": function (cm) {
var selectoion = cm.listSelections()[0];
var from = selectoion.anchor,
to = selectoion.head;
if (from.line > to.line) {
from = selectoion.head;
to = selectoion.anchor;
}
if (from.line === 0) {
return false;
}
2014-11-10 13:03:26 +03:00
// 下一行选中为0时应添加到上一行末
var replaceToLine = to.line;
if (to.ch === 0) {
replaceToLine = to.line - 1;
}
cm.replaceRange('\n' + cm.getLine(from.line - 1), CodeMirror.Pos(replaceToLine));
2014-11-09 18:01:42 +03:00
if (from.line === 1) {
2014-11-10 13:03:26 +03:00
// 移除第一行的换行
2014-11-09 18:01:42 +03:00
cm.replaceRange('', CodeMirror.Pos(0, 0),
CodeMirror.Pos(1, 0));
} else {
cm.replaceRange('', CodeMirror.Pos(from.line - 2, cm.getLine(from.line - 2).length),
CodeMirror.Pos(from.line - 1, cm.getLine(from.line - 1).length));
}
cm.setSelection(CodeMirror.Pos(from.line - 1, from.ch),
CodeMirror.Pos(to.line - 1, to.ch));
},
"Shift-Alt-Down": function (cm) {
var selectoion = cm.listSelections()[0];
var from = selectoion.anchor,
to = selectoion.head;
if (from.line > to.line) {
from = selectoion.head;
to = selectoion.anchor;
}
if (to.line === cm.lastLine()) {
return false;
}
2014-11-10 13:03:26 +03:00
// 下一行选中为0时应添加到上一行末
var replaceToLine = to.line;
if (to.ch === 0) {
replaceToLine = to.line - 1;
}
// 把选中的下一行添加到选中区域的上一行
if (from.line === 0) {
cm.replaceRange(cm.getLine(replaceToLine + 1) + '\n', CodeMirror.Pos(0, 0));
} else {
cm.replaceRange('\n' + cm.getLine(replaceToLine + 1), CodeMirror.Pos(from.line - 1));
}
// 删除选中的下一行
cm.replaceRange('', CodeMirror.Pos(replaceToLine + 1, cm.getLine(replaceToLine + 1).length),
CodeMirror.Pos(replaceToLine + 2, cm.getLine(replaceToLine + 2).length));
2014-11-09 18:01:42 +03:00
2014-11-10 13:03:26 +03:00
cm.setSelection(CodeMirror.Pos(from.line + 1, from.ch),
CodeMirror.Pos(to.line + 1, to.ch));
2014-10-31 10:54:54 +03:00
}
2014-09-25 05:46:24 +04:00
}
});
editor.on('cursorActivity', function (cm) {
2014-10-10 14:04:03 +04:00
$(".edit-exprinfo").remove();
2014-09-25 05:46:24 +04:00
var cursor = cm.getCursor();
2014-09-25 12:03:14 +04:00
$(".footer .cursor").text('| ' + (cursor.line + 1) + ':' + (cursor.ch + 1) + ' |');
2014-09-25 05:46:24 +04:00
// TODO: 关闭 tab 的时候要重置
});
2014-09-26 11:39:13 +04:00
editor.on('focus', function (cm) {
2014-09-26 12:41:25 +04:00
windows.clearFloat();
2014-09-26 11:39:13 +04:00
});
2014-10-10 14:04:03 +04:00
editor.on('blur', function (cm) {
$(".edit-exprinfo").remove();
});
2014-10-31 10:54:54 +03:00
editor.on('changes', function (cm) {
if (cm.doc.isClean()) {
// 没有修改过
2014-11-02 18:04:43 +03:00
$(".edit-panel .tabs > div").each(function () {
var $span = $(this).find("span:eq(0)");
if ($span.attr("title") === cm.options.path) {
$span.removeClass("changed");
}
});
2014-10-31 10:54:54 +03:00
} else {
// 修改过
2014-11-02 18:04:43 +03:00
$(".edit-panel .tabs > div").each(function () {
var $span = $(this).find("span:eq(0)");
if ($span.attr("title") === cm.options.path) {
$span.addClass("changed");
}
});
2014-10-31 10:54:54 +03:00
}
});
2014-09-25 11:56:26 +04:00
editor.setSize('100%', $(".edit-panel").height() - $(".edit-panel .tabs").height());
2014-10-10 14:04:03 +04:00
editor.setOption("mode", data.mode);
2014-09-25 05:46:24 +04:00
editor.setOption("gutters", ["CodeMirror-lint-markers", "CodeMirror-foldgutter"]);
if ("text/x-go" === data.mode || "application/json" === data.mode) {
editor.setOption("lint", true);
}
if ("application/xml" === data.mode || "text/html" === data.mode) {
editor.setOption("autoCloseTags", true);
}
2014-10-10 14:04:03 +04:00
2014-10-10 07:27:17 +04:00
editor.setCursor(cursor);
2014-09-25 05:46:24 +04:00
2014-11-04 19:27:43 +03:00
var half = Math.floor(editor.getScrollInfo().clientHeight / editor.defaultTextHeight() / 2);
var cursorCoords = editor.cursorCoords({line: cursor.line - half, ch: 0}, "local");
editor.scrollTo(0, cursorCoords.top);
2014-11-04 19:27:43 +03:00
2014-09-25 05:46:24 +04:00
wide.curEditor = editor;
editors.data.push({
"editor": editor,
"id": id
});
}
2014-09-26 11:39:13 +04:00
};