bzr branch
http://gegoxaren.bato24.eu/bzr/lenasys/trunk
20.1.1
by galaxyAbstractor
* Added an simple admin panel to the codeviewer-cmssy stuff |
1 |
/* ***** BEGIN LICENSE BLOCK *****
|
2 |
* Distributed under the BSD license:
|
|
3 |
*
|
|
4 |
* Copyright (c) 2010, Ajax.org B.V.
|
|
5 |
* All rights reserved.
|
|
6 |
*
|
|
7 |
* Redistribution and use in source and binary forms, with or without
|
|
8 |
* modification, are permitted provided that the following conditions are met:
|
|
9 |
* * Redistributions of source code must retain the above copyright
|
|
10 |
* notice, this list of conditions and the following disclaimer.
|
|
11 |
* * Redistributions in binary form must reproduce the above copyright
|
|
12 |
* notice, this list of conditions and the following disclaimer in the
|
|
13 |
* documentation and/or other materials provided with the distribution.
|
|
14 |
* * Neither the name of Ajax.org B.V. nor the
|
|
15 |
* names of its contributors may be used to endorse or promote products
|
|
16 |
* derived from this software without specific prior written permission.
|
|
17 |
*
|
|
18 |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
19 |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
20 |
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
21 |
* DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
|
|
22 |
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
23 |
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
24 |
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
25 |
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
26 |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
27 |
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
28 |
*
|
|
29 |
* ***** END LICENSE BLOCK ***** */
|
|
30 |
||
31 |
define('ace/keyboard/emacs', ['require', 'exports', 'module' , 'ace/lib/dom', 'ace/keyboard/hash_handler', 'ace/lib/keys'], function(require, exports, module) { |
|
32 |
||
33 |
||
34 |
var dom = require("../lib/dom"); |
|
35 |
||
36 |
var screenToTextBlockCoordinates = function(x, y) { |
|
37 |
var canvasPos = this.scroller.getBoundingClientRect(); |
|
38 |
||
39 |
var col = Math.floor( |
|
40 |
(x + this.scrollLeft - canvasPos.left - this.$padding) / this.characterWidth |
|
41 |
); |
|
42 |
var row = Math.floor( |
|
43 |
(y + this.scrollTop - canvasPos.top) / this.lineHeight |
|
44 |
); |
|
45 |
||
46 |
return this.session.screenToDocumentPosition(row, col); |
|
47 |
};
|
|
48 |
||
49 |
var HashHandler = require("./hash_handler").HashHandler; |
|
50 |
exports.handler = new HashHandler(); |
|
51 |
||
52 |
var initialized = false; |
|
53 |
var $formerLongWords; |
|
54 |
var $formerLineStart; |
|
55 |
||
56 |
exports.handler.attach = function(editor) { |
|
57 |
if (!initialized) { |
|
58 |
initialized = true; |
|
59 |
dom.importCssString('\ |
|
60 |
.emacs-mode .ace_cursor{\
|
|
61 |
border: 2px rgba(50,250,50,0.8) solid!important;\
|
|
62 |
-moz-box-sizing: border-box!important;\
|
|
63 |
-webkit-box-sizing: border-box!important;\
|
|
64 |
box-sizing: border-box!important;\
|
|
65 |
background-color: rgba(0,250,0,0.9);\
|
|
66 |
opacity: 0.5;\
|
|
67 |
}\
|
|
68 |
.emacs-mode .ace_cursor.ace_hidden{\
|
|
69 |
opacity: 1;\
|
|
70 |
background-color: transparent;\
|
|
71 |
}\
|
|
72 |
.emacs-mode .ace_overwrite-cursors .ace_cursor {\
|
|
73 |
opacity: 1;\
|
|
74 |
background-color: transparent;\
|
|
75 |
border-width: 0 0 2px 2px !important;\
|
|
76 |
}\
|
|
77 |
.emacs-mode .ace_text-layer {\
|
|
78 |
z-index: 4\
|
|
79 |
}\
|
|
80 |
.emacs-mode .ace_cursor-layer {\
|
|
81 |
z-index: 2\
|
|
82 |
}', 'emacsMode' |
|
83 |
); |
|
84 |
} |
|
85 |
$formerLongWords = editor.session.$selectLongWords; |
|
86 |
editor.session.$selectLongWords = true; |
|
87 |
$formerLineStart = editor.session.$useEmacsStyleLineStart; |
|
88 |
editor.session.$useEmacsStyleLineStart = true; |
|
89 |
||
90 |
editor.session.$emacsMark = null; |
|
91 |
||
92 |
exports.markMode = function() { |
|
93 |
return editor.session.$emacsMark; |
|
94 |
} |
|
95 |
||
96 |
exports.setMarkMode = function(p) { |
|
97 |
editor.session.$emacsMark = p; |
|
98 |
} |
|
99 |
||
100 |
editor.on("click",$resetMarkMode); |
|
101 |
editor.on("changeSession",$kbSessionChange); |
|
102 |
editor.renderer.screenToTextCoordinates = screenToTextBlockCoordinates; |
|
103 |
editor.setStyle("emacs-mode"); |
|
104 |
editor.commands.addCommands(commands); |
|
105 |
exports.handler.platform = editor.commands.platform; |
|
106 |
};
|
|
107 |
||
108 |
exports.handler.detach = function(editor) { |
|
109 |
delete editor.renderer.screenToTextCoordinates; |
|
110 |
editor.session.$selectLongWords = $formerLongWords; |
|
111 |
editor.session.$useEmacsStyleLineStart = $formerLineStart; |
|
112 |
editor.removeEventListener("click",$resetMarkMode); |
|
113 |
editor.removeEventListener("changeSession",$kbSessionChange); |
|
114 |
editor.unsetStyle("emacs-mode"); |
|
115 |
editor.commands.removeCommands(commands); |
|
116 |
};
|
|
117 |
||
118 |
var $kbSessionChange = function(e) { |
|
119 |
if (e.oldSession) { |
|
120 |
e.oldSession.$selectLongWords = $formerLongWords; |
|
121 |
e.oldSession.$useEmacsStyleLineStart = $formerLineStart; |
|
122 |
} |
|
123 |
||
124 |
$formerLongWords = e.session.$selectLongWords; |
|
125 |
e.session.$selectLongWords = true; |
|
126 |
$formerLineStart = e.session.$useEmacsStyleLineStart; |
|
127 |
e.session.$useEmacsStyleLineStart = true; |
|
128 |
||
129 |
if (!e.session.hasOwnProperty('$emacsMark')) |
|
130 |
e.session.$emacsMark = null; |
|
131 |
}
|
|
132 |
||
133 |
var $resetMarkMode = function(e) { |
|
134 |
e.editor.session.$emacsMark = null; |
|
135 |
}
|
|
136 |
||
137 |
var keys = require("../lib/keys").KEY_MODS, |
|
138 |
eMods = {C: "ctrl", S: "shift", M: "alt", CMD: "command"}, |
|
139 |
combinations = ["C-S-M-CMD", |
|
140 |
"S-M-CMD", "C-M-CMD", "C-S-CMD", "C-S-M", |
|
141 |
"M-CMD", "S-CMD", "S-M", "C-CMD", "C-M", "C-S", |
|
142 |
"CMD", "M", "S", "C"]; |
|
143 |
combinations.forEach(function(c) { |
|
144 |
var hashId = 0; |
|
145 |
c.split("-").forEach(function(c) { |
|
146 |
hashId = hashId | keys[eMods[c]]; |
|
147 |
}); |
|
148 |
eMods[hashId] = c.toLowerCase() + "-"; |
|
149 |
});
|
|
150 |
||
151 |
exports.handler.bindKey = function(key, command) { |
|
152 |
if (!key) |
|
153 |
return; |
|
154 |
||
155 |
var ckb = this.commmandKeyBinding; |
|
156 |
key.split("|").forEach(function(keyPart) { |
|
157 |
keyPart = keyPart.toLowerCase(); |
|
158 |
ckb[keyPart] = command; |
|
159 |
keyPart = keyPart.split(" ")[0]; |
|
160 |
if (!ckb[keyPart]) |
|
161 |
ckb[keyPart] = "null"; |
|
162 |
}, this); |
|
163 |
};
|
|
164 |
||
165 |
||
166 |
exports.handler.handleKeyboard = function(data, hashId, key, keyCode) { |
|
167 |
if (hashId == -1) { |
|
168 |
exports.setMarkMode(null); |
|
169 |
if (data.count) { |
|
170 |
var str = Array(data.count + 1).join(key); |
|
171 |
data.count = null; |
|
172 |
return {command: "insertstring", args: str}; |
|
173 |
} |
|
174 |
} |
|
175 |
||
176 |
if (key == "\x00") |
|
177 |
return; |
|
178 |
||
179 |
var modifier = eMods[hashId]; |
|
180 |
if (modifier == "c-" || data.universalArgument) { |
|
181 |
var count = parseInt(key[key.length - 1]); |
|
182 |
if (count) { |
|
183 |
data.count = count; |
|
184 |
return {command: "null"}; |
|
185 |
} |
|
186 |
} |
|
187 |
data.universalArgument = false; |
|
188 |
if (modifier) key = modifier + key; |
|
189 |
if (data.keyChain) key = data.keyChain += " " + key; |
|
190 |
var command = this.commmandKeyBinding[key]; |
|
191 |
data.keyChain = command == "null" ? key : ""; |
|
192 |
if (!command) return; |
|
193 |
if (command === "null") return {command: "null"}; |
|
194 |
||
195 |
if (command === "universalArgument") { |
|
196 |
data.universalArgument = true; |
|
197 |
return {command: "null"}; |
|
198 |
} |
|
199 |
var args; |
|
200 |
if (typeof command !== "string") { |
|
201 |
args = command.args; |
|
202 |
if (command.command) command = command.command; |
|
203 |
if (command === "goorselect") { |
|
204 |
command = exports.markMode() ? args[1] : args[0]; |
|
205 |
args = null; |
|
206 |
} |
|
207 |
} |
|
208 |
||
209 |
if (typeof command === "string") { |
|
210 |
if (command === "insertstring" || |
|
211 |
command === "splitline" || |
|
212 |
command === "togglecomment") { |
|
213 |
exports.setMarkMode(null); |
|
214 |
} |
|
215 |
command = this.commands[command] || data.editor.commands.commands[command]; |
|
216 |
} |
|
217 |
||
218 |
if (!command.readonly && !command.isYank) |
|
219 |
data.lastCommand = null; |
|
220 |
||
221 |
if (data.count) { |
|
222 |
var count = data.count; |
|
223 |
data.count = 0; |
|
224 |
return { |
|
225 |
args: args, |
|
226 |
command: { |
|
227 |
exec: function(editor, args) { |
|
228 |
for (var i = 0; i < count; i++) |
|
229 |
command.exec(editor, args); |
|
230 |
} |
|
231 |
} |
|
232 |
}; |
|
233 |
} |
|
234 |
||
235 |
return {command: command, args: args}; |
|
236 |
};
|
|
237 |
||
238 |
exports.emacsKeys = { |
|
239 |
"Up|C-p" : {command: "goorselect", args: ["golineup","selectup"]}, |
|
240 |
"Down|C-n" : {command: "goorselect", args: ["golinedown","selectdown"]}, |
|
241 |
"Left|C-b" : {command: "goorselect", args: ["gotoleft","selectleft"]}, |
|
242 |
"Right|C-f" : {command: "goorselect", args: ["gotoright","selectright"]}, |
|
243 |
"C-Left|M-b" : {command: "goorselect", args: ["gotowordleft","selectwordleft"]}, |
|
244 |
"C-Right|M-f" : {command: "goorselect", args: ["gotowordright","selectwordright"]}, |
|
245 |
"Home|C-a" : {command: "goorselect", args: ["gotolinestart","selecttolinestart"]}, |
|
246 |
"End|C-e" : {command: "goorselect", args: ["gotolineend","selecttolineend"]}, |
|
247 |
"C-Home|S-M-,": {command: "goorselect", args: ["gotostart","selecttostart"]}, |
|
248 |
"C-End|S-M-." : {command: "goorselect", args: ["gotoend","selecttoend"]}, |
|
249 |
"S-Up|S-C-p" : "selectup", |
|
250 |
"S-Down|S-C-n" : "selectdown", |
|
251 |
"S-Left|S-C-b" : "selectleft", |
|
252 |
"S-Right|S-C-f" : "selectright", |
|
253 |
"S-C-Left|S-M-b" : "selectwordleft", |
|
254 |
"S-C-Right|S-M-f" : "selectwordright", |
|
255 |
"S-Home|S-C-a" : "selecttolinestart", |
|
256 |
"S-End|S-C-e" : "selecttolineend", |
|
257 |
"S-C-Home" : "selecttostart", |
|
258 |
"S-C-End" : "selecttoend", |
|
259 |
||
260 |
"C-l" : "recenterTopBottom", |
|
261 |
"M-s" : "centerselection", |
|
262 |
"M-g": "gotoline", |
|
263 |
"C-x C-p": "selectall", |
|
264 |
"C-Down": {command: "goorselect", args: ["gotopagedown","selectpagedown"]}, |
|
265 |
"C-Up": {command: "goorselect", args: ["gotopageup","selectpageup"]}, |
|
266 |
"PageDown|C-v": {command: "goorselect", args: ["gotopagedown","selectpagedown"]}, |
|
267 |
"PageUp|M-v": {command: "goorselect", args: ["gotopageup","selectpageup"]}, |
|
268 |
"S-C-Down": "selectpagedown", |
|
269 |
"S-C-Up": "selectpageup", |
|
270 |
"C-s": "findnext", |
|
271 |
"C-r": "findprevious", |
|
272 |
"M-C-s": "findnext", |
|
273 |
"M-C-r": "findprevious", |
|
274 |
"S-M-5": "replace", |
|
275 |
"Backspace": "backspace", |
|
276 |
"Delete|C-d": "del", |
|
277 |
"Return|C-m": {command: "insertstring", args: "\n"}, // "newline" |
|
278 |
"C-o": "splitline", |
|
279 |
||
280 |
"M-d|C-Delete": {command: "killWord", args: "right"}, |
|
281 |
"C-Backspace|M-Backspace|M-Delete": {command: "killWord", args: "left"}, |
|
282 |
"C-k": "killLine", |
|
283 |
||
284 |
"C-y|S-Delete": "yank", |
|
285 |
"M-y": "yankRotate", |
|
286 |
"C-g": "keyboardQuit", |
|
287 |
||
288 |
"C-w": "killRegion", |
|
289 |
"M-w": "killRingSave", |
|
290 |
"C-Space": "setMark", |
|
291 |
"C-x C-x": "exchangePointAndMark", |
|
292 |
||
293 |
"C-t": "transposeletters", |
|
294 |
"M-u": "touppercase", // Doesn't work |
|
295 |
"M-l": "tolowercase", |
|
296 |
"M-/": "autocomplete", // Doesn't work |
|
297 |
"C-u": "universalArgument", |
|
298 |
||
299 |
"M-;": "togglecomment", |
|
300 |
||
301 |
"C-/|C-x u|S-C--|C-z": "undo", |
|
302 |
"S-C-/|S-C-x u|C--|S-C-z": "redo", //infinite undo? |
|
303 |
"C-x r": "selectRectangularRegion" |
|
304 |
};
|
|
305 |
||
306 |
||
307 |
exports.handler.bindKeys(exports.emacsKeys); |
|
308 |
||
309 |
exports.handler.addCommands({ |
|
310 |
recenterTopBottom: function(editor) { |
|
311 |
var renderer = editor.renderer; |
|
312 |
var pos = renderer.$cursorLayer.getPixelPosition(); |
|
313 |
var h = renderer.$size.scrollerHeight - renderer.lineHeight; |
|
314 |
var scrollTop = renderer.scrollTop; |
|
315 |
if (Math.abs(pos.top - scrollTop) < 2) { |
|
316 |
scrollTop = pos.top - h; |
|
317 |
} else if (Math.abs(pos.top - scrollTop - h * 0.5) < 2) { |
|
318 |
scrollTop = pos.top; |
|
319 |
} else { |
|
320 |
scrollTop = pos.top - h * 0.5; |
|
321 |
} |
|
322 |
editor.session.setScrollTop(scrollTop); |
|
323 |
}, |
|
324 |
selectRectangularRegion: function(editor) { |
|
325 |
editor.multiSelect.toggleBlockSelection(); |
|
326 |
}, |
|
327 |
setMark: function(editor) { |
|
328 |
var markMode = exports.markMode(); |
|
329 |
if (markMode) { |
|
330 |
var cp = editor.getCursorPosition(); |
|
331 |
if (editor.selection.isEmpty() && |
|
332 |
markMode.row == cp.row && markMode.column == cp.column) { |
|
333 |
exports.setMarkMode(null); |
|
334 |
return; |
|
335 |
} |
|
336 |
} |
|
337 |
markMode = editor.getCursorPosition(); |
|
338 |
exports.setMarkMode(markMode); |
|
339 |
editor.selection.setSelectionAnchor(markMode.row, markMode.column); |
|
340 |
||
341 |
}, |
|
342 |
exchangePointAndMark: { |
|
343 |
exec: function(editor) { |
|
344 |
var range = editor.selection.getRange(); |
|
345 |
editor.selection.setSelectionRange(range, !editor.selection.isBackwards()); |
|
346 |
}, |
|
347 |
readonly: true, |
|
348 |
multiselectAction: "forEach" |
|
349 |
}, |
|
350 |
killWord: { |
|
351 |
exec: function(editor, dir) { |
|
352 |
editor.clearSelection(); |
|
353 |
if (dir == "left") |
|
354 |
editor.selection.selectWordLeft(); |
|
355 |
else |
|
356 |
editor.selection.selectWordRight(); |
|
357 |
||
358 |
var range = editor.getSelectionRange(); |
|
359 |
var text = editor.session.getTextRange(range); |
|
360 |
exports.killRing.add(text); |
|
361 |
||
362 |
editor.session.remove(range); |
|
363 |
editor.clearSelection(); |
|
364 |
}, |
|
365 |
multiselectAction: "forEach" |
|
366 |
}, |
|
367 |
killLine: function(editor) { |
|
368 |
exports.setMarkMode(null); |
|
369 |
var pos = editor.getCursorPosition(); |
|
370 |
if (pos.column == 0 && |
|
371 |
editor.session.doc.getLine(pos.row).length == 0) { |
|
372 |
editor.selection.selectLine(); |
|
373 |
} else { |
|
374 |
editor.clearSelection(); |
|
375 |
editor.selection.selectLineEnd(); |
|
376 |
} |
|
377 |
var range = editor.getSelectionRange(); |
|
378 |
var text = editor.session.getTextRange(range); |
|
379 |
exports.killRing.add(text); |
|
380 |
||
381 |
editor.session.remove(range); |
|
382 |
editor.clearSelection(); |
|
383 |
}, |
|
384 |
yank: function(editor) { |
|
385 |
editor.onPaste(exports.killRing.get()); |
|
386 |
editor.keyBinding.$data.lastCommand = "yank"; |
|
387 |
}, |
|
388 |
yankRotate: function(editor) { |
|
389 |
if (editor.keyBinding.$data.lastCommand != "yank") |
|
390 |
return; |
|
391 |
editor.undo(); |
|
392 |
editor.onPaste(exports.killRing.rotate()); |
|
393 |
editor.keyBinding.$data.lastCommand = "yank"; |
|
394 |
}, |
|
395 |
killRegion: function(editor) { |
|
396 |
exports.killRing.add(editor.getCopyText()); |
|
397 |
editor.commands.byName.cut.exec(editor); |
|
398 |
}, |
|
399 |
killRingSave: function(editor) { |
|
400 |
exports.killRing.add(editor.getCopyText()); |
|
401 |
}, |
|
402 |
keyboardQuit: function(editor) { |
|
403 |
editor.selection.clearSelection(); |
|
404 |
exports.setMarkMode(null); |
|
405 |
} |
|
406 |
});
|
|
407 |
||
408 |
var commands = exports.handler.commands; |
|
409 |
commands.yank.isYank = true; |
|
410 |
commands.yankRotate.isYank = true; |
|
411 |
||
412 |
exports.killRing = { |
|
413 |
$data: [], |
|
414 |
add: function(str) { |
|
415 |
str && this.$data.push(str); |
|
416 |
if (this.$data.length > 30) |
|
417 |
this.$data.shift(); |
|
418 |
}, |
|
419 |
get: function() { |
|
420 |
return this.$data[this.$data.length - 1] || ""; |
|
421 |
}, |
|
422 |
pop: function() { |
|
423 |
if (this.$data.length > 1) |
|
424 |
this.$data.pop(); |
|
425 |
return this.get(); |
|
426 |
}, |
|
427 |
rotate: function() { |
|
428 |
this.$data.unshift(this.$data.pop()); |
|
429 |
return this.get(); |
|
430 |
} |
|
431 |
};
|
|
432 |
||
433 |
||
434 |
});
|