Skip to content

Commit

Permalink
Implement rot13 cypher (#179)
Browse files Browse the repository at this point in the history
* implement rot13 cypher

* added tests

* fix one testcase

* fix g? testcase
  • Loading branch information
Opisek authored Oct 25, 2024
1 parent 160a7fd commit 4af5537
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 1 deletion.
33 changes: 32 additions & 1 deletion src/vim.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ export function initVim(CodeMirror) {
{ keys: 'gN', type: 'motion', motion: 'findAndSelectNextInclusive', motionArgs: { forward: false }},
{ keys: 'gq', type: 'operator', operator: 'hardWrap' },
{ keys: 'gw', type: 'operator', operator: 'hardWrap', operatorArgs: {keepCursor: true}},
{ keys: 'g?', type: 'operator', operator: 'rot13'},
// Operator-Motion dual commands
{ keys: 'x', type: 'operatorMotion', operator: 'delete', motion: 'moveByCharacters', motionArgs: { forward: true }, operatorMotionArgs: { visualLine: false }},
{ keys: 'X', type: 'operatorMotion', operator: 'delete', motion: 'moveByCharacters', motionArgs: { forward: false }, operatorMotionArgs: { visualLine: true }},
Expand Down Expand Up @@ -2729,7 +2730,37 @@ export function initVim(CodeMirror) {
args.registerName, 'yank',
text, args.linewise, vim.visualBlock);
return endPos;
}
},
rot13: function(cm, args, ranges, oldAnchor, newHead) {
var selections = cm.getSelections();
var swapped = [];
for (var j = 0; j < selections.length; j++) {
const replacement = selections[j]
.split('')
.map(x => {
const code = x.charCodeAt(0);
if (code >= 65 && code <= 90) { // Uppercase
return String.fromCharCode(65 + ((code - 65 + 13) % 26))
} else if (code >= 97 && code <= 122) { // Lowercase
return String.fromCharCode(97 + ((code - 97 + 13) % 26))
} else { // Not a letter
return x;
}
})
.join('')
swapped.push(replacement);
}
cm.replaceSelections(swapped);
if (args.shouldMoveCursor){
return newHead;
} else if (!cm.state.vim.visualMode && args.linewise && ranges[0].anchor.line + 1 == ranges[0].head.line) {
return motions.moveToFirstNonWhiteSpaceCharacter(cm, oldAnchor);
} else if (args.linewise){
return oldAnchor;
} else {
return cursorMin(ranges[0].anchor, ranges[0].head);
}
},
};

/** @arg {string} name @arg {import("./types").OperatorFn} fn */
Expand Down
38 changes: 38 additions & 0 deletions test/vim_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1386,6 +1386,44 @@ testVim('gu_and_gU', function(cm, vim, helpers) {
helpers.doKeys('g', 'U', '2', 'U');
eq(cm.getValue(), 'ABC EFG\nXYZ');
}, { value: 'wa wb xx wc wd' });
testVim('g?', function(cm, vim, helpers) {
var curStart = makeCursor(0, 7);
var value = cm.getValue();
cm.setCursor(curStart);
helpers.doKeys('2', 'g', '?', 'w');
eq(cm.getValue(), 'wa wb xk jp wd');
eqCursorPos(curStart, cm.getCursor());
helpers.doKeys('2', 'g', '?', 'w');
eq(cm.getValue(), value);

helpers.doKeys('2', 'g', '?', 'B');
eq(cm.getValue(), 'wa jo kx wc wd');
eqCursorPos(makeCursor(0, 3), cm.getCursor());

cm.setCursor(makeCursor(0, 4));
helpers.doKeys('g', '?', 'i', 'w');
eq(cm.getValue(), 'wa wb kx wc wd');
eqCursorPos(makeCursor(0, 3), cm.getCursor());

var register = helpers.getRegisterController().getRegister();
eq('', register.toString());
is(!register.linewise);

cm.setCursor(curStart);
cm.setValue('abc efg();\nxyz');
helpers.doKeys('g', '?', 'g', '?');
eq(cm.getValue(), 'nop rst();\nxyz');
helpers.doKeys('g', '?', '?');
eq(cm.getValue(), 'abc efg();\nxyz');
eqCursorPos(makeCursor(0, 0), cm.getCursor());
helpers.doKeys('g', '?', '2', '?');
eq(cm.getValue(), 'nop rst();\nklm');

cm.setCursor(curStart);
cm.setValue('hello\nworld');
helpers.doKeys('l','<C-v>','l','j','g','?');
eq(cm.getValue(), 'hrylo\nwbeld');
}, { value: 'wa wb xx wc wd' });
testVim('visual_block_~', function(cm, vim, helpers) {
cm.setCursor(1, 1);
helpers.doKeys('<C-v>', 'l', 'l', 'j', '~');
Expand Down

0 comments on commit 4af5537

Please sign in to comment.