2017-01-30 11:32:54 +00:00

242 lines
8.7 KiB
JavaScript

define(function(require, exports, module) {
var isWindows = require("ace/lib/useragent").isWindows;
module.exports = function initInput(ace) {
// use showkey --ascii to test
var HashHandler = require("ace/keyboard/hash_handler").HashHandler;
var KEY_MODS = require("ace/lib/keys").KEY_MODS;
var TERM_MODS = {
"shift-": 2,
"alt-": 3,
"alt-shift-": 4,
"ctrl-": 5,
"ctrl-shift-": 6,
"ctrl-alt-": 7,
"ctrl-alt-shift-": 8,
};
var specialKeys = new HashHandler();
// http://www.math.utah.edu/docs/info/features_7.html
specialKeys.bindKeys({
"Shift-PageUp": { command: "pageup" },
"Shift-PageDown": { command: "pagedown" },
"Ctrl-Up": { command: "scrollup" },
"Ctrl-Down": { command: "scrolldown" },
"Backspace": '\x7f',
"Shift-Backspace": '\x08',
"Alt-Backspace": '\x1b\x7f',
"Tab": '\t',
"Shift-Tab": '\x1b[Z',
"Return": '\r',
"Escape": '\x1b',
"Left": '\x1b[D',
"Right": '\x1b[C',
"Up": '\x1b[A',
"Down": '\x1b[B',
"Delete": '\x1b[3~',
"Insert": '\x1b[2~',
"Home": '\x1b[1~',
"End": '\x1b[4~',
"PageUp": '\x1b[5~',
"PageDown": '\x1b[6~',
"F1": '\x1bOP',
"F2": '\x1bOQ',
"F3": '\x1bOR',
"F4": '\x1bOS',
"F5": '\x1b[15~',
"F6": '\x1b[17~',
"F7": '\x1b[18~',
"F8": '\x1b[19~',
"F9": '\x1b[20~',
"F10": '\x1b[21~',
"F11": '\x1b[23~',
"F12": '\x1b[24~'
});
// make shell to behave more like regular editor
var aliases = [{
bindKey: { win: "Ctrl-left", mac: "Option-left" },
name: "\u001bb" // "alt-b"
}, {
bindKey: { win: "Ctrl-right", mac: "Option-right" },
name: "\u001bf" // "alt-b"
}, {
bindKey: { win: "Ctrl-Delete", mac: "Option-Delete" },
name: "\u001bd" // "alt-d"
}, {
bindKey: { win: "Ctrl-Backspace", mac: "Option-Backspace" },
name: "\x1b\x7f" // "alt-backspace"
}, {
bindKey: { win: "Ctrl-Delete", mac: "Option-Delete" },
name: "\u001bd" // "alt-d"
}, {
bindKey: { win: "Alt-Backspace", mac: "Ctrl-Backspace" },
name: "\u0015" // "ctrl-u"
}, {
bindKey: { win: "Alt-Delete", mac: "Ctrl-Delete" },
name: "\u000b" // "ctrl-k"
}, {
bindKey: { win: "Ctrl-z", mac: "Cmd-z" },
name: "\u0018\u0015" // "ctrl-x ctrl-u"
}, {
bindKey: { win: null, mac: "Cmd-Left" },
name: "\x1b[1~" // "ctrl-x ctrl-u"
}, {
bindKey: { win: null, mac: "Cmd-Right" },
name: "\x1b[4~" // "ctrl-x ctrl-u"
}];
specialKeys.addCommands(aliases);
// SS3 as ^[O for 7-bit '\x8fD'; SS3 as 0x8f for 8-bit
var applicationKeys = {
"left": '\x1bOD',
"right": '\x1bOC',
"up": '\x1bOA',
"down": '\x1bOB',
"home": '\x1bOH',
"end": '\x1bOF'
};
function defaultHandler(ev) {
var key = null;
var keyCode = ev.keyCode;
var isControl = ev.ctrlKey;
var isMeta = specialKeys.platform == "mac" ? ev.metaKey : ev.altKey;
// a-z and space
if (isControl) {
if (keyCode >= 65 && keyCode <= 90) {
key = String.fromCharCode(keyCode - 64);
} else if (keyCode === 32 || keyCode == 192) {
// NUL
key = String.fromCharCode(0);
} else if (keyCode >= 51 && keyCode <= 55) {
// escape, file sep, group sep, record sep, unit sep
key = String.fromCharCode(keyCode - 51 + 27);
} else if (keyCode === 56) {
// delete
key = String.fromCharCode(127);
} else if (keyCode === 219) {
// ^[ - escape
key = String.fromCharCode(27);
} else if (keyCode === 221) {
// ^] - group sep
key = String.fromCharCode(29);
} else if (keyCode === 189 || keyCode === 173) {
// _
key = String.fromCharCode(31);
} else if (keyCode === 220) {
// SIGQUIT
key = String.fromCharCode(28);
}
} else if (isMeta) {
if (keyCode >= 65 && keyCode <= 90) {
key = '\x1b' + String.fromCharCode(keyCode + 32);
} else if (keyCode === 192) {
key = '\x1b`';
} else if (keyCode >= 48 && keyCode <= 57) {
key = '\x1b' + (keyCode - 48);
}
}
return key;
}
this.handleKeyboard = function(data, hashId, keyString, keyCode, ev) {
var term = data.editor.session.term;
if (hashId == -1) {
this.send(keyString);
return { command: "null" };
}
if (term.applicationKeypad) {
if (applicationKeys[keyString]) {
var mod = TERM_MODS[KEY_MODS[hashId]];
var str = applicationKeys[keyString];
if (mod)
str = "\u001b[1;" + mod + str.slice(-1);
this.send(str);
return { command: "null" };
}
}
var key = specialKeys.findKeyCommand(hashId, keyString);
if (typeof key == "string") {
this.send(key);
return { command: "null" };
} else if (key && key.command) {
return key;
} else if (key && key.exec) {
if (!key.isAvailable || key.isAvailable(ace))
return { command: key };
} else if (key && key.name) {
this.send(key.name);
return { command: "null" };
}
key = defaultHandler(ev);
if (key)
this.send(key);
return {
command: "null",
passEvent: !hashId || hashId === KEY_MODS.shift || (
// on mac key combos without ctrl or cmd trigger textinput
specialKeys.platform === "mac" && !(hashId & (KEY_MODS.ctrl | KEY_MODS.cmd))
) || (
// on windows 8+ calling preventDefault on win+space breaks textinput
specialKeys.platform === "win" && hashId == KEY_MODS.cmd && (keyCode == 32 || keyCode == -1)
)
};
};
var isCopyAvailable = function(ed) {
if (ed && !ed.getCopyText)
ed = ed.ace || ed.$editor;
return ed && !!ed.getCopyText();
};
var noop = function() {};
// Add special handling for editor keys
specialKeys.addCommands([{
name: "copy",
bindKey: { mac: "Cmd-c", win: "Ctrl-c" },
exec: noop,
isAvailable: isCopyAvailable,
passEvent: true
}, {
name: "cut",
bindKey: { mac: "Cmd-x", win: "Ctrl-x" },
exec: noop,
isAvailable: isCopyAvailable,
passEvent: true
}, {
name: "paste",
bindKey: { mac: "Cmd-v", win: "Ctrl-v" },
exec: noop,
isAvailable: function(ed) {
return true;
},
passEvent: true
}, {
name: "clear",
bindKey: { mac: "Cmd-K", win: "Ctrl-K" },
exec: function(ed) {
var term = ed.ace.session.term;
term.clear();
term.send("\x0c"); //"ctrl-l"
},
isAvailable: function(editor) {
return true; // todo disable in vim?
}
}]);
ace.onPaste = function(text) {
this.send(text.replace(/\r\n?|\n/g, this.session.term.convertEol ? "\n" : "\r"));
};
ace.setKeyboardHandler(this);
ace.keyBinding.addKeyboardHandler(ace.commands);
ace.commands.commandKeyBinding = {};
this.send = ace.send = function(text) {
ace.session.send && ace.session.send(text);
};
return specialKeys;
};
});