mirror of
https://github.com/coderaiser/cloudcmd.git
synced 2026-01-23 18:55:26 +00:00
483 lines
12 KiB
JavaScript
483 lines
12 KiB
JavaScript
/* global CloudCmd, DOM */
|
||
|
||
'use strict';
|
||
|
||
const Info = DOM.CurrentInfo;
|
||
|
||
const exec = require('execon');
|
||
const clipboard = require('@cloudcmd/clipboard');
|
||
const wraptile = require('wraptile/legacy');
|
||
|
||
const Events = require('../dom/events');
|
||
const Buffer = require('../dom/buffer');
|
||
const KEY = require('./key');
|
||
const vim = require('./vim');
|
||
const setCurrentByChar = require('./set-current-by-char');
|
||
const fullstore = require('fullstore/legacy');
|
||
const Chars = fullstore();
|
||
|
||
Chars([]);
|
||
|
||
KeyProto.prototype = KEY;
|
||
CloudCmd.Key = KeyProto;
|
||
|
||
function KeyProto() {
|
||
let Binded;
|
||
|
||
const Key = this;
|
||
|
||
this.isBind = () => {
|
||
return Binded;
|
||
};
|
||
|
||
this.setBind = () => {
|
||
Binded = true;
|
||
};
|
||
|
||
this.unsetBind = () => {
|
||
Binded = false;
|
||
};
|
||
|
||
this.bind = () => {
|
||
Events.addKey(listener);
|
||
Binded = true;
|
||
};
|
||
|
||
function getChar(event) {
|
||
/*
|
||
* event.keyIdentifier deprecated in chrome v51
|
||
* but event.key is absent in chrome <= v51
|
||
*/
|
||
|
||
if (event.key)
|
||
return event.key;
|
||
|
||
return fromCharCode(event.keyIdentifier);
|
||
}
|
||
|
||
function listener(event) {
|
||
const keyCode = event.keyCode;
|
||
const alt = event.altKey;
|
||
const ctrl = event.ctrlKey;
|
||
const shift = event.shiftKey;
|
||
const meta = event.metaKey;
|
||
const isBetween = keyCode >= KEY.ZERO && keyCode <= KEY.Z;
|
||
const isNumpad = /Numpad/.test(event.code);
|
||
|
||
let char = getChar(event);
|
||
let isSymbol = ~['.', '_', '-', '+', '='].indexOf(char);
|
||
|
||
if (!isSymbol) {
|
||
isSymbol = getSymbol(shift, keyCode);
|
||
|
||
if (isSymbol)
|
||
char = isSymbol;
|
||
}
|
||
|
||
if (!Key.isBind())
|
||
return;
|
||
|
||
const isVim = CloudCmd.config('vim');
|
||
|
||
if (!isVim && !isNumpad && !alt && !ctrl && !meta && (isBetween || isSymbol))
|
||
return setCurrentByChar(char, Chars);
|
||
|
||
Chars([]);
|
||
switchKey(event);
|
||
|
||
if (keyCode >= KEY.F1 && keyCode <= KEY.F10)
|
||
return;
|
||
|
||
if (isVim)
|
||
vim(char, event);
|
||
}
|
||
|
||
function getSymbol(shift, keyCode) {
|
||
switch (keyCode) {
|
||
case KEY.DOT:
|
||
return '.';
|
||
|
||
case KEY.HYPHEN:
|
||
return shift ? '_' : '-';
|
||
|
||
case KEY.EQUAL:
|
||
return shift ? '+' : '=';
|
||
}
|
||
}
|
||
|
||
function fromCharCode(keyIdentifier) {
|
||
const code = keyIdentifier.substring(2);
|
||
const hex = parseInt(code, 16);
|
||
const char = String.fromCharCode(hex);
|
||
|
||
return char;
|
||
}
|
||
|
||
function switchKey(event) {
|
||
let i, isSelected, prev, next;
|
||
let current = Info.element;
|
||
let dataName;
|
||
|
||
const name = Info.name;
|
||
|
||
const {Operation} = CloudCmd;
|
||
const panel = Info.panel;
|
||
const path = Info.path;
|
||
const isDir = Info.isDir;
|
||
|
||
const keyCode = event.keyCode;
|
||
const alt = event.altKey;
|
||
const shift = event.shiftKey;
|
||
const ctrl = event.ctrlKey;
|
||
const meta = event.metaKey;
|
||
const ctrlMeta = ctrl || meta;
|
||
|
||
if (current) {
|
||
prev = current.previousSibling;
|
||
next = current.nextSibling;
|
||
}
|
||
|
||
switch (keyCode) {
|
||
case Key.TAB:
|
||
DOM.changePanel();
|
||
event.preventDefault();
|
||
break;
|
||
|
||
case Key.INSERT:
|
||
DOM .toggleSelectedFile(current)
|
||
.setCurrentFile(next);
|
||
break;
|
||
|
||
case Key.INSERT_MAC:
|
||
DOM .toggleSelectedFile(current)
|
||
.setCurrentFile(next);
|
||
break;
|
||
|
||
case Key.DELETE:
|
||
if (shift)
|
||
Operation.show('delete:silent');
|
||
else
|
||
Operation.show('delete');
|
||
break;
|
||
|
||
case Key.ASTERISK:
|
||
DOM.toggleAllSelectedFiles(current);
|
||
break;
|
||
|
||
case Key.PLUS:
|
||
DOM.expandSelection();
|
||
event.preventDefault();
|
||
break;
|
||
|
||
case Key.MINUS:
|
||
DOM.shrinkSelection();
|
||
event.preventDefault();
|
||
break;
|
||
|
||
case Key.F1:
|
||
CloudCmd.Help.show();
|
||
event.preventDefault();
|
||
break;
|
||
|
||
case Key.F2:
|
||
DOM.renameCurrent(current);
|
||
break;
|
||
|
||
case Key.F3:
|
||
if (shift)
|
||
CloudCmd.Markdown.show(path);
|
||
else if (ctrlMeta)
|
||
CloudCmd.sortPanel('name');
|
||
else
|
||
CloudCmd.View.show();
|
||
|
||
event.preventDefault();
|
||
break;
|
||
|
||
case Key.F4:
|
||
if (shift)
|
||
CloudCmd.EditFileVim.show();
|
||
else
|
||
CloudCmd.EditFile.show();
|
||
|
||
event.preventDefault();
|
||
break;
|
||
|
||
case Key.F5:
|
||
if (ctrlMeta)
|
||
CloudCmd.sortPanel('date');
|
||
else if (alt)
|
||
Operation.show('pack');
|
||
else
|
||
Operation.show('copy');
|
||
|
||
event.preventDefault();
|
||
break;
|
||
|
||
case Key.F6:
|
||
if (ctrlMeta)
|
||
CloudCmd.sortPanel('size');
|
||
else
|
||
Operation.show('move');
|
||
|
||
event.preventDefault();
|
||
break;
|
||
|
||
case Key.F7:
|
||
if (shift)
|
||
DOM.promptNewFile();
|
||
else
|
||
DOM.promptNewDir();
|
||
|
||
event.preventDefault();
|
||
break;
|
||
|
||
case Key.F8:
|
||
Operation.show('delete');
|
||
event.preventDefault();
|
||
break;
|
||
|
||
case Key.F9:
|
||
if (alt)
|
||
Operation.show('extract');
|
||
else
|
||
CloudCmd.Menu.show();
|
||
event.preventDefault();
|
||
break;
|
||
|
||
case Key.F10:
|
||
CloudCmd.Config.show();
|
||
event.preventDefault();
|
||
break;
|
||
|
||
case Key.TRA:
|
||
event.preventDefault();
|
||
|
||
if (shift)
|
||
return CloudCmd.Terminal.show();
|
||
|
||
CloudCmd.Konsole.show();
|
||
break;
|
||
|
||
case KEY.BRACKET_CLOSE:
|
||
CloudCmd.Konsole.show();
|
||
event.preventDefault();
|
||
break;
|
||
|
||
case Key.SPACE:
|
||
if (!isDir || name === '..')
|
||
isSelected = true;
|
||
else
|
||
isSelected = DOM.isSelected(current);
|
||
|
||
exec.if(isSelected, () => {
|
||
DOM.toggleSelectedFile(current);
|
||
}, (callback) => {
|
||
DOM.loadCurrentSize(callback, current);
|
||
});
|
||
|
||
event.preventDefault();
|
||
break;
|
||
|
||
case Key.U:
|
||
if (ctrlMeta) {
|
||
DOM.swapPanels();
|
||
event.preventDefault();
|
||
}
|
||
break;
|
||
|
||
/* navigation on file table: *
|
||
* in case of pressing button 'up', *
|
||
* select previous row */
|
||
case Key.UP:
|
||
if (shift)
|
||
DOM.toggleSelectedFile(current);
|
||
|
||
DOM.setCurrentFile(prev);
|
||
event.preventDefault();
|
||
break;
|
||
|
||
/* in case of pressing button 'down', *
|
||
* select next row */
|
||
case Key.DOWN:
|
||
if (shift)
|
||
DOM.toggleSelectedFile(current);
|
||
|
||
DOM.setCurrentFile(next);
|
||
event.preventDefault();
|
||
break;
|
||
|
||
case Key.LEFT:
|
||
if (!alt)
|
||
return;
|
||
|
||
event.preventDefault();
|
||
|
||
dataName = Info.panel.getAttribute('data-name');
|
||
|
||
if (dataName === 'js-right')
|
||
DOM.duplicatePanel();
|
||
|
||
break;
|
||
|
||
case Key.RIGHT:
|
||
if (!alt)
|
||
return;
|
||
|
||
event.preventDefault();
|
||
|
||
dataName = Info.panel.getAttribute('data-name');
|
||
|
||
if (dataName === 'js-left')
|
||
DOM.duplicatePanel();
|
||
|
||
break;
|
||
|
||
/* in case of pressing button 'Home', *
|
||
* go to top element */
|
||
case Key.HOME:
|
||
DOM.setCurrentFile(Info.first);
|
||
event.preventDefault();
|
||
break;
|
||
|
||
/* in case of pressing button 'End', select last element */
|
||
case Key.END:
|
||
DOM.setCurrentFile(Info.last);
|
||
event.preventDefault();
|
||
break;
|
||
|
||
/* если нажали клавишу page down проматываем экран */
|
||
case Key.PAGE_DOWN:
|
||
DOM.scrollByPages(panel, 1);
|
||
|
||
for (i = 0; i < 30; i++) {
|
||
if (!current.nextSibling)
|
||
break;
|
||
|
||
current = current.nextSibling;
|
||
}
|
||
|
||
DOM.setCurrentFile(current);
|
||
event.preventDefault();
|
||
break;
|
||
|
||
/* если нажали клавишу page up проматываем экран */
|
||
case Key.PAGE_UP:
|
||
DOM.scrollByPages(panel, -1);
|
||
|
||
for (i = 0; i < 30; i++) {
|
||
if (!current.previousSibling)
|
||
break;
|
||
|
||
current = current.previousSibling;
|
||
}
|
||
|
||
DOM.setCurrentFile(current);
|
||
event.preventDefault();
|
||
break;
|
||
|
||
/* open directory */
|
||
case Key.ENTER:
|
||
if (Info.isDir)
|
||
CloudCmd.loadDir({
|
||
path: path === '/' ? '/' : path + '/'
|
||
});
|
||
break;
|
||
|
||
case Key.BACKSPACE:
|
||
CloudCmd.goToParentDir();
|
||
event.preventDefault();
|
||
break;
|
||
|
||
case Key.BACKSLASH:
|
||
if (ctrlMeta)
|
||
CloudCmd.loadDir({
|
||
path: '/'
|
||
});
|
||
break;
|
||
|
||
case Key.A:
|
||
if (ctrlMeta) {
|
||
DOM.selectAllFiles();
|
||
event.preventDefault();
|
||
}
|
||
|
||
break;
|
||
|
||
case Key.G:
|
||
if (alt) {
|
||
DOM.goToDirectory();
|
||
event.preventDefault();
|
||
}
|
||
|
||
break;
|
||
|
||
case Key.M:
|
||
if (ctrlMeta) {
|
||
if (shift)
|
||
CloudCmd.EditNamesVim.show();
|
||
else
|
||
CloudCmd.EditNames.show();
|
||
|
||
event.preventDefault();
|
||
}
|
||
|
||
break;
|
||
|
||
case Key.P:
|
||
if (!ctrlMeta)
|
||
return;
|
||
|
||
event.preventDefault();
|
||
clipboard
|
||
.writeText(Info.dirPath)
|
||
.catch(CloudCmd.log);
|
||
|
||
break;
|
||
/**
|
||
* обновляем страницу,
|
||
* загружаем содержимое каталога
|
||
* при этом данные берём всегда с
|
||
* сервера, а не из кэша
|
||
* (обновляем кэш)
|
||
*/
|
||
case Key.R:
|
||
if (ctrlMeta) {
|
||
CloudCmd.log('reloading page...\n');
|
||
CloudCmd.refresh();
|
||
event.preventDefault();
|
||
}
|
||
break;
|
||
|
||
case Key.C:
|
||
if (ctrlMeta)
|
||
Buffer.copy();
|
||
break;
|
||
|
||
case Key.X:
|
||
if (ctrlMeta)
|
||
Buffer.cut();
|
||
break;
|
||
|
||
case Key.V:
|
||
if (ctrlMeta)
|
||
Buffer.paste();
|
||
break;
|
||
|
||
case Key.Z:
|
||
if (ctrlMeta)
|
||
Buffer.clear();
|
||
break;
|
||
|
||
/* чистим хранилище */
|
||
case Key.D:
|
||
if (ctrlMeta) {
|
||
CloudCmd.log('clearing storage...');
|
||
DOM.Storage.clear(wraptile(CloudCmd.log, 'storage cleared'));
|
||
event.preventDefault();
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|