Skip to content

Commit

Permalink
feature(vim) add find support with: "/", "n" and "N"
Browse files Browse the repository at this point in the history
  • Loading branch information
coderaiser committed Sep 11, 2017
1 parent 3693f6f commit 2edf7f8
Show file tree
Hide file tree
Showing 7 changed files with 269 additions and 29 deletions.
3 changes: 3 additions & 0 deletions HELP.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,9 @@ When `--vim` option provided, or configuration parameter `vim` set, next hot key
| `y` | copy (selected in visual mode files)
| `p` | paste files
| `Esc` | unselect all
| `/` | find file in current directory
| `n` | navigate to next found file
| `N` | navigate to previous found file

Commands can be joined, for example:
- `5j` will navigate `5` files below current;
Expand Down
53 changes: 53 additions & 0 deletions client/key/vim/find.js
Original file line number Diff line number Diff line change
@@ -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;
}

29 changes: 28 additions & 1 deletion client/key/vim.js → client/key/vim/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
'use strict';
/* global CloudCmd, DOM */

const KEY = require('../key');
const Info = DOM.CurrentInfo;
const KEY = require('./key');
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);
Expand Down Expand Up @@ -104,6 +112,25 @@ module.exports = (key, event) => {

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;
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@
"version-io": "^2.0.1",
"webpack": "^3.0.0",
"wraptile": "^1.0.0",
"yaspeller": "^4.0.0"
"yaspeller": "^4.0.0",
"limier": "^1.0.1"
},
"engines": {
"node": ">=4.0.0"
Expand Down
79 changes: 79 additions & 0 deletions test/client/key/vim/find.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
'use strict';

const test = require('tape');
const diff = require('sinon-called-with-diff');
const sinon = diff(require('sinon'));
const dir = '../../../../client/key/vim/';

const {
getDOM,
getCloudCmd,
} = require('./globals');

global.DOM = global.DOM || getDOM();
global.CloudCmd = global.CloudCmd || getCloudCmd();

const DOM = global.DOM
const CloudCmd = global.CloudCmd;

const {
find,
findNext,
findPrevious,
_next,
_previous,
} = require(dir + 'find');

test('cloudcmd: client: vim: find', (t) => {
const setCurrentByName = sinon.stub();
DOM.setCurrentByName = setCurrentByName;
DOM.Dialog.prompt = Promise.resolve.bind(Promise);

find('');

t.ok(setCurrentByName.calledWith(), 'should call setCurrentByName');
t.end();
});

test('cloudcmd: client: vim: findNext', (t) => {
const setCurrentByName = sinon.stub();
DOM.setCurrentByName = setCurrentByName;

findNext();

t.ok(setCurrentByName.calledWith(), 'should call setCurrentByName');
t.end();
});

test('cloudcmd: client: vim: findPrevious', (t) => {
const setCurrentByName = sinon.stub();
DOM.setCurrentByName = setCurrentByName;

findPrevious();

t.ok(setCurrentByName.calledWith(), 'should call setCurrentByName');
t.end();
});

test('cloudcmd: client: vim: _next', (t) => {
const result = _next(1, 2)

t.notOk(result, 'should return 0');
t.end();
});

test('cloudcmd: client: vim: _previous', (t) => {
const result = _previous(0, 2)

t.equal(result, 1, 'should return 1');
t.end();
});

function clean(path) {
delete require.cache[require.resolve(path)];
}

function stub(name, fn) {
require.cache[require.resolve(name)].exports = fn;
}

43 changes: 43 additions & 0 deletions test/client/key/vim/globals.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
'use strict';

module.exports.getDOM = () => {
const resolve = Promise.resolve.bind(Promise);
const CurrentInfo = {
element: {},
files: [],
};

const noop = () => {};
const Buffer = {
copy: noop,
paste: noop,
};

const Dialog = {
prompt: resolve
};

return {
Buffer,
CurrentInfo,
Dialog,
selectFile: noop,
unselectFile: noop,
unselectFiles: noop,
setCurrentFile: noop,
getCurrentName: noop,
setCurrentByName: noop,
toggleSelectedFile: noop,
};
};

module.exports.getCloudCmd = () => {
const show = () => {};

return {
Operation: {
show
}
};
};

88 changes: 61 additions & 27 deletions test/client/key/vim.js → test/client/key/vim/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@
const test = require('tape');
const diff = require('sinon-called-with-diff');
const sinon = diff(require('sinon'));
const dir = '../../../client/key/';
const dir = '../../../../client/key/';
const KEY = require(dir + 'key');

initGlobals();
const {
getDOM,
getCloudCmd,
} = require('./globals');

global.DOM = global.DOM || getDOM();
global.CloudCmd = global.CloudCmd || getCloudCmd();

const DOM = global.DOM;
const Buffer = DOM.Buffer;
Expand Down Expand Up @@ -349,8 +355,8 @@ test('cloudcmd: client: key: Enter', (t) => {

const setCurrentFile = sinon.stub();

global.DOM.CurrentInfo.element = element;
global.DOM.setCurrentFile = setCurrentFile;
DOM.CurrentInfo.element = element;
DOM.setCurrentFile = setCurrentFile;

vim('', {
keyCode: KEY.ENTER
Expand All @@ -363,32 +369,60 @@ test('cloudcmd: client: key: Enter', (t) => {
t.end();
});

function initGlobals() {
const CurrentInfo = {
element: {},
};
test('cloudcmd: client: key: /', (t) => {
const preventDefault = sinon.stub();
const element = {};

const noop = () => {};
const Buffer = {
copy: noop,
};
DOM.CurrentInfo.element = element;
DOM.getCurrentName = () => '';

global.DOM = {
Buffer,
CurrentInfo,
selectFile: noop,
unselectFile: noop,
unselectFiles: noop,
setCurrentFile: noop,
toggleSelectedFile: noop,
};
vim('/', {
preventDefault
});

const show = () => {};
t.ok(preventDefault.calledWith(), 'should call preventDefault');
t.end();
});

test('cloudcmd: client: key: n', (t) => {
const findNext = sinon.stub();

global.CloudCmd = {
Operation: {
show
}
};
clean(dir + 'vim');
stub(dir + 'vim/find', {
findNext
});

const vim = require(dir + 'vim');
const event = {};

vim('n', event);

t.ok(findNext.calledWith(), 'should call findNext');
t.end();
});

test('cloudcmd: client: key: N', (t) => {
const findPrevious = sinon.stub();

clean(dir + 'vim');
stub(dir + 'vim/find', {
findPrevious,
});

const vim = require(dir + 'vim');
const event = {};

vim('N', event);

t.ok(findPrevious.calledWith(), 'should call findPrevious');
t.end();
});

function clean(path) {
delete require.cache[require.resolve(path)];
}

function stub(name, fn) {
require.cache[require.resolve(name)].exports = fn;
}

0 comments on commit 2edf7f8

Please sign in to comment.