feature(vim) add find support with: "/", "n" and "N"

This commit is contained in:
coderaiser 2017-09-11 17:12:24 +03:00
parent 3693f6f799
commit 2edf7f8321
7 changed files with 269 additions and 29 deletions

53
client/key/vim/find.js Normal file
View file

@ -0,0 +1,53 @@
'use strict';
/* global DOM */
const fullstore = require('fullstore');
const limier = require('limier');
const Info = DOM.CurrentInfo;
const searchStore = fullstore([]);
const searchIndex = fullstore(0);
module.exports.find = (value) => {
const names = Info.files.map(DOM.getCurrentName);
const result = limier(value, names);
searchStore(result);
searchIndex(0);
DOM.setCurrentByName(result[0]);
};
module.exports.findNext = () => {
const names = searchStore();
const index = next(searchIndex(), names.length);
searchIndex(index);
DOM.setCurrentByName(names[searchIndex()]);
};
module.exports.findPrevious = () => {
const names = searchStore();
const index = previous(searchIndex(), names.length);
searchIndex(index);
DOM.setCurrentByName(names[index]);
};
module.exports._next = next;
module.exports._previous = previous;
function next(index, length) {
if (index === length - 1)
return 0;
return ++index;
}
function previous(index, length) {
if (!index)
return length - 1;
return --index;
}

199
client/key/vim/index.js Normal file
View file

@ -0,0 +1,199 @@
'use strict';
/* global CloudCmd, DOM */
const KEY = require('../key');
const Info = DOM.CurrentInfo;
const Dialog = DOM.Dialog;
const fullstore = require('fullstore/legacy');
const store = fullstore('');
const visual = fullstore(false);
const {
find,
findNext,
findPrevious,
} = require('./find');
const TITLE = 'Cloud Commander';
const stopVisual = () => {
visual(false);
};
const end = () => {
store('');
};
const rmFirst = (a) => {
return a
.split('')
.slice(1)
.join('');
};
module.exports = (key, event) => {
const current = Info.element;
const keyCode = event.keyCode;
const prevStore = store();
const value = store(prevStore.concat(key));
if (keyCode === KEY.ENTER)
return end();
if (keyCode === KEY.ESC) {
DOM.unselectFiles();
visual(false);
return end();
}
if (key === 'j') {
move('next', {
prevStore,
current,
});
return end();
}
if (key === 'k') {
move('previous', {
prevStore,
current,
});
return end();
}
if (/gg/.test(value)) {
move('previous', {
current,
prevStore,
max: Infinity,
});
return end();
}
if (key === 'd' && (visual() || prevStore === 'd')) {
CloudCmd.Operation.show('delete');
stopVisual();
return end();
}
if (key === 'G') {
move('next', {
current,
prevStore,
max: Infinity,
});
return end();
}
if (key === 'y') {
if (!visual())
return end();
DOM.Buffer.copy();
stopVisual();
DOM.unselectFiles();
return end();
}
if (/^p$/i.test(key)) {
DOM.Buffer.paste();
return end();
}
if (/^v$/i.test(key)) {
DOM.toggleSelectedFile(current);
visual(!visual());
return end();
}
if (key === '/') {
event.preventDefault();
Dialog.prompt(TITLE, 'Find', '', {cancel: false})
.then(find);
return end();
}
if (key === 'n') {
findNext();
return end();
}
if (key === 'N') {
findPrevious();
return end();
}
};
module.exports.selectFile = selectFile;
function move(sibling, {max, current, prevStore}) {
const isDelete = prevStore[0] === 'd';
if (isDelete) {
visual(true);
prevStore = rmFirst(prevStore);
}
const n = max || getNumber(prevStore);
if (isNaN(n))
return;
setCurrent({
n,
current,
sibling,
visual: visual(),
});
if (isDelete)
CloudCmd.Operation.show('delete');
}
function getNumber(value) {
if (!value)
return 1;
if (value === 'g')
return 1;
return parseInt(value);
}
function selectFile(current) {
const name = DOM.getCurrentName(current);
if (name === '..')
return;
DOM.selectFile(current);
}
function setCurrent({n, current, visual, sibling}) {
const select = visual ? selectFile : DOM.unselectFile;
select(current);
const position = `${sibling}Sibling`;
for (let i = 0; i < n; i++) {
const next = current[position];
if (!next)
break;
current = next;
select(current);
}
DOM.setCurrentFile(current);
}