From bd0b75158da8de50d038dd51306fcfc05fd4dce2 Mon Sep 17 00:00:00 2001 From: Kevin Wu Date: Wed, 4 Dec 2019 01:37:28 -0800 Subject: [PATCH 1/7] Add Search Functionality. 'recording-macro' is moved to the atom-workspace classList because input can occur in a separate editor during search. Co-Authored-By: compostbrain --- README.md | 9 +- keymaps/macro-keymap.cson | 218 ++++++++++++++++++------------------ lib/vim-mode-plus-macros.js | 110 +++++++++++------- 3 files changed, 189 insertions(+), 148 deletions(-) diff --git a/README.md b/README.md index b8d05ca..94edf19 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,15 @@ # Macros for vim mode plus -This package is still under construction, but the basic functionality works. You can create a single macro and apply it many times. -Searching with `/` definitely doesn't work yet. +This package is still under construction, but the basic functionality works. You can create a single macro and apply it many times. ## Install + `apm install vim-mode-plus-macros` at the command line, or `ctrl-,`, click on install, then type vim-mode-plus-macros and click install. Make sure you also have vim-mode-plus installed, this package requires it. ## Usage + `q` in normal mode to start recording a macro `q` in normal mode while recording a macro to stop recording the macro @@ -16,10 +17,14 @@ Make sure you also have vim-mode-plus installed, this package requires it. `@` to apply the macro ## Roadmap + - [x] a macro can be recorded - [x] a macro can be replayed - [x] macros can include typing in insert mode - [x] indicate macro recording state to user +- [x] add searching with '/' +- [ ] allow prefixing with number to replay +- [ ] add searching with 'f', 'F', 't', 'T' - [ ] macros can be saved to (and recalled from) the 26 letters (e.g. `qa` and `@a`) - [ ] macros can be named and saved (maybe use a fuzzy finder?) - [ ] specs diff --git a/keymaps/macro-keymap.cson b/keymaps/macro-keymap.cson index 021ffa8..c53e511 100644 --- a/keymaps/macro-keymap.cson +++ b/keymaps/macro-keymap.cson @@ -2,112 +2,116 @@ 'q': 'vim-mode-plus-macros:start-recording-macro' '@': 'vim-mode-plus-macros:apply-macro' -'atom-text-editor.vim-mode-plus.normal-mode.recording-macro': +'atom-workspace.recording-macro atom-text-editor.vim-mode-plus.normal-mode': 'q': 'vim-mode-plus-macros:stop-recording-macro' -'atom-text-editor.vim-mode-plus.insert-mode.recording-macro': - 'space': 'vim-mode-plus-macros:record-insert-of-space' - '!': 'vim-mode-plus-macros:record-insert-of-!' - '"': 'vim-mode-plus-macros:record-insert-of-"' - '#': 'vim-mode-plus-macros:record-insert-of-#' - '$': 'vim-mode-plus-macros:record-insert-of-$' - '%': 'vim-mode-plus-macros:record-insert-of-%' - '&': 'vim-mode-plus-macros:record-insert-of-&' - '\'': 'vim-mode-plus-macros:record-insert-of-\'' - '(': 'vim-mode-plus-macros:record-insert-of-(' - ')': 'vim-mode-plus-macros:record-insert-of-)' - '*': 'vim-mode-plus-macros:record-insert-of-*' - '+': 'vim-mode-plus-macros:record-insert-of-+' - ',': 'vim-mode-plus-macros:record-insert-of-,' - '-': 'vim-mode-plus-macros:record-insert-of--' - '.': 'vim-mode-plus-macros:record-insert-of-.' - '/': 'vim-mode-plus-macros:record-insert-of-/' - '0': 'vim-mode-plus-macros:record-insert-of-0' - '1': 'vim-mode-plus-macros:record-insert-of-1' - '2': 'vim-mode-plus-macros:record-insert-of-2' - '3': 'vim-mode-plus-macros:record-insert-of-3' - '4': 'vim-mode-plus-macros:record-insert-of-4' - '5': 'vim-mode-plus-macros:record-insert-of-5' - '6': 'vim-mode-plus-macros:record-insert-of-6' - '7': 'vim-mode-plus-macros:record-insert-of-7' - '8': 'vim-mode-plus-macros:record-insert-of-8' - '9': 'vim-mode-plus-macros:record-insert-of-9' - 'numpad0': 'vim-mode-plus-macros:record-insert-of-0' - 'numpad1': 'vim-mode-plus-macros:record-insert-of-1' - 'numpad2': 'vim-mode-plus-macros:record-insert-of-2' - 'numpad3': 'vim-mode-plus-macros:record-insert-of-3' - 'numpad4': 'vim-mode-plus-macros:record-insert-of-4' - 'numpad5': 'vim-mode-plus-macros:record-insert-of-5' - 'numpad6': 'vim-mode-plus-macros:record-insert-of-6' - 'numpad7': 'vim-mode-plus-macros:record-insert-of-7' - 'numpad8': 'vim-mode-plus-macros:record-insert-of-8' - 'numpad9': 'vim-mode-plus-macros:record-insert-of-9' - ':': 'vim-mode-plus-macros:record-insert-of-:' - ';': 'vim-mode-plus-macros:record-insert-of-;' - '<': 'vim-mode-plus-macros:record-insert-of-<' - '=': 'vim-mode-plus-macros:record-insert-of-=' - '>': 'vim-mode-plus-macros:record-insert-of->' - '?': 'vim-mode-plus-macros:record-insert-of-?' - '@': 'vim-mode-plus-macros:record-insert-of-@' - 'A': 'vim-mode-plus-macros:record-insert-of-A' - 'B': 'vim-mode-plus-macros:record-insert-of-B' - 'C': 'vim-mode-plus-macros:record-insert-of-C' - 'D': 'vim-mode-plus-macros:record-insert-of-D' - 'E': 'vim-mode-plus-macros:record-insert-of-E' - 'F': 'vim-mode-plus-macros:record-insert-of-F' - 'G': 'vim-mode-plus-macros:record-insert-of-G' - 'H': 'vim-mode-plus-macros:record-insert-of-H' - 'I': 'vim-mode-plus-macros:record-insert-of-I' - 'J': 'vim-mode-plus-macros:record-insert-of-J' - 'K': 'vim-mode-plus-macros:record-insert-of-K' - 'L': 'vim-mode-plus-macros:record-insert-of-L' - 'M': 'vim-mode-plus-macros:record-insert-of-M' - 'N': 'vim-mode-plus-macros:record-insert-of-N' - 'O': 'vim-mode-plus-macros:record-insert-of-O' - 'P': 'vim-mode-plus-macros:record-insert-of-P' - 'Q': 'vim-mode-plus-macros:record-insert-of-Q' - 'R': 'vim-mode-plus-macros:record-insert-of-R' - 'S': 'vim-mode-plus-macros:record-insert-of-S' - 'T': 'vim-mode-plus-macros:record-insert-of-T' - 'U': 'vim-mode-plus-macros:record-insert-of-U' - 'V': 'vim-mode-plus-macros:record-insert-of-V' - 'W': 'vim-mode-plus-macros:record-insert-of-W' - 'X': 'vim-mode-plus-macros:record-insert-of-X' - 'Y': 'vim-mode-plus-macros:record-insert-of-Y' - 'Z': 'vim-mode-plus-macros:record-insert-of-Z' - '[': 'vim-mode-plus-macros:record-insert-of-[' - '\\': 'vim-mode-plus-macros:record-insert-of-\\' - ']': 'vim-mode-plus-macros:record-insert-of-]' - '^': 'vim-mode-plus-macros:record-insert-of-^' - '_': 'vim-mode-plus-macros:record-insert-of-_' - '`': 'vim-mode-plus-macros:record-insert-of-`' - 'a': 'vim-mode-plus-macros:record-insert-of-a' - 'b': 'vim-mode-plus-macros:record-insert-of-b' - 'c': 'vim-mode-plus-macros:record-insert-of-c' - 'd': 'vim-mode-plus-macros:record-insert-of-d' - 'e': 'vim-mode-plus-macros:record-insert-of-e' - 'f': 'vim-mode-plus-macros:record-insert-of-f' - 'g': 'vim-mode-plus-macros:record-insert-of-g' - 'h': 'vim-mode-plus-macros:record-insert-of-h' - 'i': 'vim-mode-plus-macros:record-insert-of-i' - 'j': 'vim-mode-plus-macros:record-insert-of-j' - 'k': 'vim-mode-plus-macros:record-insert-of-k' - 'l': 'vim-mode-plus-macros:record-insert-of-l' - 'm': 'vim-mode-plus-macros:record-insert-of-m' - 'n': 'vim-mode-plus-macros:record-insert-of-n' - 'o': 'vim-mode-plus-macros:record-insert-of-o' - 'p': 'vim-mode-plus-macros:record-insert-of-p' - 'q': 'vim-mode-plus-macros:record-insert-of-q' - 'r': 'vim-mode-plus-macros:record-insert-of-r' - 's': 'vim-mode-plus-macros:record-insert-of-s' - 't': 'vim-mode-plus-macros:record-insert-of-t' - 'u': 'vim-mode-plus-macros:record-insert-of-u' - 'v': 'vim-mode-plus-macros:record-insert-of-v' - 'w': 'vim-mode-plus-macros:record-insert-of-w' - 'x': 'vim-mode-plus-macros:record-insert-of-x' - 'y': 'vim-mode-plus-macros:record-insert-of-y' - 'z': 'vim-mode-plus-macros:record-insert-of-z' - '{': 'vim-mode-plus-macros:record-insert-of-{' - '|': 'vim-mode-plus-macros:record-insert-of-|' - '}': 'vim-mode-plus-macros:record-insert-of-}' - '~': 'vim-mode-plus-macros:record-insert-of-~' +# 'atom-text-editor.vim-mode-plus-input.find': +# 'e': 'vim-mode-plus-macros:record-insert-of-e-find' + +'atom-workspace.recording-macro atom-text-editor.vim-mode-plus.insert-mode, \ + atom-workspace.recording-macro atom-text-editor.vim-mode-plus-search': + 'space': 'vim-mode-plus-macros:insert-of-space' + '!': 'vim-mode-plus-macros:insert-of-!' + '"': 'vim-mode-plus-macros:insert-of-"' + '#': 'vim-mode-plus-macros:insert-of-#' + '$': 'vim-mode-plus-macros:insert-of-$' + '%': 'vim-mode-plus-macros:insert-of-%' + '&': 'vim-mode-plus-macros:insert-of-&' + '\'': 'vim-mode-plus-macros:insert-of-\'' + '(': 'vim-mode-plus-macros:insert-of-(' + ')': 'vim-mode-plus-macros:insert-of-)' + '*': 'vim-mode-plus-macros:insert-of-*' + '+': 'vim-mode-plus-macros:insert-of-+' + ',': 'vim-mode-plus-macros:insert-of-,' + '-': 'vim-mode-plus-macros:insert-of--' + '.': 'vim-mode-plus-macros:insert-of-.' + '/': 'vim-mode-plus-macros:insert-of-/' + '0': 'vim-mode-plus-macros:insert-of-0' + '1': 'vim-mode-plus-macros:insert-of-1' + '2': 'vim-mode-plus-macros:insert-of-2' + '3': 'vim-mode-plus-macros:insert-of-3' + '4': 'vim-mode-plus-macros:insert-of-4' + '5': 'vim-mode-plus-macros:insert-of-5' + '6': 'vim-mode-plus-macros:insert-of-6' + '7': 'vim-mode-plus-macros:insert-of-7' + '8': 'vim-mode-plus-macros:insert-of-8' + '9': 'vim-mode-plus-macros:insert-of-9' + 'numpad0': 'vim-mode-plus-macros:insert-of-0' + 'numpad1': 'vim-mode-plus-macros:insert-of-1' + 'numpad2': 'vim-mode-plus-macros:insert-of-2' + 'numpad3': 'vim-mode-plus-macros:insert-of-3' + 'numpad4': 'vim-mode-plus-macros:insert-of-4' + 'numpad5': 'vim-mode-plus-macros:insert-of-5' + 'numpad6': 'vim-mode-plus-macros:insert-of-6' + 'numpad7': 'vim-mode-plus-macros:insert-of-7' + 'numpad8': 'vim-mode-plus-macros:insert-of-8' + 'numpad9': 'vim-mode-plus-macros:insert-of-9' + ':': 'vim-mode-plus-macros:insert-of-:' + ';': 'vim-mode-plus-macros:insert-of-;' + '<': 'vim-mode-plus-macros:insert-of-<' + '=': 'vim-mode-plus-macros:insert-of-=' + '>': 'vim-mode-plus-macros:insert-of->' + '?': 'vim-mode-plus-macros:insert-of-?' + '@': 'vim-mode-plus-macros:insert-of-@' + 'A': 'vim-mode-plus-macros:insert-of-A' + 'B': 'vim-mode-plus-macros:insert-of-B' + 'C': 'vim-mode-plus-macros:insert-of-C' + 'D': 'vim-mode-plus-macros:insert-of-D' + 'E': 'vim-mode-plus-macros:insert-of-E' + 'F': 'vim-mode-plus-macros:insert-of-F' + 'G': 'vim-mode-plus-macros:insert-of-G' + 'H': 'vim-mode-plus-macros:insert-of-H' + 'I': 'vim-mode-plus-macros:insert-of-I' + 'J': 'vim-mode-plus-macros:insert-of-J' + 'K': 'vim-mode-plus-macros:insert-of-K' + 'L': 'vim-mode-plus-macros:insert-of-L' + 'M': 'vim-mode-plus-macros:insert-of-M' + 'N': 'vim-mode-plus-macros:insert-of-N' + 'O': 'vim-mode-plus-macros:insert-of-O' + 'P': 'vim-mode-plus-macros:insert-of-P' + 'Q': 'vim-mode-plus-macros:insert-of-Q' + 'R': 'vim-mode-plus-macros:insert-of-R' + 'S': 'vim-mode-plus-macros:insert-of-S' + 'T': 'vim-mode-plus-macros:insert-of-T' + 'U': 'vim-mode-plus-macros:insert-of-U' + 'V': 'vim-mode-plus-macros:insert-of-V' + 'W': 'vim-mode-plus-macros:insert-of-W' + 'X': 'vim-mode-plus-macros:insert-of-X' + 'Y': 'vim-mode-plus-macros:insert-of-Y' + 'Z': 'vim-mode-plus-macros:insert-of-Z' + '[': 'vim-mode-plus-macros:insert-of-[' + '\\': 'vim-mode-plus-macros:insert-of-\\' + ']': 'vim-mode-plus-macros:insert-of-]' + '^': 'vim-mode-plus-macros:insert-of-^' + '_': 'vim-mode-plus-macros:insert-of-_' + '`': 'vim-mode-plus-macros:insert-of-`' + 'a': 'vim-mode-plus-macros:insert-of-a' + 'b': 'vim-mode-plus-macros:insert-of-b' + 'c': 'vim-mode-plus-macros:insert-of-c' + 'd': 'vim-mode-plus-macros:insert-of-d' + 'e': 'vim-mode-plus-macros:insert-of-e' + 'f': 'vim-mode-plus-macros:insert-of-f' + 'g': 'vim-mode-plus-macros:insert-of-g' + 'h': 'vim-mode-plus-macros:insert-of-h' + 'i': 'vim-mode-plus-macros:insert-of-i' + 'j': 'vim-mode-plus-macros:insert-of-j' + 'k': 'vim-mode-plus-macros:insert-of-k' + 'l': 'vim-mode-plus-macros:insert-of-l' + 'm': 'vim-mode-plus-macros:insert-of-m' + 'n': 'vim-mode-plus-macros:insert-of-n' + 'o': 'vim-mode-plus-macros:insert-of-o' + 'p': 'vim-mode-plus-macros:insert-of-p' + 'q': 'vim-mode-plus-macros:insert-of-q' + 'r': 'vim-mode-plus-macros:insert-of-r' + 's': 'vim-mode-plus-macros:insert-of-s' + 't': 'vim-mode-plus-macros:insert-of-t' + 'u': 'vim-mode-plus-macros:insert-of-u' + 'v': 'vim-mode-plus-macros:insert-of-v' + 'w': 'vim-mode-plus-macros:insert-of-w' + 'x': 'vim-mode-plus-macros:insert-of-x' + 'y': 'vim-mode-plus-macros:insert-of-y' + 'z': 'vim-mode-plus-macros:insert-of-z' + '{': 'vim-mode-plus-macros:insert-of-{' + '|': 'vim-mode-plus-macros:insert-of-|' + '}': 'vim-mode-plus-macros:insert-of-}' + '~': 'vim-mode-plus-macros:insert-of-~' diff --git a/lib/vim-mode-plus-macros.js b/lib/vim-mode-plus-macros.js index c2be259..09802f2 100644 --- a/lib/vim-mode-plus-macros.js +++ b/lib/vim-mode-plus-macros.js @@ -1,11 +1,12 @@ /** @babel */ -import { CompositeDisposable } from 'atom' +import { CompositeDisposable } from "atom"; -let commandQueue = [] -let recording = false +let commandQueue = []; +let recording = false; -// all the characters we record keypresses of +// All the characters we record keypresses of +// prettier-ignore const characters = [ 'space', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', @@ -16,68 +17,99 @@ const characters = [ 'y', 'z', '{', '|', '}', '~' ] +const ignoredCommands = new Set([ + "vim-mode-plus-macros:start-recording-macro", + "vim-mode-plus-macros:apply-macro", + "vim-mode-plus-macros:start-recording-macro" +]); + export default { activate(_state) { // Events subscribed to in atom's system can be easily cleaned up with a CompositeDisposable - this.subscriptions = new CompositeDisposable() + this.subscriptions = new CompositeDisposable(); const convertToCommand = (accumulator, character) => { - const actualCharacter = character === 'space' ? ' ' : character - accumulator[`vim-mode-plus-macros:record-insert-of-${character}`] = () => this.typeCharacter(actualCharacter) - return accumulator - } - const characterCommands = characters.reduce(convertToCommand, {}) + const actualCharacter = character === "space" ? " " : character; + accumulator[`vim-mode-plus-macros:insert-of-${character}`] = () => + this.typeCharacter(actualCharacter); + return accumulator; + }; + const characterCommands = characters.reduce(convertToCommand, {}); - this.subscriptions.add(atom.commands.add('atom-workspace', Object.assign(characterCommands, { - 'vim-mode-plus-macros:start-recording-macro': () => this.startRecordingMacro(), - 'vim-mode-plus-macros:stop-recording-macro': () => this.stopRecordingMacro(), - 'vim-mode-plus-macros:apply-macro': () => this.applyMacro() - }))) + this.subscriptions.add( + atom.commands.add( + "atom-workspace", + Object.assign(characterCommands, { + "vim-mode-plus-macros:start-recording-macro": () => + this.startRecordingMacro(), + "vim-mode-plus-macros:stop-recording-macro": () => + this.stopRecordingMacro(), + "vim-mode-plus-macros:apply-macro": () => this.applyMacro() + }) + ) + ); - atom.commands.onDidDispatch(this.logCommand) + atom.commands.onDidDispatch(this.recordCommand); }, deactivate() { - this.subscriptions.dispose() + this.subscriptions.dispose(); }, startRecordingMacro() { - let editor = atom.views.getView(atom.workspace.getActiveTextEditor()) - editor.classList.add('recording-macro') - commandQueue = [] // empty the queue - recording = true - atom.notifications.addInfo('Recording macro') + let workspaceView = atom.views.getView(atom.workspace); + workspaceView.classList.add("recording-macro"); + commandQueue = []; // empty the queue + recording = true; + atom.notifications.addInfo("Recording macro"); }, stopRecordingMacro() { - let editor = atom.views.getView(atom.workspace.getActiveTextEditor()) - editor.classList.remove('recording-macro') - recording = false - atom.notifications.addInfo('Stopped recording macro') + let workspaceView = atom.views.getView(atom.workspace); + workspaceView.classList.remove("recording-macro"); + recording = false; + atom.notifications.addInfo("Stopped recording macro"); }, applyMacro() { - atom.notifications.addInfo('Applying macro') - let editor = atom.views.getView(atom.workspace.getActiveTextEditor()) - let cursor = editor.querySelector('.cursor') + atom.notifications.addInfo("Applying macro"); commandQueue.forEach(command => { - atom.commands.dispatch(cursor, command) - }) + atom.commands.dispatch(atom.views.getView(this.activeEditor()), command); + }); }, - logCommand(event) { + recordCommand(event) { if (!recording) { - return + return; } - const commandName = event.type - if (commandName === 'vim-mode-plus-macros:start-recording-macro') { - return + const commandName = event.type; + if (ignoredCommands.has(commandName)) { + return; } - commandQueue.push(commandName) + commandQueue.push(commandName); }, typeCharacter(character) { - let editor = atom.workspace.getActiveTextEditor() - editor.insertText(character) + let editor = this.activeEditor(); + editor.insertText(character); + }, + + // When Searching, getActiveTextEditor is incorrect. + // This function correctly returns the active Text Editor + activeEditor() { + let editor = atom.workspace.getActiveTextEditor(); + let editorView = atom.views.getView(editor); + const className = "vim-mode-plus-search-input-focused"; + if (editorView.classList.contains(className)) { + let allEditors = atom.textEditors.editorsWithMaintainedConfig; + allEditors.forEach(e => { + if (e.mini) { + editor = e; + editorView = atom.views.getView(e); + return false; + } + }); + } + return editor; } }; From 985ea95f918c8e968af7e16f149a627f69d8d3df Mon Sep 17 00:00:00 2001 From: Kevin Wu Date: Wed, 4 Dec 2019 02:03:29 -0800 Subject: [PATCH 2/7] Delete comment and unnecessary line of code --- keymaps/macro-keymap.cson | 3 --- lib/vim-mode-plus-macros.js | 1 - 2 files changed, 4 deletions(-) diff --git a/keymaps/macro-keymap.cson b/keymaps/macro-keymap.cson index c53e511..5d4c9de 100644 --- a/keymaps/macro-keymap.cson +++ b/keymaps/macro-keymap.cson @@ -5,9 +5,6 @@ 'atom-workspace.recording-macro atom-text-editor.vim-mode-plus.normal-mode': 'q': 'vim-mode-plus-macros:stop-recording-macro' -# 'atom-text-editor.vim-mode-plus-input.find': -# 'e': 'vim-mode-plus-macros:record-insert-of-e-find' - 'atom-workspace.recording-macro atom-text-editor.vim-mode-plus.insert-mode, \ atom-workspace.recording-macro atom-text-editor.vim-mode-plus-search': 'space': 'vim-mode-plus-macros:insert-of-space' diff --git a/lib/vim-mode-plus-macros.js b/lib/vim-mode-plus-macros.js index 09802f2..3473329 100644 --- a/lib/vim-mode-plus-macros.js +++ b/lib/vim-mode-plus-macros.js @@ -105,7 +105,6 @@ export default { allEditors.forEach(e => { if (e.mini) { editor = e; - editorView = atom.views.getView(e); return false; } }); From c8839389e61c3be59fcc4e8a535bfd5064fc1f9f Mon Sep 17 00:00:00 2001 From: Kevin Wu Date: Wed, 4 Dec 2019 02:37:14 -0800 Subject: [PATCH 3/7] Change 'let' to 'const' for unchanging variables. --- lib/vim-mode-plus-macros.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/vim-mode-plus-macros.js b/lib/vim-mode-plus-macros.js index 3473329..adad5eb 100644 --- a/lib/vim-mode-plus-macros.js +++ b/lib/vim-mode-plus-macros.js @@ -57,7 +57,7 @@ export default { }, startRecordingMacro() { - let workspaceView = atom.views.getView(atom.workspace); + const workspaceView = atom.views.getView(atom.workspace); workspaceView.classList.add("recording-macro"); commandQueue = []; // empty the queue recording = true; @@ -65,7 +65,7 @@ export default { }, stopRecordingMacro() { - let workspaceView = atom.views.getView(atom.workspace); + const workspaceView = atom.views.getView(atom.workspace); workspaceView.classList.remove("recording-macro"); recording = false; atom.notifications.addInfo("Stopped recording macro"); @@ -90,7 +90,7 @@ export default { }, typeCharacter(character) { - let editor = this.activeEditor(); + const editor = this.activeEditor(); editor.insertText(character); }, @@ -98,10 +98,10 @@ export default { // This function correctly returns the active Text Editor activeEditor() { let editor = atom.workspace.getActiveTextEditor(); - let editorView = atom.views.getView(editor); + const editorView = atom.views.getView(editor); const className = "vim-mode-plus-search-input-focused"; if (editorView.classList.contains(className)) { - let allEditors = atom.textEditors.editorsWithMaintainedConfig; + const allEditors = atom.textEditors.editorsWithMaintainedConfig; allEditors.forEach(e => { if (e.mini) { editor = e; From e94aedade93ebc7fe1c4ec15f9ba7e4d7f90d246 Mon Sep 17 00:00:00 2001 From: Kevin Wu Date: Wed, 11 Dec 2019 00:23:38 -0800 Subject: [PATCH 4/7] Add prefixing with a number to replay that many times --- README.md | 2 +- lib/vim-mode-plus-macros.js | 54 ++++++++++++++++++++++++++++++------- package.json | 9 ++++++- 3 files changed, 53 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 94edf19..98b5b2d 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Make sure you also have vim-mode-plus installed, this package requires it. - [x] macros can include typing in insert mode - [x] indicate macro recording state to user - [x] add searching with '/' -- [ ] allow prefixing with number to replay +- [x] allow prefixing with number to replay - [ ] add searching with 'f', 'F', 't', 'T' - [ ] macros can be saved to (and recalled from) the 26 letters (e.g. `qa` and `@a`) - [ ] macros can be named and saved (maybe use a fuzzy finder?) diff --git a/lib/vim-mode-plus-macros.js b/lib/vim-mode-plus-macros.js index adad5eb..8bfb6d5 100644 --- a/lib/vim-mode-plus-macros.js +++ b/lib/vim-mode-plus-macros.js @@ -24,7 +24,7 @@ const ignoredCommands = new Set([ ]); export default { - activate(_state) { + activate() { // Events subscribed to in atom's system can be easily cleaned up with a CompositeDisposable this.subscriptions = new CompositeDisposable(); @@ -43,8 +43,7 @@ export default { "vim-mode-plus-macros:start-recording-macro": () => this.startRecordingMacro(), "vim-mode-plus-macros:stop-recording-macro": () => - this.stopRecordingMacro(), - "vim-mode-plus-macros:apply-macro": () => this.applyMacro() + this.stopRecordingMacro() }) ) ); @@ -56,6 +55,48 @@ export default { this.subscriptions.dispose(); }, + consumeVim(service) { + class ApplyMacro extends service.getClass("MiscCommand") { + static commandPrefix = "vim-mode-plus-macros"; + + applyMacro(count) { + atom.notifications.addInfo("Applying macro"); + commandQueue.unshift("vim-mode-plus:reset-normal-mode"); + for (let i = 0; i < count; i++) { + commandQueue.forEach(command => { + atom.commands.dispatch( + atom.views.getView(this.activeEditor()), + command + ); + }); + } + } + + // When Searching, getActiveTextEditor is incorrect. + // This function correctly returns the active Text Editor + activeEditor() { + let editor = atom.workspace.getActiveTextEditor(); + const editorView = atom.views.getView(editor); + const className = "vim-mode-plus-search-input-focused"; + if (editorView.classList.contains(className)) { + const allEditors = atom.textEditors.editorsWithMaintainedConfig; + allEditors.forEach(e => { + if (e.mini) { + editor = e; + return false; + } + }); + } + return editor; + } + + execute() { + this.applyMacro(this.getCount()); + } + } + this.subscriptions.add(ApplyMacro.registerCommand()); + }, + startRecordingMacro() { const workspaceView = atom.views.getView(atom.workspace); workspaceView.classList.add("recording-macro"); @@ -71,13 +112,6 @@ export default { atom.notifications.addInfo("Stopped recording macro"); }, - applyMacro() { - atom.notifications.addInfo("Applying macro"); - commandQueue.forEach(command => { - atom.commands.dispatch(atom.views.getView(this.activeEditor()), command); - }); - }, - recordCommand(event) { if (!recording) { return; diff --git a/package.json b/package.json index 772e29d..5557c0d 100644 --- a/package.json +++ b/package.json @@ -16,5 +16,12 @@ "engines": { "atom": ">=1.0.0 <2.0.0" }, - "dependencies": {} + "dependencies": {}, + "consumedServices": { + "vim-mode-plus": { + "versions": { + "^0.1.0": "consumeVim" + } + } + } } From 5a6a5f9988f194280f20c0532f86665b0d485f6d Mon Sep 17 00:00:00 2001 From: Kevin Wu Date: Wed, 11 Dec 2019 03:06:54 -0800 Subject: [PATCH 5/7] Convert commands to Vim Mode Plus class based commands --- README.md | 1 + lib/main.js | 53 +++++++++++ lib/vim-mode-plus-macros.js | 153 ++++++++++++------------------ package.json | 2 +- spec/vim-mode-plus-macros-spec.js | 46 +++++---- 5 files changed, 145 insertions(+), 110 deletions(-) create mode 100644 lib/main.js diff --git a/README.md b/README.md index 98b5b2d..dc0442e 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ Make sure you also have vim-mode-plus installed, this package requires it. - [x] indicate macro recording state to user - [x] add searching with '/' - [x] allow prefixing with number to replay +- [ ] add undoing the entire macro in one undo - [ ] add searching with 'f', 'F', 't', 'T' - [ ] macros can be saved to (and recalled from) the 26 letters (e.g. `qa` and `@a`) - [ ] macros can be named and saved (maybe use a fuzzy finder?) diff --git a/lib/main.js b/lib/main.js new file mode 100644 index 0000000..47ae8dc --- /dev/null +++ b/lib/main.js @@ -0,0 +1,53 @@ +"use babel"; + +const { CompositeDisposable } = require("atom"); +const { + recordCommand, + typeCharacter, + loadVmpCommands +} = require("./vim-mode-plus-macros"); + +module.exports = { + activate() { + // Events subscribed to in atom's system can be easily cleaned up with a CompositeDisposable + this.subscriptions = new CompositeDisposable(); + + // All the characters we record keypresses of + // prettier-ignore + const characters = [ + 'space', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', + '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', + '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', + 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', + 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', + 'y', 'z', '{', '|', '}', '~' + ] + + const convertToCommand = (accumulator, character) => { + const actualCharacter = character === "space" ? " " : character; + accumulator[`vim-mode-plus-macros:insert-of-${character}`] = () => + typeCharacter(actualCharacter); + return accumulator; + }; + const characterCommands = characters.reduce(convertToCommand, {}); + + this.subscriptions.add( + atom.commands.add("atom-workspace", characterCommands) + ); + + atom.commands.onDidDispatch(recordCommand); + }, + + deactivate() { + this.subscriptions.dispose(); + }, + + consumeVim(service) { + const commands = loadVmpCommands(service); + for (const command of Object.values(commands)) { + command.commandPrefix = "vim-mode-plus-macros"; + this.subscriptions.add(command.registerCommand()); + } + } +}; diff --git a/lib/vim-mode-plus-macros.js b/lib/vim-mode-plus-macros.js index 8bfb6d5..82eec4e 100644 --- a/lib/vim-mode-plus-macros.js +++ b/lib/vim-mode-plus-macros.js @@ -5,60 +5,46 @@ import { CompositeDisposable } from "atom"; let commandQueue = []; let recording = false; -// All the characters we record keypresses of -// prettier-ignore -const characters = [ - 'space', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', - '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', - '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', - 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', - 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', - 'y', 'z', '{', '|', '}', '~' -] - -const ignoredCommands = new Set([ - "vim-mode-plus-macros:start-recording-macro", - "vim-mode-plus-macros:apply-macro", - "vim-mode-plus-macros:start-recording-macro" -]); - -export default { - activate() { - // Events subscribed to in atom's system can be easily cleaned up with a CompositeDisposable - this.subscriptions = new CompositeDisposable(); - - const convertToCommand = (accumulator, character) => { - const actualCharacter = character === "space" ? " " : character; - accumulator[`vim-mode-plus-macros:insert-of-${character}`] = () => - this.typeCharacter(actualCharacter); - return accumulator; - }; - const characterCommands = characters.reduce(convertToCommand, {}); - - this.subscriptions.add( - atom.commands.add( - "atom-workspace", - Object.assign(characterCommands, { - "vim-mode-plus-macros:start-recording-macro": () => - this.startRecordingMacro(), - "vim-mode-plus-macros:stop-recording-macro": () => - this.stopRecordingMacro() - }) - ) - ); +module.exports = { + recordCommand(event) { + if (!recording) { + return; + } + const ignoredCommands = new Set([ + "vim-mode-plus-macros:start-recording-macro", + "vim-mode-plus-macros:apply-macro", + "vim-mode-plus-macros:start-recording-macro" + ]); - atom.commands.onDidDispatch(this.recordCommand); + const commandName = event.type; + if (ignoredCommands.has(commandName)) { + return; + } + commandQueue.push(commandName); }, - deactivate() { - this.subscriptions.dispose(); + typeCharacter(character) { + let editor = atom.workspace.getActiveTextEditor(); + const editorView = atom.views.getView(editor); + const className = "vim-mode-plus-search-input-focused"; + if (editorView.classList.contains(className)) { + const allEditors = atom.textEditors.editorsWithMaintainedConfig; + allEditors.forEach(e => { + if (e.mini) { + editor = e; + return; + } + }); + } + editor.insertText(character); }, - consumeVim(service) { - class ApplyMacro extends service.getClass("MiscCommand") { - static commandPrefix = "vim-mode-plus-macros"; + // When Searching, getActiveTextEditor is incorrect. + // This function correctly returns the active Text Editor + activeEditor() {}, + loadVmpCommands({ Base }) { + class ApplyMacro extends Base.getClass("MiscCommand") { applyMacro(count) { atom.notifications.addInfo("Applying macro"); commandQueue.unshift("vim-mode-plus:reset-normal-mode"); @@ -94,55 +80,38 @@ export default { this.applyMacro(this.getCount()); } } - this.subscriptions.add(ApplyMacro.registerCommand()); - }, - - startRecordingMacro() { - const workspaceView = atom.views.getView(atom.workspace); - workspaceView.classList.add("recording-macro"); - commandQueue = []; // empty the queue - recording = true; - atom.notifications.addInfo("Recording macro"); - }, - stopRecordingMacro() { - const workspaceView = atom.views.getView(atom.workspace); - workspaceView.classList.remove("recording-macro"); - recording = false; - atom.notifications.addInfo("Stopped recording macro"); - }, + class StartRecordingMacro extends Base.getClass("MiscCommand") { + startRecordingMacro() { + const workspaceView = atom.views.getView(atom.workspace); + workspaceView.classList.add("recording-macro"); + commandQueue = []; // empty the queue + recording = true; + atom.notifications.addInfo("Recording macro"); + } - recordCommand(event) { - if (!recording) { - return; - } - const commandName = event.type; - if (ignoredCommands.has(commandName)) { - return; + execute() { + this.startRecordingMacro(); + } } - commandQueue.push(commandName); - }, - typeCharacter(character) { - const editor = this.activeEditor(); - editor.insertText(character); - }, + class StopRecordingMacro extends Base.getClass("MiscCommand") { + stopRecordingMacro() { + const workspaceView = atom.views.getView(atom.workspace); + workspaceView.classList.remove("recording-macro"); + recording = false; + atom.notifications.addInfo("Stopped recording macro"); + } - // When Searching, getActiveTextEditor is incorrect. - // This function correctly returns the active Text Editor - activeEditor() { - let editor = atom.workspace.getActiveTextEditor(); - const editorView = atom.views.getView(editor); - const className = "vim-mode-plus-search-input-focused"; - if (editorView.classList.contains(className)) { - const allEditors = atom.textEditors.editorsWithMaintainedConfig; - allEditors.forEach(e => { - if (e.mini) { - editor = e; - return false; - } - }); + execute() { + this.stopRecordingMacro(); + } } - return editor; + + return { + ApplyMacro, + StartRecordingMacro, + StopRecordingMacro + }; } }; diff --git a/package.json b/package.json index 5557c0d..fda38b6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vim-mode-plus-macros", - "main": "./lib/vim-mode-plus-macros", + "main": "./lib/main", "version": "0.1.2", "description": "Implements macros for vim mode plus", "keywords": [ diff --git a/spec/vim-mode-plus-macros-spec.js b/spec/vim-mode-plus-macros-spec.js index 57050e2..a15e431 100644 --- a/spec/vim-mode-plus-macros-spec.js +++ b/spec/vim-mode-plus-macros-spec.js @@ -1,48 +1,56 @@ -'use babel'; +"use babel"; -import VimModePlusMacros from '../lib/vim-mode-plus-macros'; +import VimModePlusMacros from "../lib/vim-mode-plus-macros"; // Use the command `window:run-package-specs` (cmd-alt-ctrl-p) to run specs. // // To run a specific `it` or `describe` block add an `f` to the front (e.g. `fit` // or `fdescribe`). Remove the `f` to unfocus the block. -describe('VimModePlusMacros', () => { +describe("VimModePlusMacros", () => { let workspaceElement, activationPromise; beforeEach(() => { workspaceElement = atom.views.getView(atom.workspace); - activationPromise = atom.packages.activatePackage('vim-mode-plus-macros'); + activationPromise = atom.packages.activatePackage("vim-mode-plus-macros"); }); - describe('when the vim-mode-plus-macros:toggle event is triggered', () => { - it('hides and shows the modal panel', () => { + describe("when the vim-mode-plus-macros:toggle event is triggered", () => { + it("hides and shows the modal panel", () => { // Before the activation event the view is not on the DOM, and no panel // has been created - expect(workspaceElement.querySelector('.vim-mode-plus-macros')).not.toExist(); + expect( + workspaceElement.querySelector(".vim-mode-plus-macros") + ).not.toExist(); // This is an activation event, triggering it will cause the package to be // activated. - atom.commands.dispatch(workspaceElement, 'vim-mode-plus-macros:toggle'); + atom.commands.dispatch(workspaceElement, "vim-mode-plus-macros:toggle"); waitsForPromise(() => { return activationPromise; }); runs(() => { - expect(workspaceElement.querySelector('.vim-mode-plus-macros')).toExist(); + expect( + workspaceElement.querySelector(".vim-mode-plus-macros") + ).toExist(); - let vimModePlusMacrosElement = workspaceElement.querySelector('.vim-mode-plus-macros'); + let vimModePlusMacrosElement = workspaceElement.querySelector( + ".vim-mode-plus-macros" + ); expect(vimModePlusMacrosElement).toExist(); - let vimModePlusMacrosPanel = atom.workspace.panelForItem(vimModePlusMacrosElement); + let vimModePlusMacrosPanel = atom.workspace.panelForItem( + vimModePlusMacrosElement + ); expect(vimModePlusMacrosPanel.isVisible()).toBe(true); - atom.commands.dispatch(workspaceElement, 'vim-mode-plus-macros:toggle'); + atom.commands.dispatch(workspaceElement, "vim-mode-plus-macros:toggle"); expect(vimModePlusMacrosPanel.isVisible()).toBe(false); }); }); - it('hides and shows the view', () => { + it("hides and shows the view", () => { // This test shows you an integration test testing at the view level. // Attaching the workspaceElement to the DOM is required to allow the @@ -51,11 +59,13 @@ describe('VimModePlusMacros', () => { // workspaceElement to the DOM are generally slower than those off DOM. jasmine.attachToDOM(workspaceElement); - expect(workspaceElement.querySelector('.vim-mode-plus-macros')).not.toExist(); + expect( + workspaceElement.querySelector(".vim-mode-plus-macros") + ).not.toExist(); // This is an activation event, triggering it causes the package to be // activated. - atom.commands.dispatch(workspaceElement, 'vim-mode-plus-macros:toggle'); + atom.commands.dispatch(workspaceElement, "vim-mode-plus-macros:toggle"); waitsForPromise(() => { return activationPromise; @@ -63,9 +73,11 @@ describe('VimModePlusMacros', () => { runs(() => { // Now we can test for view visibility - let vimModePlusMacrosElement = workspaceElement.querySelector('.vim-mode-plus-macros'); + let vimModePlusMacrosElement = workspaceElement.querySelector( + ".vim-mode-plus-macros" + ); expect(vimModePlusMacrosElement).toBeVisible(); - atom.commands.dispatch(workspaceElement, 'vim-mode-plus-macros:toggle'); + atom.commands.dispatch(workspaceElement, "vim-mode-plus-macros:toggle"); expect(vimModePlusMacrosElement).not.toBeVisible(); }); }); From cc87816c4424dad5ef8367be1844fd666465dc6a Mon Sep 17 00:00:00 2001 From: Kevin Wu Date: Thu, 12 Dec 2019 01:14:14 -0800 Subject: [PATCH 6/7] Move some logic to vim-mode-plus-macros and change the export style --- lib/main.js | 22 +--- lib/vim-mode-plus-macros.js | 198 +++++++++++++++++++----------------- 2 files changed, 103 insertions(+), 117 deletions(-) diff --git a/lib/main.js b/lib/main.js index 47ae8dc..ada796d 100644 --- a/lib/main.js +++ b/lib/main.js @@ -2,8 +2,8 @@ const { CompositeDisposable } = require("atom"); const { + characterCommands, recordCommand, - typeCharacter, loadVmpCommands } = require("./vim-mode-plus-macros"); @@ -12,26 +12,6 @@ module.exports = { // Events subscribed to in atom's system can be easily cleaned up with a CompositeDisposable this.subscriptions = new CompositeDisposable(); - // All the characters we record keypresses of - // prettier-ignore - const characters = [ - 'space', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', - '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', - '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', - 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', - 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', - 'y', 'z', '{', '|', '}', '~' - ] - - const convertToCommand = (accumulator, character) => { - const actualCharacter = character === "space" ? " " : character; - accumulator[`vim-mode-plus-macros:insert-of-${character}`] = () => - typeCharacter(actualCharacter); - return accumulator; - }; - const characterCommands = characters.reduce(convertToCommand, {}); - this.subscriptions.add( atom.commands.add("atom-workspace", characterCommands) ); diff --git a/lib/vim-mode-plus-macros.js b/lib/vim-mode-plus-macros.js index 82eec4e..daaa504 100644 --- a/lib/vim-mode-plus-macros.js +++ b/lib/vim-mode-plus-macros.js @@ -5,113 +5,119 @@ import { CompositeDisposable } from "atom"; let commandQueue = []; let recording = false; -module.exports = { - recordCommand(event) { - if (!recording) { - return; - } - const ignoredCommands = new Set([ - "vim-mode-plus-macros:start-recording-macro", - "vim-mode-plus-macros:apply-macro", - "vim-mode-plus-macros:start-recording-macro" - ]); - - const commandName = event.type; - if (ignoredCommands.has(commandName)) { - return; - } - commandQueue.push(commandName); - }, - - typeCharacter(character) { - let editor = atom.workspace.getActiveTextEditor(); - const editorView = atom.views.getView(editor); - const className = "vim-mode-plus-search-input-focused"; - if (editorView.classList.contains(className)) { - const allEditors = atom.textEditors.editorsWithMaintainedConfig; - allEditors.forEach(e => { - if (e.mini) { - editor = e; - return; - } - }); - } - editor.insertText(character); - }, - - // When Searching, getActiveTextEditor is incorrect. - // This function correctly returns the active Text Editor - activeEditor() {}, - - loadVmpCommands({ Base }) { - class ApplyMacro extends Base.getClass("MiscCommand") { - applyMacro(count) { - atom.notifications.addInfo("Applying macro"); - commandQueue.unshift("vim-mode-plus:reset-normal-mode"); - for (let i = 0; i < count; i++) { - commandQueue.forEach(command => { - atom.commands.dispatch( - atom.views.getView(this.activeEditor()), - command - ); - }); - } - } +// All the characters we record keypresses of +// prettier-ignore +const characters = [ + 'space', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', + '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', + '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', + 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', + 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', + 'y', 'z', '{', '|', '}', '~' +] + +const convertToCommand = (accumulator, character) => { + const actualCharacter = character === "space" ? " " : character; + accumulator[`vim-mode-plus-macros:insert-of-${character}`] = () => + typeCharacter(actualCharacter); + return accumulator; +}; +const characterCommands = characters.reduce(convertToCommand, {}); - // When Searching, getActiveTextEditor is incorrect. - // This function correctly returns the active Text Editor - activeEditor() { - let editor = atom.workspace.getActiveTextEditor(); - const editorView = atom.views.getView(editor); - const className = "vim-mode-plus-search-input-focused"; - if (editorView.classList.contains(className)) { - const allEditors = atom.textEditors.editorsWithMaintainedConfig; - allEditors.forEach(e => { - if (e.mini) { - editor = e; - return false; - } - }); - } - return editor; +function recordCommand(event) { + if (!recording) { + return; + } + const ignoredCommands = new Set([ + "vim-mode-plus-macros:start-recording-macro", + "vim-mode-plus-macros:apply-macro", + "vim-mode-plus-macros:start-recording-macro" + ]); + + const commandName = event.type; + if (ignoredCommands.has(commandName)) { + return; + } + commandQueue.push(commandName); +} + +function typeCharacter(character) { + const editor = activeEditor(); + editor.insertText(character); +} + +// When Searching, getActiveTextEditor is incorrect. +// This function correctly returns the active Text Editor +function activeEditor() { + let editor = atom.workspace.getActiveTextEditor(); + const editorView = atom.views.getView(editor); + const className = "vim-mode-plus-search-input-focused"; + if (editorView.classList.contains(className)) { + const allEditors = atom.textEditors.editorsWithMaintainedConfig; + allEditors.forEach(e => { + if (e.mini) { + editor = e; + return false; } + }); + } + return editor; +} - execute() { - this.applyMacro(this.getCount()); +function loadVmpCommands({ Base }) { + class ApplyMacro extends Base.getClass("MiscCommand") { + applyMacro(count) { + atom.notifications.addInfo("Applying macro"); + commandQueue.unshift("vim-mode-plus:reset-normal-mode"); + for (let i = 0; i < count; i++) { + commandQueue.forEach(command => { + atom.commands.dispatch(atom.views.getView(activeEditor()), command); + }); } } - class StartRecordingMacro extends Base.getClass("MiscCommand") { - startRecordingMacro() { - const workspaceView = atom.views.getView(atom.workspace); - workspaceView.classList.add("recording-macro"); - commandQueue = []; // empty the queue - recording = true; - atom.notifications.addInfo("Recording macro"); - } + execute() { + this.applyMacro(this.getCount()); + } + } - execute() { - this.startRecordingMacro(); - } + class StartRecordingMacro extends Base.getClass("MiscCommand") { + startRecordingMacro() { + const workspaceView = atom.views.getView(atom.workspace); + workspaceView.classList.add("recording-macro"); + commandQueue = []; // empty the queue + recording = true; + atom.notifications.addInfo("Recording macro"); } - class StopRecordingMacro extends Base.getClass("MiscCommand") { - stopRecordingMacro() { - const workspaceView = atom.views.getView(atom.workspace); - workspaceView.classList.remove("recording-macro"); - recording = false; - atom.notifications.addInfo("Stopped recording macro"); - } + execute() { + this.startRecordingMacro(); + } + } - execute() { - this.stopRecordingMacro(); - } + class StopRecordingMacro extends Base.getClass("MiscCommand") { + stopRecordingMacro() { + const workspaceView = atom.views.getView(atom.workspace); + workspaceView.classList.remove("recording-macro"); + recording = false; + atom.notifications.addInfo("Stopped recording macro"); } - return { - ApplyMacro, - StartRecordingMacro, - StopRecordingMacro - }; + execute() { + this.stopRecordingMacro(); + } } + + return { + ApplyMacro, + StartRecordingMacro, + StopRecordingMacro + }; +} + +module.exports = { + characterCommands, + recordCommand, + loadVmpCommands }; From df60241b3730707cab6158d8a204d16bde654915 Mon Sep 17 00:00:00 2001 From: Kevin Wu Date: Thu, 12 Dec 2019 01:33:41 -0800 Subject: [PATCH 7/7] Add example for prefixing with number --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index dc0442e..fba8b8a 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,8 @@ Make sure you also have vim-mode-plus installed, this package requires it. `@` to apply the macro +`[num]@` to apply the macro [num] times ex. `12@` + ## Roadmap - [x] a macro can be recorded