hotkeys refactor & files up, down, right, left
This commit is contained in:
parent
e814ee39d7
commit
db0c3992d0
|
@ -266,6 +266,12 @@ var editors = {
|
||||||
"Ctrl-E": "deleteLine",
|
"Ctrl-E": "deleteLine",
|
||||||
"Ctrl-D": "doNothing", // 取消默认的 deleteLine
|
"Ctrl-D": "doNothing", // 取消默认的 deleteLine
|
||||||
"Ctrl-B": "jumpToDecl",
|
"Ctrl-B": "jumpToDecl",
|
||||||
|
"Ctrl-S": function () {
|
||||||
|
wide.saveFile();
|
||||||
|
},
|
||||||
|
"Alt-Shift-F": function () {
|
||||||
|
wide.fmt();
|
||||||
|
},
|
||||||
"Alt-F7": "findUsages"
|
"Alt-F7": "findUsages"
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,165 @@
|
||||||
|
var hotkeys = {
|
||||||
|
defaultKeyMap: {
|
||||||
|
// Ctrl+1 焦点切换到文件树
|
||||||
|
goFileTree: {
|
||||||
|
ctrlKey: true,
|
||||||
|
altKey: false,
|
||||||
|
shiftKey: false,
|
||||||
|
which: 49
|
||||||
|
},
|
||||||
|
// Ctrl+4 焦点切换到输出窗口
|
||||||
|
goOutPut: {
|
||||||
|
ctrlKey: true,
|
||||||
|
altKey: false,
|
||||||
|
shiftKey: false,
|
||||||
|
which: 52
|
||||||
|
},
|
||||||
|
// F6 构建并运行
|
||||||
|
buildRun: {
|
||||||
|
ctrlKey: false,
|
||||||
|
altKey: false,
|
||||||
|
shiftKey: false,
|
||||||
|
which: 117
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_bindFileTree: function() {
|
||||||
|
// TODO: 滚动处理
|
||||||
|
$("#files").keydown(function(event) {
|
||||||
|
switch (event.which) {
|
||||||
|
case 13: // 回车
|
||||||
|
if (!wide.curNode) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wide.curNode.iconSkin === "ico-ztree-dir ") { // 选中节点是目录
|
||||||
|
// 不做任何处理
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 模拟点击:打开文件
|
||||||
|
tree._onClick(wide.curNode);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 38: // 上
|
||||||
|
var node = {};
|
||||||
|
|
||||||
|
if (!wide.curNode) { // 没有选中节点时,默认选中第一个
|
||||||
|
node = tree.fileTree.getNodeByTId("files_1");
|
||||||
|
} else {
|
||||||
|
if (wide.curNode && wide.curNode.isFirstNode && wide.curNode.level === 0) {
|
||||||
|
// 当前节点为顶部第一个节点
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
node = wide.curNode.getPreNode();
|
||||||
|
if (wide.curNode.isFirstNode && wide.curNode.getParentNode()) {
|
||||||
|
// 当前节点为第一个节点且有父亲
|
||||||
|
node = wide.curNode.getParentNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
var preNode = wide.curNode.getPreNode();
|
||||||
|
if (preNode && preNode.iconSkin === "ico-ztree-dir "
|
||||||
|
&& preNode.open) {
|
||||||
|
// 当前节点的上一个节点是目录且打开时
|
||||||
|
node = preNode.children[preNode.children.length - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wide.curNode = node;
|
||||||
|
tree.fileTree.selectNode(node);
|
||||||
|
$("#files").focus();
|
||||||
|
break;
|
||||||
|
case 40: // 下
|
||||||
|
var node = {};
|
||||||
|
|
||||||
|
if (!wide.curNode) { // 没有选中节点时,默认选中第一个
|
||||||
|
node = tree.fileTree.getNodeByTId("files_1");
|
||||||
|
} else {
|
||||||
|
if (wide.curNode && wide.curNode.isLastNode && !wide.curNode.open
|
||||||
|
&& wide.curNode.getParentNode().isLastNode) {
|
||||||
|
// 当前节点为最底部的节点
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
node = wide.curNode.getNextNode();
|
||||||
|
if (wide.curNode.iconSkin === "ico-ztree-dir " && wide.curNode.open) {
|
||||||
|
// 当前节点是目录且打开时
|
||||||
|
node = wide.curNode.children[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wide.curNode.isLastNode && wide.curNode.level !== 0
|
||||||
|
&& wide.curNode.getParentNode().getNextNode()) {
|
||||||
|
// 当前节点为最后一个节点,但其父节点还有下一个节点
|
||||||
|
node = wide.curNode.getParentNode().getNextNode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wide.curNode = node;
|
||||||
|
tree.fileTree.selectNode(node);
|
||||||
|
$("#files").focus();
|
||||||
|
break;
|
||||||
|
case 37: // 左
|
||||||
|
if (!wide.curNode) {
|
||||||
|
wide.curNode = tree.fileTree.getNodeByTId("files_1");
|
||||||
|
tree.fileTree.selectNode(wide.curNode);
|
||||||
|
$("#files").focus();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wide.curNode.iconSkin !== "ico-ztree-dir " || !wide.curNode.open) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
tree.fileTree.expandNode(wide.curNode, false, false, true);
|
||||||
|
$("#files").focus();
|
||||||
|
break;
|
||||||
|
case 39: // 右
|
||||||
|
if (!wide.curNode) {
|
||||||
|
wide.curNode = tree.fileTree.getNodeByTId("files_1");
|
||||||
|
tree.fileTree.selectNode(wide.curNode);
|
||||||
|
$("#files").focus();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wide.curNode.iconSkin !== "ico-ztree-dir " || wide.curNode.open) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
tree.fileTree.expandNode(wide.curNode, true, false, true);
|
||||||
|
$("#files").focus();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
init: function() {
|
||||||
|
this._bindFileTree();
|
||||||
|
|
||||||
|
var hotKeys = this.defaultKeyMap;
|
||||||
|
$(document).keydown(function(event) {
|
||||||
|
if (event.ctrlKey === hotKeys.goFileTree.ctrlKey
|
||||||
|
&& event.which === hotKeys.goFileTree.which) { // Ctrl+1 焦点切换到文件树
|
||||||
|
// 有些元素需设置 tabindex 为 -1 时才可以 focus
|
||||||
|
$("#files").focus();
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.ctrlKey === hotKeys.goOutPut.ctrlKey
|
||||||
|
&& event.which === hotKeys.goOutPut.which) { // Ctrl+4 焦点切换到输出窗口
|
||||||
|
$("#output").focus();
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.which === hotKeys.buildRun.which) { // F6 构建并运行
|
||||||
|
wide.run();
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
|
@ -1,9 +1,9 @@
|
||||||
var outputWS = new WebSocket(config.channel.output + '/output/ws');
|
var outputWS = new WebSocket(config.channel.output + '/output/ws');
|
||||||
outputWS.onopen = function () {
|
outputWS.onopen = function() {
|
||||||
console.log('[output onopen] connected');
|
console.log('[output onopen] connected');
|
||||||
};
|
};
|
||||||
|
|
||||||
outputWS.onmessage = function (e) {
|
outputWS.onmessage = function(e) {
|
||||||
console.log('[output onmessage]' + e.data);
|
console.log('[output onmessage]' + e.data);
|
||||||
var data = JSON.parse(e.data);
|
var data = JSON.parse(e.data);
|
||||||
|
|
||||||
|
@ -43,37 +43,37 @@ outputWS.onmessage = function (e) {
|
||||||
url: '/run',
|
url: '/run',
|
||||||
data: JSON.stringify(request),
|
data: JSON.stringify(request),
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
beforeSend: function (data) {
|
beforeSend: function(data) {
|
||||||
$('#output').text('');
|
$('#output').text('');
|
||||||
},
|
},
|
||||||
success: function (data) {
|
success: function(data) {
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
outputWS.onclose = function (e) {
|
outputWS.onclose = function(e) {
|
||||||
console.log('[output onclose] disconnected (' + e.code + ')');
|
console.log('[output onclose] disconnected (' + e.code + ')');
|
||||||
delete outputWS;
|
delete outputWS;
|
||||||
};
|
};
|
||||||
outputWS.onerror = function (e) {
|
outputWS.onerror = function(e) {
|
||||||
console.log('[output onerror] ' + e);
|
console.log('[output onerror] ' + e);
|
||||||
};
|
};
|
||||||
|
|
||||||
var wide = {
|
var wide = {
|
||||||
curNode: undefined,
|
curNode: undefined,
|
||||||
curEditor: undefined,
|
curEditor: undefined,
|
||||||
_initLayout: function () {
|
_initLayout: function() {
|
||||||
var mainH = $(window).height() - $(".menu").height() - $(".footer").height() - 2;
|
var mainH = $(window).height() - $(".menu").height() - $(".footer").height() - 2;
|
||||||
$(".content, .ztree").height(mainH);
|
$(".content, .ztree").height(mainH);
|
||||||
|
|
||||||
$(".edit-panel").height(mainH - $(".output").height());
|
$(".edit-panel").height(mainH - $(".output").height());
|
||||||
},
|
},
|
||||||
init: function () {
|
init: function() {
|
||||||
this._initLayout();
|
this._initLayout();
|
||||||
|
|
||||||
$("body").bind("mousedown", function (event) {
|
$("body").bind("mousedown", function(event) {
|
||||||
if (!(event.target.id === "dirRMenu" || $(event.target).closest("#dirRMenu").length > 0)) {
|
if (!(event.target.id === "dirRMenu" || $(event.target).closest("#dirRMenu").length > 0)) {
|
||||||
$("#dirRMenu").hide();
|
$("#dirRMenu").hide();
|
||||||
}
|
}
|
||||||
|
@ -89,9 +89,8 @@ var wide = {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this._bindKey();
|
|
||||||
},
|
},
|
||||||
saveFile: function () {
|
saveFile: function() {
|
||||||
var request = {
|
var request = {
|
||||||
file: $(".edit-header .current span:eq(0)").attr("title"),
|
file: $(".edit-header .current span:eq(0)").attr("title"),
|
||||||
code: wide.curEditor.getValue()
|
code: wide.curEditor.getValue()
|
||||||
|
@ -101,23 +100,23 @@ var wide = {
|
||||||
url: '/file/save',
|
url: '/file/save',
|
||||||
data: JSON.stringify(request),
|
data: JSON.stringify(request),
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (data) {
|
success: function(data) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
saveAllFiles: function () {
|
saveAllFiles: function() {
|
||||||
// TODO: save all files
|
// TODO: save all files
|
||||||
},
|
},
|
||||||
closeFile: function () {
|
closeFile: function() {
|
||||||
// TODO: close file
|
// TODO: close file
|
||||||
},
|
},
|
||||||
closeAllFiles: function () {
|
closeAllFiles: function() {
|
||||||
// TODO: close all files
|
// TODO: close all files
|
||||||
},
|
},
|
||||||
exit: function () {
|
exit: function() {
|
||||||
// TODO: exit
|
// TODO: exit
|
||||||
},
|
},
|
||||||
run: function () {
|
run: function() {
|
||||||
var request = {
|
var request = {
|
||||||
file: $(".edit-header .current span:eq(0)").attr("title"),
|
file: $(".edit-header .current span:eq(0)").attr("title"),
|
||||||
code: wide.curEditor.getValue()
|
code: wide.curEditor.getValue()
|
||||||
|
@ -128,14 +127,14 @@ var wide = {
|
||||||
url: '/build',
|
url: '/build',
|
||||||
data: JSON.stringify(request),
|
data: JSON.stringify(request),
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
beforeSend: function (data) {
|
beforeSend: function(data) {
|
||||||
$('#output').text('');
|
$('#output').text('');
|
||||||
},
|
},
|
||||||
success: function (data) {
|
success: function(data) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
goget: function () {
|
goget: function() {
|
||||||
var request = {
|
var request = {
|
||||||
file: $(".edit-header .current span:eq(0)").attr("title")
|
file: $(".edit-header .current span:eq(0)").attr("title")
|
||||||
};
|
};
|
||||||
|
@ -145,14 +144,14 @@ var wide = {
|
||||||
url: '/go/get',
|
url: '/go/get',
|
||||||
data: JSON.stringify(request),
|
data: JSON.stringify(request),
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
beforeSend: function (data) {
|
beforeSend: function(data) {
|
||||||
$('#output').text('');
|
$('#output').text('');
|
||||||
},
|
},
|
||||||
success: function (data) {
|
success: function(data) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
goinstall: function () {
|
goinstall: function() {
|
||||||
var request = {
|
var request = {
|
||||||
file: $(".edit-header .current span:eq(0)").attr("title"),
|
file: $(".edit-header .current span:eq(0)").attr("title"),
|
||||||
code: wide.curEditor.getValue()
|
code: wide.curEditor.getValue()
|
||||||
|
@ -163,14 +162,14 @@ var wide = {
|
||||||
url: '/go/install',
|
url: '/go/install',
|
||||||
data: JSON.stringify(request),
|
data: JSON.stringify(request),
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
beforeSend: function (data) {
|
beforeSend: function(data) {
|
||||||
$('#output').text('');
|
$('#output').text('');
|
||||||
},
|
},
|
||||||
success: function (data) {
|
success: function(data) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
fmt: function () {
|
fmt: function() {
|
||||||
var path = $(".edit-header .current span:eq(0)").attr("title");
|
var path = $(".edit-header .current span:eq(0)").attr("title");
|
||||||
var mode = wide.curNode.mode;
|
var mode = wide.curNode.mode;
|
||||||
|
|
||||||
|
@ -188,7 +187,7 @@ var wide = {
|
||||||
url: '/go/fmt',
|
url: '/go/fmt',
|
||||||
data: JSON.stringify(request),
|
data: JSON.stringify(request),
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (data) {
|
success: function(data) {
|
||||||
if (data.succ) {
|
if (data.succ) {
|
||||||
wide.curEditor.setValue(data.code);
|
wide.curEditor.setValue(data.code);
|
||||||
}
|
}
|
||||||
|
@ -202,7 +201,7 @@ var wide = {
|
||||||
url: '/html/fmt',
|
url: '/html/fmt',
|
||||||
data: JSON.stringify(request),
|
data: JSON.stringify(request),
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (data) {
|
success: function(data) {
|
||||||
if (data.succ) {
|
if (data.succ) {
|
||||||
wide.curEditor.setValue(data.code);
|
wide.curEditor.setValue(data.code);
|
||||||
}
|
}
|
||||||
|
@ -226,92 +225,12 @@ var wide = {
|
||||||
// TODO: XML/JSON 格式化处理
|
// TODO: XML/JSON 格式化处理
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
|
||||||
_bindKey: function () {
|
|
||||||
$("#files").keydown(function (event) {
|
|
||||||
switch (event.which) {
|
|
||||||
case 13: // 回车
|
|
||||||
if (!wide.curNode) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wide.curNode.iconSkin === "ico-ztree-dir ") { // 选中节点是目录
|
|
||||||
// 不做任何处理
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 模拟点击:打开文件
|
|
||||||
tree._onClick(wide.curNode);
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 38: // 上
|
|
||||||
if (!wide.curNode) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
tree.fileTree.selectNode(wide.curNode.getPreNode());
|
|
||||||
wide.curNode = wide.curNode.getPreNode();
|
|
||||||
$("#files").focus();
|
|
||||||
break;
|
|
||||||
case 40: // 下
|
|
||||||
if (!wide.curNode) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: 处理滚动条,递归获取下一个
|
|
||||||
tree.fileTree.selectNode(wide.curNode.getNextNode());
|
|
||||||
wide.curNode = wide.curNode.getNextNode();
|
|
||||||
$("#files").focus();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).keydown(function (event) {
|
|
||||||
if (event.ctrlKey && event.which === 49) { // Ctrl+1 焦点切换到文件树
|
|
||||||
// 有些元素需设置 tabindex 为 -1 时才可以 focus
|
|
||||||
$("#files").focus();
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.ctrlKey && event.which === 52) { // Ctrl+4 焦点切换到输出窗口
|
|
||||||
$("#output").focus();
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.ctrlKey && event.which === 83) { // Ctrl+S 保存当前编辑器文件
|
|
||||||
wide.saveFile();
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.altKey && event.shiftKey && event.which === 70) { // Alt+Shift+F 格式化当前编辑器文件
|
|
||||||
if (!wide.curNode) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
wide.fmt();
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.which === 117) { // F6 构建并运行
|
|
||||||
wide.run();
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function() {
|
||||||
wide.init();
|
wide.init();
|
||||||
tree.init();
|
tree.init();
|
||||||
menu.init();
|
menu.init();
|
||||||
|
hotkeys.init();
|
||||||
});
|
});
|
|
@ -199,5 +199,6 @@
|
||||||
<script type="text/javascript" src="{{.Wide.StaticServer}}/static/js/tree.js?{{.Wide.StaticResourceVersion}}"></script>
|
<script type="text/javascript" src="{{.Wide.StaticServer}}/static/js/tree.js?{{.Wide.StaticResourceVersion}}"></script>
|
||||||
<script type="text/javascript" src="{{.Wide.StaticServer}}/static/js/wide.js?{{.Wide.StaticResourceVersion}}"></script>
|
<script type="text/javascript" src="{{.Wide.StaticServer}}/static/js/wide.js?{{.Wide.StaticResourceVersion}}"></script>
|
||||||
<script type="text/javascript" src="{{.Wide.StaticServer}}/static/js/menu.js?{{.Wide.StaticResourceVersion}}"></script>
|
<script type="text/javascript" src="{{.Wide.StaticServer}}/static/js/menu.js?{{.Wide.StaticResourceVersion}}"></script>
|
||||||
|
<script type="text/javascript" src="{{.Wide.StaticServer}}/static/js/hotkeys.js?{{.Wide.StaticResourceVersion}}"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Reference in New Issue