From eb818dd00e94413511e421e656e5086b807ebadd Mon Sep 17 00:00:00 2001 From: Bryan Phelps Date: Wed, 26 Aug 2020 08:25:18 -0700 Subject: [PATCH 1/2] Plumb through additional context to be shown in the status bar --- .../ClipboardInsertModePasteEmptyTest.re | 4 +- .../ClipboardInsertModePasteMultiLineTest.re | 4 +- .../ClipboardInsertModePasteSingleLineTest.re | 4 +- .../ClipboardNormalModePasteTest.re | 2 +- integration_test/ClipboardYankTest.re | 4 +- integration_test/EchoNotificationTest.re | 2 +- integration_test/EditorFontFromPathTest.re | 2 +- integration_test/EditorFontValidTest.re | 2 +- integration_test/EditorUtf8Test.re | 2 +- integration_test/ExtHostBufferOpenTest.re | 2 +- integration_test/ExtHostBufferUpdatesTest.re | 2 +- integration_test/ExtHostCompletionTest.re | 2 +- integration_test/ExtHostDefinitionTest.re | 2 +- integration_test/FontSizeChangeTest.re | 2 +- integration_test/InputIgnoreTest.re | 4 +- integration_test/InsertModeTest.re | 4 +- integration_test/KeySequenceJJTest.re | 6 +-- .../KeybindingsInvalidJsonTest.re | 2 +- integration_test/LanguageCssTest.re | 2 +- integration_test/LanguageTypeScriptTest.re | 2 +- integration_test/LineEndingsCRLFTest.re | 2 +- integration_test/LineEndingsLFTest.re | 2 +- .../QuickOpenEventuallyCompletesTest.re | 2 +- integration_test/Regression1671Test.re | 2 +- integration_test/Regression2349EnewTest.re | 2 +- .../RegressionCommandLineNoCompletionTest.re | 4 +- .../RegressionFileModifiedIndicationTest.re | 2 +- integration_test/SCMGitTest.re | 2 +- .../SearchShowClearHighlightsTest.re | 4 +- .../SyntaxHighlightTextMateTest.re | 2 +- .../SyntaxHighlightTreesitterTest.re | 2 +- integration_test/TypingBatchedTest.re | 4 +- integration_test/TypingUnbatchedTest.re | 4 +- integration_test/VimlConfigurationTest.re | 4 +- src/Core/Mode.re | 30 ++++++++--- src/Core/VisualRange.re | 38 ++++++++----- src/Feature/Editor/Editor.re | 25 ++++----- src/Feature/Editor/Editor.rei | 4 +- src/Feature/Editor/EditorSurface.re | 8 ++- src/Feature/Editor/Feature_Editor.re | 1 + src/Feature/Editor/Msg.re | 1 + src/Feature/Editor/Scrollbar.re | 8 +-- src/Feature/Theme/GlobalColors.re | 12 ++--- src/Feature/Vim/Feature_Vim.re | 2 +- src/Model/ContextKeys.re | 8 +-- src/Model/ModeManager.re | 23 ++++---- src/Service/Vim/Service_Vim.re | 4 +- src/Store/Features.re | 4 +- src/Store/StoreThread.re | 2 +- src/Store/VimStoreConnector.re | 48 +++++++++-------- src/editor-core-types/ByteRange.re | 2 + src/editor-core-types/ByteRange.rei | 2 + src/reason-libvim/Effect.re | 3 +- src/reason-libvim/Listeners.re | 4 -- src/reason-libvim/Mode.re | 53 ++++++++++++++++--- src/reason-libvim/Native.re | 11 +++- src/reason-libvim/Types.re | 9 ---- src/reason-libvim/Vim.re | 43 ++++----------- src/reason-libvim/Vim.rei | 20 ++++++- src/reason-libvim/Visual.re | 4 -- test/reason-libvim/CommandLineTest.re | 2 +- test/reason-libvim/FormatTest.re | 48 +++++++++++++---- test/reason-libvim/ModeTest.re | 6 +-- test/reason-libvim/VisualTest.re | 34 ------------ test/test.sh | 30 +++++++++++ 65 files changed, 336 insertions(+), 247 deletions(-) create mode 100644 test/test.sh diff --git a/integration_test/ClipboardInsertModePasteEmptyTest.re b/integration_test/ClipboardInsertModePasteEmptyTest.re index b35cbf1f99..af44a4f474 100644 --- a/integration_test/ClipboardInsertModePasteEmptyTest.re +++ b/integration_test/ClipboardInsertModePasteEmptyTest.re @@ -10,13 +10,13 @@ runTest( ~name="InsertMode test - effects batched to runEffects", (dispatch, wait, runEffects) => { wait(~name="Initial mode is normal", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); dispatch(KeyboardInput({isText: true, input: "i"})); wait(~name="Mode switches to insert", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Insert + Feature_Vim.mode(state.vim) == Vim.Mode.Insert ); setClipboard(None); diff --git a/integration_test/ClipboardInsertModePasteMultiLineTest.re b/integration_test/ClipboardInsertModePasteMultiLineTest.re index cf44800b0a..b07b2357af 100644 --- a/integration_test/ClipboardInsertModePasteMultiLineTest.re +++ b/integration_test/ClipboardInsertModePasteMultiLineTest.re @@ -10,13 +10,13 @@ runTest( ~name="InsertMode test - effects batched to runEffects", (dispatch, wait, runEffects) => { wait(~name="Initial mode is normal", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); dispatch(KeyboardInput({isText: true, input: "i"})); wait(~name="Mode switches to insert", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Insert + Feature_Vim.mode(state.vim) == Vim.Mode.Insert ); setClipboard(Some("def\nghi")); diff --git a/integration_test/ClipboardInsertModePasteSingleLineTest.re b/integration_test/ClipboardInsertModePasteSingleLineTest.re index 06216b44ab..e4f9f463b4 100644 --- a/integration_test/ClipboardInsertModePasteSingleLineTest.re +++ b/integration_test/ClipboardInsertModePasteSingleLineTest.re @@ -10,13 +10,13 @@ runTest( ~name="InsertMode test - effects batched to runEffects", (dispatch, wait, runEffects) => { wait(~name="Initial mode is normal", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); dispatch(KeyboardInput({isText: true, input: "i"})); wait(~name="Mode switches to insert", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Insert + Feature_Vim.mode(state.vim) == Vim.Mode.Insert ); setClipboard(Some("def")); diff --git a/integration_test/ClipboardNormalModePasteTest.re b/integration_test/ClipboardNormalModePasteTest.re index f98f53c181..bec0ab5758 100644 --- a/integration_test/ClipboardNormalModePasteTest.re +++ b/integration_test/ClipboardNormalModePasteTest.re @@ -19,7 +19,7 @@ runTest( ~name="InsertMode test - effects batched to runEffects", (dispatch, wait, runEffects) => { wait(~name="Initial mode is normal", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); // '*' test case diff --git a/integration_test/ClipboardYankTest.re b/integration_test/ClipboardYankTest.re index 1dc1ba0355..6d4cd7282b 100644 --- a/integration_test/ClipboardYankTest.re +++ b/integration_test/ClipboardYankTest.re @@ -37,7 +37,7 @@ runTest(~name="ClipboardYankTest", (dispatch, wait, runEffects) => { dispatch(KeyboardInput({isText: true, input: "i"})); wait(~name="Mode switches to insert", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Insert + Feature_Vim.mode(state.vim) == Vim.Mode.Insert ); dispatch(KeyboardInput({isText: true, input: "abc"})); @@ -45,7 +45,7 @@ runTest(~name="ClipboardYankTest", (dispatch, wait, runEffects) => { runEffects(); wait(~name="Mode switches back to normal", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); setClipboard(None); diff --git a/integration_test/EchoNotificationTest.re b/integration_test/EchoNotificationTest.re index 350378c468..8f5fc1a447 100644 --- a/integration_test/EchoNotificationTest.re +++ b/integration_test/EchoNotificationTest.re @@ -3,7 +3,7 @@ open Oni_IntegrationTestLib; runTest(~name="EchoNotificationTest", (dispatch, wait, _runEffects) => { wait(~name="Initial mode is normal", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); dispatch(VimExecuteCommand("echo 'hi from test'")); diff --git a/integration_test/EditorFontFromPathTest.re b/integration_test/EditorFontFromPathTest.re index 74483df125..f1fdc66a44 100644 --- a/integration_test/EditorFontFromPathTest.re +++ b/integration_test/EditorFontFromPathTest.re @@ -16,7 +16,7 @@ runTest( ~name="EditorFontFromPath", (_, wait, _) => { wait(~name="Initial mode is normal", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); print_endline("Using font: " ++ font); diff --git a/integration_test/EditorFontValidTest.re b/integration_test/EditorFontValidTest.re index 33a1d78e37..b3f703d08b 100644 --- a/integration_test/EditorFontValidTest.re +++ b/integration_test/EditorFontValidTest.re @@ -23,7 +23,7 @@ if (Revery.Environment.os !== Revery.Environment.Linux) { ~name="EditorFontValid", (_, wait, _) => { wait(~name="Initial mode is normal", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); wait( diff --git a/integration_test/EditorUtf8Test.re b/integration_test/EditorUtf8Test.re index 09fde84676..d85bacfb71 100644 --- a/integration_test/EditorUtf8Test.re +++ b/integration_test/EditorUtf8Test.re @@ -7,7 +7,7 @@ open Feature_Editor; runTestWithInput(~name="EditorUtf8Test", (input, dispatch, wait, _) => { wait(~name="Initial mode is normal", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); let testFile = getAssetPath("utf8.txt"); diff --git a/integration_test/ExtHostBufferOpenTest.re b/integration_test/ExtHostBufferOpenTest.re index ffddfbca8d..4bfd6530f9 100644 --- a/integration_test/ExtHostBufferOpenTest.re +++ b/integration_test/ExtHostBufferOpenTest.re @@ -10,7 +10,7 @@ module TS = TextSynchronization; runTestWithInput( ~name="ExtHostBufferOpen", (_input, dispatch, wait, _runEffects) => { wait(~name="Capture initial state", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); // Wait until the extension is activated diff --git a/integration_test/ExtHostBufferUpdatesTest.re b/integration_test/ExtHostBufferUpdatesTest.re index 6858b18155..613d0dda94 100644 --- a/integration_test/ExtHostBufferUpdatesTest.re +++ b/integration_test/ExtHostBufferUpdatesTest.re @@ -11,7 +11,7 @@ module TS = TextSynchronization; runTestWithInput( ~name="ExtHostBufferUpdates", (input, dispatch, wait, _runEffects) => { wait(~name="Capture initial state", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); // Wait until the extension is activated diff --git a/integration_test/ExtHostCompletionTest.re b/integration_test/ExtHostCompletionTest.re index ba48cdc763..66070d9d6c 100644 --- a/integration_test/ExtHostCompletionTest.re +++ b/integration_test/ExtHostCompletionTest.re @@ -8,7 +8,7 @@ open Oni_IntegrationTestLib; runTestWithInput( ~name="ExtHostCompletionTest", (input, dispatch, wait, _runEffects) => { wait(~name="Capture initial state", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); // Wait until the extension is activated diff --git a/integration_test/ExtHostDefinitionTest.re b/integration_test/ExtHostDefinitionTest.re index 6bbed672ea..743b20dece 100644 --- a/integration_test/ExtHostDefinitionTest.re +++ b/integration_test/ExtHostDefinitionTest.re @@ -9,7 +9,7 @@ open Feature_Editor; runTestWithInput( ~name="ExtHostDefinitionTest", (input, dispatch, wait, _runEffects) => { wait(~name="Capture initial state", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); // Wait until the extension is activated diff --git a/integration_test/FontSizeChangeTest.re b/integration_test/FontSizeChangeTest.re index 6d9ef45894..3892dda897 100644 --- a/integration_test/FontSizeChangeTest.re +++ b/integration_test/FontSizeChangeTest.re @@ -4,7 +4,7 @@ open Oni_IntegrationTestLib; // Validate that change the font size via config results in new metrics runTest(~name="FontSizeChangeTest", (dispatch, wait, runEffects) => { wait(~name="Mode switches back to normal", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); wait(~name="Set configuration to small font size", (state: State.t) => { diff --git a/integration_test/InputIgnoreTest.re b/integration_test/InputIgnoreTest.re index 70b43731a1..f98adad48f 100644 --- a/integration_test/InputIgnoreTest.re +++ b/integration_test/InputIgnoreTest.re @@ -7,13 +7,13 @@ module Log = (val Log.withNamespace("IntegrationTest.inputIgnore")); // This test validates that certain keystrokes are ignored by our Vim layer runTest(~name="InputIgnore test", (dispatch, wait, runEffects) => { wait(~name="Initial mode is normal", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); dispatch(KeyboardInput({isText: true, input: "i"})); wait(~name="Mode switches to insert", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Insert + Feature_Vim.mode(state.vim) == Vim.Mode.Insert ); dispatch(KeyboardInput({isText: false, input: ""})); diff --git a/integration_test/InsertModeTest.re b/integration_test/InsertModeTest.re index 7aa8233b00..8d7f0be4b2 100644 --- a/integration_test/InsertModeTest.re +++ b/integration_test/InsertModeTest.re @@ -3,12 +3,12 @@ open Oni_IntegrationTestLib; runTest(~name="InsertMode test", (dispatch, wait, _) => { wait(~name="Initial mode is normal", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); dispatch(KeyboardInput({isText: true, input: "i"})); wait(~name="Mode switches to insert", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Insert + Feature_Vim.mode(state.vim) == Vim.Mode.Insert ); }); diff --git a/integration_test/KeySequenceJJTest.re b/integration_test/KeySequenceJJTest.re index 4b94cc305f..0cb5ffe7ee 100644 --- a/integration_test/KeySequenceJJTest.re +++ b/integration_test/KeySequenceJJTest.re @@ -13,7 +13,7 @@ runTest( ~name="KeySequenceJJTest", (dispatch, wait, _) => { wait(~name="Initial mode is normal", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); let input = key => { @@ -31,14 +31,14 @@ runTest( input("i"); wait(~name="Mode is now insert", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Insert + Feature_Vim.mode(state.vim) == Vim.Mode.Insert ); input("j"); input("j"); wait(~name="Mode is back to normal", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); // TODO: Figure out why this check is failing... wait(~name="Validate buffer is empty", (state: State.t) => { diff --git a/integration_test/KeybindingsInvalidJsonTest.re b/integration_test/KeybindingsInvalidJsonTest.re index 9f109868b9..755347cdf6 100644 --- a/integration_test/KeybindingsInvalidJsonTest.re +++ b/integration_test/KeybindingsInvalidJsonTest.re @@ -10,7 +10,7 @@ runTest( ~name="KeybindingsInvalidJson", (_dispatch, wait, _) => { wait(~name="Initial mode is normal", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); let getErrorNotificationCount = (state: State.t) => { diff --git a/integration_test/LanguageCssTest.re b/integration_test/LanguageCssTest.re index 7b25d21722..fb3085343a 100644 --- a/integration_test/LanguageCssTest.re +++ b/integration_test/LanguageCssTest.re @@ -9,7 +9,7 @@ open Feature_LanguageSupport; runTestWithInput( ~name="LanguageCssTest", (input, dispatch, wait, _runEffects) => { wait(~name="Capture initial state", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); ExtensionHelpers.waitForExtensionToActivate( diff --git a/integration_test/LanguageTypeScriptTest.re b/integration_test/LanguageTypeScriptTest.re index 1f441e7874..1d161bdd8b 100644 --- a/integration_test/LanguageTypeScriptTest.re +++ b/integration_test/LanguageTypeScriptTest.re @@ -6,7 +6,7 @@ open Feature_LanguageSupport; runTestWithInput( ~name="LanguageTypeScriptTest", (input, dispatch, wait, _runEffects) => { wait(~name="Capture initial state", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); ExtensionHelpers.waitForExtensionToActivate( diff --git a/integration_test/LineEndingsCRLFTest.re b/integration_test/LineEndingsCRLFTest.re index 3592a86a0f..70f3712870 100644 --- a/integration_test/LineEndingsCRLFTest.re +++ b/integration_test/LineEndingsCRLFTest.re @@ -5,7 +5,7 @@ open Oni_IntegrationTestLib; runTest(~name="LineEndingsCRLFTest", (dispatch, wait, _runEffects) => { wait(~name="Capture initial state", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); let testFile = getAssetPath("test.crlf"); diff --git a/integration_test/LineEndingsLFTest.re b/integration_test/LineEndingsLFTest.re index 61c26b60b0..9784363d5f 100644 --- a/integration_test/LineEndingsLFTest.re +++ b/integration_test/LineEndingsLFTest.re @@ -5,7 +5,7 @@ open Oni_IntegrationTestLib; runTest(~name="LineEndingsLFTest", (dispatch, wait, _runEffects) => { wait(~name="Capture initial state", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); let testFile = getAssetPath("test.lf"); diff --git a/integration_test/QuickOpenEventuallyCompletesTest.re b/integration_test/QuickOpenEventuallyCompletesTest.re index ea4e33df99..803f32e502 100644 --- a/integration_test/QuickOpenEventuallyCompletesTest.re +++ b/integration_test/QuickOpenEventuallyCompletesTest.re @@ -3,7 +3,7 @@ open Oni_IntegrationTestLib; runTest(~name="QuickOpen eventually completes", (dispatch, wait, runEffects) => { wait(~name="Initial mode is normal", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); /* Switch to root directory */ diff --git a/integration_test/Regression1671Test.re b/integration_test/Regression1671Test.re index 61cc049cdd..00a437e5f6 100644 --- a/integration_test/Regression1671Test.re +++ b/integration_test/Regression1671Test.re @@ -8,7 +8,7 @@ runTestWithInput( ~name="Regression1671 - Opening new buffer loses changes in previous buffer", (input, _dispatch, wait, _runEffects) => { wait(~name="Capture initial state", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); input(":e a-test-file"); diff --git a/integration_test/Regression2349EnewTest.re b/integration_test/Regression2349EnewTest.re index e4fdaec0fc..37d4273ec0 100644 --- a/integration_test/Regression2349EnewTest.re +++ b/integration_test/Regression2349EnewTest.re @@ -3,7 +3,7 @@ open Oni_IntegrationTestLib; runTest(~name="Regression: Command line no completions", (dispatch, wait, _) => { wait(~name="Initial mode is normal", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); let initialEditorId = ref(None); diff --git a/integration_test/RegressionCommandLineNoCompletionTest.re b/integration_test/RegressionCommandLineNoCompletionTest.re index 25d097a046..8231915f61 100644 --- a/integration_test/RegressionCommandLineNoCompletionTest.re +++ b/integration_test/RegressionCommandLineNoCompletionTest.re @@ -3,13 +3,13 @@ open Oni_IntegrationTestLib; runTest(~name="Regression: Command line no completions", (dispatch, wait, _) => { wait(~name="Initial mode is normal", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); dispatch(KeyboardInput({isText: true, input: ":"})); wait(~name="Mode switches to command line", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.CommandLine + Feature_Vim.mode(state.vim) == Vim.Mode.CommandLine ); dispatch(KeyboardInput({isText: true, input: "e"})); diff --git a/integration_test/RegressionFileModifiedIndicationTest.re b/integration_test/RegressionFileModifiedIndicationTest.re index 4499f78322..2c93d93d66 100644 --- a/integration_test/RegressionFileModifiedIndicationTest.re +++ b/integration_test/RegressionFileModifiedIndicationTest.re @@ -10,7 +10,7 @@ runTestWithInput( ~name="RegressionFileModifiedIndication", (input, dispatch, wait, runEffects) => { wait(~name="Initial mode is normal", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); let initialBuffer = Vim.Buffer.getCurrent(); diff --git a/integration_test/SCMGitTest.re b/integration_test/SCMGitTest.re index 1f9f605bf4..b3fb6a78fc 100644 --- a/integration_test/SCMGitTest.re +++ b/integration_test/SCMGitTest.re @@ -3,7 +3,7 @@ open Oni_IntegrationTestLib; runTest(~name="SCMGitTest", (_dispatch, wait, _runEffects) => { wait(~name="Capture initial state", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); // For now... just validate that the extension activated diff --git a/integration_test/SearchShowClearHighlightsTest.re b/integration_test/SearchShowClearHighlightsTest.re index 124b5a1d4b..951209cdb4 100644 --- a/integration_test/SearchShowClearHighlightsTest.re +++ b/integration_test/SearchShowClearHighlightsTest.re @@ -7,14 +7,14 @@ runTest( ~name="InsertMode test - effects batched to runEffects", (dispatch, wait, runEffects) => { wait(~name="Initial mode is normal", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); // Edit dispatch(KeyboardInput({isText: true, input: "i"})); wait(~name="Mode switches to insert", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Insert + Feature_Vim.mode(state.vim) == Vim.Mode.Insert ); dispatch(KeyboardInput({isText: true, input: "a"})); diff --git a/integration_test/SyntaxHighlightTextMateTest.re b/integration_test/SyntaxHighlightTextMateTest.re index 8a49000a68..514e25e307 100644 --- a/integration_test/SyntaxHighlightTextMateTest.re +++ b/integration_test/SyntaxHighlightTextMateTest.re @@ -5,7 +5,7 @@ open Oni_IntegrationTestLib; // Validate that textmate highlight runs runTest(~name="SyntaxHighlightTextMateTest", (dispatch, wait, _runEffects) => { wait(~name="Capture initial state", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); wait(~name="Wait for syntax server", ~timeout=10.0, (state: State.t) => { Feature_Syntax.isSyntaxServerRunning(state.syntaxHighlights) diff --git a/integration_test/SyntaxHighlightTreesitterTest.re b/integration_test/SyntaxHighlightTreesitterTest.re index 237403775c..6dbe6938e7 100644 --- a/integration_test/SyntaxHighlightTreesitterTest.re +++ b/integration_test/SyntaxHighlightTreesitterTest.re @@ -12,7 +12,7 @@ runTest( ~name="SyntaxHighlightTreesitterTest", (dispatch, wait, _runEffects) => { wait(~name="Capture initial state", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); wait(~name="Wait for syntax server", ~timeout=10.0, (state: State.t) => { diff --git a/integration_test/TypingBatchedTest.re b/integration_test/TypingBatchedTest.re index d52ef9fbb4..51004c296e 100644 --- a/integration_test/TypingBatchedTest.re +++ b/integration_test/TypingBatchedTest.re @@ -8,13 +8,13 @@ runTest( ~name="InsertMode test - effects batched to runEffects", (dispatch, wait, runEffects) => { wait(~name="Initial mode is normal", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); dispatch(KeyboardInput({isText: true, input: "i"})); wait(~name="Mode switches to insert", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Insert + Feature_Vim.mode(state.vim) == Vim.Mode.Insert ); /* Simulate multiple events getting dispatched before running effects */ diff --git a/integration_test/TypingUnbatchedTest.re b/integration_test/TypingUnbatchedTest.re index 63509c9d75..8102bdbf7a 100644 --- a/integration_test/TypingUnbatchedTest.re +++ b/integration_test/TypingUnbatchedTest.re @@ -8,13 +8,13 @@ runTest( ~name="InsertMode test - effects batched to runEffects", (dispatch, wait, runEffects) => { wait(~name="Initial mode is normal", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); dispatch(KeyboardInput({isText: true, input: "i"})); wait(~name="Mode switches to insert", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Insert + Feature_Vim.mode(state.vim) == Vim.Mode.Insert ); /* Simulate multiple events getting dispatched before running effects */ diff --git a/integration_test/VimlConfigurationTest.re b/integration_test/VimlConfigurationTest.re index 7e2b47716f..5f9e8c9170 100644 --- a/integration_test/VimlConfigurationTest.re +++ b/integration_test/VimlConfigurationTest.re @@ -10,7 +10,7 @@ runTest( ~name="Viml Configuration Block", (dispatch, wait, _) => { wait(~name="Initial mode is normal", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.Normal + Feature_Vim.mode(state.vim) == Vim.Mode.Normal ); // Because of our 'experimental.viml' block, the ';' semicolon @@ -18,7 +18,7 @@ runTest( dispatch(KeyboardInput({isText: true, input: ";"})); wait(~name="Mode switches to command line", (state: State.t) => - Feature_Vim.mode(state.vim) == Vim.Types.CommandLine + Feature_Vim.mode(state.vim) == Vim.Mode.CommandLine ); dispatch(KeyboardInput({isText: true, input: "e"})); diff --git a/src/Core/Mode.re b/src/Core/Mode.re index ea7ad42b36..134041a747 100644 --- a/src/Core/Mode.re +++ b/src/Core/Mode.re @@ -8,25 +8,43 @@ type t = // Vim modes | Normal | Insert - | Visual - | Select + | Visual({range: VisualRange.t}) + | Select({range: VisualRange.t}) | Replace | Operator | CommandLine // Additional modes | TerminalInsert | TerminalNormal - | TerminalVisual; + | TerminalVisual({range: VisualRange.t}); let toString = fun | Insert => "Insert" | Normal => "Normal" - | Visual => "Visual" - | Select => "Select" + | Visual({range}) => + switch (range.mode) { + | Character => "Visual Character" + | Line => "Visual Line" + | Block => "Visual Block" + | None => "Visual" + } + | Select({range}) => + switch (range.mode) { + | Character => "Select Character" + | Line => "Select Line" + | Block => "Select Block" + | None => "Select" + } | Replace => "Replace" | Operator => "Operator" | CommandLine => "Command Line" | TerminalInsert => "Terminal Insert" | TerminalNormal => "Terminal Normal" - | TerminalVisual => "Terminal Visual"; + | TerminalVisual({range}) => + switch (range.mode) { + | Character => "Terminal Visual Character" + | Line => "Terminal Visual Line" + | Block => "Terminal Visual Block" + | None => "Terminal Visual" + }; diff --git a/src/Core/VisualRange.re b/src/Core/VisualRange.re index 9e05445ce5..b0598d8fb4 100644 --- a/src/Core/VisualRange.re +++ b/src/Core/VisualRange.re @@ -7,18 +7,30 @@ type t = { mode, }; -/* - * The range might not always come through in the correct 'order' - - * this method normalizes the range so that the (startLine, startColumn) is - * before or equal to (endLine, endColumn) - */ -let _normalizeRange = (range: ByteRange.t) => - if (LineNumber.(range.start.line > range.stop.line) - || LineNumber.(range.start.line == range.stop.line) - && ByteIndex.(range.start.byte > range.stop.byte)) { - ByteRange.{start: range.stop, stop: range.start}; - } else { - range; +module Internal = { + /* + * The range might not always come through in the correct 'order' - + * this method normalizes the range so that the (startLine, startColumn) is + * before or equal to (endLine, endColumn) + */ + let normalizeRange = (range: ByteRange.t) => + if (LineNumber.(range.start.line > range.stop.line) + || LineNumber.(range.start.line == range.stop.line) + && ByteIndex.(range.start.byte > range.stop.byte)) { + ByteRange.{start: range.stop, stop: range.start}; + } else { + range; + }; +}; + +let ofVim = (visualRange: Vim.VisualRange.t) => { + { + range: Internal.normalizeRange(visualRange.range), + mode: visualRange.visualType, }; +}; -let create = (~mode, range) => {range: _normalizeRange(range), mode}; +let create = (~mode, range) => { + range: Internal.normalizeRange(range), + mode, +}; diff --git a/src/Feature/Editor/Editor.re b/src/Feature/Editor/Editor.re index 549d9cfb79..1a05a022e7 100644 --- a/src/Feature/Editor/Editor.re +++ b/src/Feature/Editor/Editor.re @@ -41,7 +41,7 @@ type t = { maxLineLength: int, viewLines: int, cursors: [@opaque] list(BytePosition.t), - selection: [@opaque] VisualRange.t, + selection: [@opaque] option(VisualRange.t), pixelWidth: int, pixelHeight: int, }; @@ -49,7 +49,11 @@ type t = { let key = ({key, _}) => key; let totalViewLines = ({viewLines, _}) => viewLines; let selection = ({selection, _}) => selection; -let setSelection = (~selection, editor) => {...editor, selection}; +let setSelection = (~selection, editor) => { + ...editor, + selection: Some(selection), +}; +let clearSelection = editor => {...editor, selection: None}; let visiblePixelWidth = ({pixelWidth, _}) => pixelWidth; let visiblePixelHeight = ({pixelHeight, _}) => pixelHeight; let scrollY = ({scrollY, _}) => scrollY; @@ -148,16 +152,7 @@ let create = (~config, ~buffer, ()) => { * if a buffer loads prior to our first render. */ cursors: [{line: EditorCoreTypes.LineNumber.zero, byte: ByteIndex.zero}], - selection: - VisualRange.create( - ~mode=Vim.Types.None, - EditorCoreTypes.( - ByteRange.{ - start: BytePosition.{line: LineNumber.zero, byte: ByteIndex.zero}, - stop: BytePosition.{line: LineNumber.zero, byte: ByteIndex.zero}, - } - ), - ), + selection: None, pixelWidth: 1, pixelHeight: 1, }; @@ -340,7 +335,7 @@ let getPrimaryCursorByte = editor => BytePosition.{line: EditorCoreTypes.LineNumber.zero, byte: ByteIndex.zero} }; let selectionOrCursorRange = editor => { - switch (editor.selection.mode) { + switch (editor.selection) { | None => let pos = getPrimaryCursorByte(editor); ByteRange.{ @@ -351,9 +346,7 @@ let selectionOrCursorRange = editor => { byte: ByteIndex.zero, }, }; - | Line - | Block - | Character => editor.selection.range + | Some(selection) => selection.range }; }; diff --git a/src/Feature/Editor/Editor.rei b/src/Feature/Editor/Editor.rei index f1479467ea..0caeb2c92d 100644 --- a/src/Feature/Editor/Editor.rei +++ b/src/Feature/Editor/Editor.rei @@ -76,8 +76,10 @@ let linePaddingInPixels: t => float; let setLineHeight: (~lineHeight: LineHeight.t, t) => t; let characterWidthInPixels: t => float; -let selection: t => VisualRange.t; +let selection: t => option(VisualRange.t); let setSelection: (~selection: VisualRange.t, t) => t; +let clearSelection: t => t; + let selectionOrCursorRange: t => ByteRange.t; let totalViewLines: t => int; diff --git a/src/Feature/Editor/EditorSurface.re b/src/Feature/Editor/EditorSurface.re index 1e5129d707..0083b43637 100644 --- a/src/Feature/Editor/EditorSurface.re +++ b/src/Feature/Editor/EditorSurface.re @@ -208,7 +208,7 @@ let%component make = ); let matchingPairCheckPosition = - mode == Vim.Types.Insert + mode == Vim.Mode.Insert ? CharacterPosition.{ line: cursorPosition.line, character: CharacterIndex.(cursorPosition.character - 1), @@ -226,7 +226,11 @@ let%component make = let diagnosticsMap = Diagnostics.getDiagnosticsMap(diagnostics, buffer); let selectionRanges = - Selection.getRanges(Editor.selection(editor), buffer) |> ByteRange.toHash; + editor + |> Editor.selection + |> Option.map(selection => Selection.getRanges(selection, buffer)) + |> Option.map(ByteRange.toHash) + |> Option.value(~default=Hashtbl.create(1)); let diffMarkers = lineCount < Constants.diffMarkersMaxLineCount && showDiffMarkers diff --git a/src/Feature/Editor/Feature_Editor.re b/src/Feature/Editor/Feature_Editor.re index 2ffe74fe9a..9a34a4f5fe 100644 --- a/src/Feature/Editor/Feature_Editor.re +++ b/src/Feature/Editor/Feature_Editor.re @@ -122,6 +122,7 @@ let update = (editor, msg) => { Editor.setSelection(~selection, editor), Nothing, ) + | SelectionCleared => (Editor.clearSelection(editor), Nothing) | CursorsChanged(cursors) => ( Editor.setCursors(~cursors, editor), Nothing, diff --git a/src/Feature/Editor/Msg.re b/src/Feature/Editor/Msg.re index b08dede50c..4ba5511a59 100644 --- a/src/Feature/Editor/Msg.re +++ b/src/Feature/Editor/Msg.re @@ -25,6 +25,7 @@ type t = | MouseHovered({bytePosition: BytePosition.t}) | MouseMoved({bytePosition: BytePosition.t}) | SelectionChanged([@opaque] VisualRange.t) + | SelectionCleared | CursorsChanged([@opaque] list(BytePosition.t)) | ScrollToLine(int) | ScrollToColumn(int) diff --git a/src/Feature/Editor/Scrollbar.re b/src/Feature/Editor/Scrollbar.re index b9ad0a3e42..b9f108c0af 100644 --- a/src/Feature/Editor/Scrollbar.re +++ b/src/Feature/Editor/Scrollbar.re @@ -322,10 +322,10 @@ module Vertical = { ), ]; }; - let getSelectionElements = (selection: VisualRange.t) => { - switch (selection.mode) { - | Vim.Types.None => [] - | _ => + let getSelectionElements = (selection: option(VisualRange.t)) => { + switch (selection) { + | None => [] + | Some(selection) => let topLine = Editor.projectLine( ~line=selection.range.start.line, diff --git a/src/Feature/Theme/GlobalColors.re b/src/Feature/Theme/GlobalColors.re index 190d050838..6e680199d9 100644 --- a/src/Feature/Theme/GlobalColors.re +++ b/src/Feature/Theme/GlobalColors.re @@ -597,9 +597,9 @@ module Oni = { let backgroundFor = (mode: Mode.t) => switch (mode) { - | Select - | TerminalVisual - | Visual => visualModeBackground + | Select(_) + | TerminalVisual(_) + | Visual(_) => visualModeBackground | CommandLine => commandlineModeBackground | Operator => operatorModeBackground | TerminalInsert @@ -611,9 +611,9 @@ module Oni = { let foregroundFor = (mode: Mode.t) => switch (mode) { - | Select - | TerminalVisual - | Visual => visualModeForeground + | Select(_) + | TerminalVisual(_) + | Visual(_) => visualModeForeground | CommandLine => commandlineModeForeground | Operator => operatorModeForeground | TerminalInsert diff --git a/src/Feature/Vim/Feature_Vim.re b/src/Feature/Vim/Feature_Vim.re index ba83ea0810..9356f99410 100644 --- a/src/Feature/Vim/Feature_Vim.re +++ b/src/Feature/Vim/Feature_Vim.re @@ -5,7 +5,7 @@ open Oni_Core.Utility; type model = {mode: Vim.Mode.t}; -let initial = {mode: Vim.Types.Normal}; +let initial = {mode: Vim.Mode.Normal}; let mode = ({mode}) => mode; diff --git a/src/Model/ContextKeys.re b/src/Model/ContextKeys.re index 00b37048d0..425e9b6c8f 100644 --- a/src/Model/ContextKeys.re +++ b/src/Model/ContextKeys.re @@ -29,7 +29,7 @@ let editors = switch (ModeManager.current(state)) { | TerminalInsert | TerminalNormal - | TerminalVisual => false + | TerminalVisual(_) => false | _ => true } ), @@ -37,7 +37,7 @@ let editors = switch (ModeManager.current(state)) { | TerminalInsert | TerminalNormal - | TerminalVisual => true + | TerminalVisual(_) => true | _ => false } ), @@ -60,8 +60,8 @@ let editors = ), bool("visualMode", state => switch (ModeManager.current(state)) { - | TerminalVisual - | Visual => true + | TerminalVisual(_) + | Visual(_) => true | _ => false } ), diff --git a/src/Model/ModeManager.re b/src/Model/ModeManager.re index 9c2cffafc7..efb66cc326 100644 --- a/src/Model/ModeManager.re +++ b/src/Model/ModeManager.re @@ -3,9 +3,10 @@ open Oni_Core; module Internal = { let getTerminalNormalMode = fun - | Vim.Types.Visual => Mode.TerminalVisual - | Vim.Types.Operator => Mode.Operator - | Vim.Types.CommandLine => Mode.CommandLine + | Vim.Mode.Visual({range}) => + Mode.TerminalVisual({range: Oni_Core.VisualRange.ofVim(range)}) + | Vim.Mode.Operator => Mode.Operator + | Vim.Mode.CommandLine => Mode.CommandLine | _ => Mode.TerminalNormal; }; @@ -21,12 +22,14 @@ let current: State.t => Oni_Core.Mode.t = |> Option.value( ~default= switch (Feature_Vim.mode(state.vim)) { - | Vim.Types.Insert => Mode.Insert - | Vim.Types.Normal => Mode.Normal - | Vim.Types.Visual => Mode.Visual - | Vim.Types.Select => Mode.Select - | Vim.Types.Replace => Mode.Replace - | Vim.Types.Operator => Mode.Operator - | Vim.Types.CommandLine => Mode.CommandLine + | Vim.Mode.Insert => Mode.Insert + | Vim.Mode.Normal => Mode.Normal + | Vim.Mode.Visual({range}) => + Mode.Visual({range: Oni_Core.VisualRange.ofVim(range)}) + | Vim.Mode.Select({range}) => + Mode.Select({range: Oni_Core.VisualRange.ofVim(range)}) + | Vim.Mode.Replace => Mode.Replace + | Vim.Mode.Operator => Mode.Operator + | Vim.Mode.CommandLine => Mode.CommandLine }, ); diff --git a/src/Service/Vim/Service_Vim.re b/src/Service/Vim/Service_Vim.re index 4e45280d18..b06852bd04 100644 --- a/src/Service/Vim/Service_Vim.re +++ b/src/Service/Vim/Service_Vim.re @@ -30,8 +30,8 @@ let quitAll = () => module Effects = { let paste = (~toMsg, text) => { Isolinear.Effect.createWithDispatch(~name="vim.clipboardPaste", dispatch => { - let isCmdLineMode = Vim.Mode.getCurrent() == Vim.Types.CommandLine; - let isInsertMode = Vim.Mode.getCurrent() == Vim.Types.Insert; + let isCmdLineMode = Vim.Mode.current() == Vim.Mode.CommandLine; + let isInsertMode = Vim.Mode.current() == Vim.Mode.Insert; if (isInsertMode || isCmdLineMode) { if (!isCmdLineMode) { diff --git a/src/Store/Features.re b/src/Store/Features.re index c375acc91e..3276caa198 100644 --- a/src/Store/Features.re +++ b/src/Store/Features.re @@ -869,7 +869,7 @@ let update = ({...state, signatureHelp, languageSupport: languageSupport'}, shEffect); | Vim(msg) => - let wasInInsertMode = Feature_Vim.mode(state.vim) == Vim.Types.Insert; + let wasInInsertMode = Feature_Vim.mode(state.vim) == Vim.Mode.Insert; let (vim, outmsg) = Feature_Vim.update(msg, state.vim); let state = {...state, vim}; @@ -894,7 +894,7 @@ let update = ({...state, layout: layout'}, Isolinear.Effect.none); }; - let isInInsertMode = Feature_Vim.mode(state'.vim) == Vim.Types.Insert; + let isInInsertMode = Feature_Vim.mode(state'.vim) == Vim.Mode.Insert; // Entered insert mode let languageSupport = diff --git a/src/Store/StoreThread.re b/src/Store/StoreThread.re index ca45f7f2ec..1844a0ded5 100644 --- a/src/Store/StoreThread.re +++ b/src/Store/StoreThread.re @@ -197,7 +197,7 @@ let start = let visibleBuffersAndRanges = state |> Model.EditorVisibleRanges.getVisibleBuffersAndRanges; - let isInsertMode = Feature_Vim.mode(state.vim) == Vim.Types.Insert; + let isInsertMode = Feature_Vim.mode(state.vim) == Vim.Mode.Insert; let visibleRanges = visibleBuffersAndRanges diff --git a/src/Store/VimStoreConnector.re b/src/Store/VimStoreConnector.re index ee4606adce..d225a28f21 100644 --- a/src/Store/VimStoreConnector.re +++ b/src/Store/VimStoreConnector.re @@ -152,12 +152,31 @@ let start = ~endLine, ), ), - ), - ); - - let _: unit => unit = - Vim.Mode.onChanged(newMode => - dispatch(Actions.Vim(Feature_Vim.ModeChanged(newMode))) + ) + | ModeChanged(newMode) => { + dispatch(Actions.Vim(Feature_Vim.ModeChanged(newMode))); + + let editorId = + Feature_Layout.activeEditor(getState().layout) |> Editor.getId; + + switch (newMode) { + | Visual({range}) + | Select({range}) => + dispatch( + Editor({ + scope: Oni_Model.EditorScope.Editor(editorId), + msg: SelectionChanged(Oni_Core.VisualRange.ofVim(range)), + }), + ) + | _ => + dispatch( + Editor({ + scope: Oni_Model.EditorScope.Editor(editorId), + msg: SelectionCleared, + }), + ) + }; + }, ); let _: unit => unit = @@ -277,23 +296,6 @@ let start = ); }); - let _: unit => unit = - Vim.Visual.onRangeChanged(vr => { - open Vim.VisualRange; - - let {visualType, range} = vr; - let vr = Core.VisualRange.create(~mode=visualType, range); - - let editorId = - Feature_Layout.activeEditor(getState().layout) |> Editor.getId; - dispatch( - Editor({ - scope: Oni_Model.EditorScope.Editor(editorId), - msg: SelectionChanged(vr), - }), - ); - }); - let _: unit => unit = Vim.Window.onSplit((splitType, buf) => { /* If buf wasn't specified, use the filepath from the current buffer */ diff --git a/src/editor-core-types/ByteRange.re b/src/editor-core-types/ByteRange.re index 6e41b94f0f..43ca156efe 100644 --- a/src/editor-core-types/ByteRange.re +++ b/src/editor-core-types/ByteRange.re @@ -4,6 +4,8 @@ type t = { stop: BytePosition.t, }; +let zero = {start: BytePosition.zero, stop: BytePosition.zero}; + let contains = (position: BytePosition.t, range) => { ( LineNumber.(position.line == range.start.line) diff --git a/src/editor-core-types/ByteRange.rei b/src/editor-core-types/ByteRange.rei index fef1adbcdb..38a516e01f 100644 --- a/src/editor-core-types/ByteRange.rei +++ b/src/editor-core-types/ByteRange.rei @@ -4,6 +4,8 @@ type t = { stop: BytePosition.t, }; +let zero: t; + let contains: (BytePosition.t, t) => bool; /** diff --git a/src/reason-libvim/Effect.re b/src/reason-libvim/Effect.re index 5bb73671c5..aea9e49000 100644 --- a/src/reason-libvim/Effect.re +++ b/src/reason-libvim/Effect.re @@ -1,4 +1,5 @@ type t = | Goto(Goto.effect) | TabPage(TabPage.effect) - | Format(Format.effect); + | Format(Format.effect) + | ModeChanged(Mode.t); diff --git a/src/reason-libvim/Listeners.re b/src/reason-libvim/Listeners.re index e936e62855..25659fe6f6 100644 --- a/src/reason-libvim/Listeners.re +++ b/src/reason-libvim/Listeners.re @@ -11,9 +11,7 @@ type commandLineUpdateListener = Types.cmdline => unit; type effectListener = Effect.t => unit; type directoryChangedListener = string => unit; type messageListener = (Types.msgPriority, string, string) => unit; -type modeChangedListener = mode => unit; type quitListener = (Types.quitType, bool) => unit; -type visualRangeChangedListener = VisualRange.t => unit; type windowMovementListener = (Types.windowMovementType, int) => unit; type windowSplitListener = (Types.windowSplitType, string) => unit; type yankListener = Yank.t => unit; @@ -40,14 +38,12 @@ let directoryChanged: ref(list(directoryChangedListener)) = ref([]); let effect: ref(list(effectListener)) = ref([]); let intro: ref(list(noopListener)) = ref([]); let message: ref(list(messageListener)) = ref([]); -let modeChanged: ref(list(modeChangedListener)) = ref([]); let quit: ref(list(quitListener)) = ref([]); let stopSearchHighlight: ref(list(noopListener)) = ref([]); let terminalRequested: Event.t(Types.terminalRequest => unit) = Event.create(); let unhandledEscape: ref(list(noopListener)) = ref([]); let version: ref(list(noopListener)) = ref([]); -let visualRangeChanged: ref(list(visualRangeChangedListener)) = ref([]); let windowMovement: ref(list(windowMovementListener)) = ref([]); let windowSplit: ref(list(windowSplitListener)) = ref([]); let yank: ref(list(yankListener)) = ref([]); diff --git a/src/reason-libvim/Mode.re b/src/reason-libvim/Mode.re index 449494879d..9112342fdd 100644 --- a/src/reason-libvim/Mode.re +++ b/src/reason-libvim/Mode.re @@ -1,19 +1,60 @@ -type t = Types.mode; +type t = + | Normal + | Insert + | CommandLine + | Replace + | Visual({range: VisualRange.t}) + | Operator + | Select({range: VisualRange.t}); let show = (mode: t) => { switch (mode) { | Normal => "Normal" - | Visual => "Visual" + | Visual(_) => "Visual" | CommandLine => "CommandLine" | Replace => "Replace" | Operator => "Operator" | Insert => "Insert" - | Select => "Select" + | Select(_) => "Select" }; }; -let getCurrent = Native.vimGetMode; +let current = () => { + let nativeMode: Native.mode = Native.vimGetMode(); -let onChanged = (f: Listeners.modeChangedListener) => { - Event.add(f, Listeners.modeChanged); + switch (nativeMode) { + | Native.Normal => Normal + | Native.Visual => + Visual({ + range: + VisualRange.create( + ~range=Visual.getRange(), + ~visualType=Visual.getType(), + (), + ), + }) + | Native.CommandLine => CommandLine + | Native.Replace => Replace + | Native.Operator => Operator + | Native.Insert => Insert + | Native.Select => + Select({ + range: + VisualRange.create( + ~range=Visual.getRange(), + ~visualType=Visual.getType(), + (), + ), + }) + }; }; + +let isVisual = + fun + | Visual(_) => true + | _ => false; + +let isSelect = + fun + | Select(_) => true + | _ => false; diff --git a/src/reason-libvim/Native.re b/src/reason-libvim/Native.re index dcd8a30696..f0d4c6cb1c 100644 --- a/src/reason-libvim/Native.re +++ b/src/reason-libvim/Native.re @@ -1,6 +1,15 @@ type buffer = Types.buffer; type lineEnding = Types.lineEnding; +type mode = + | Normal + | Insert + | CommandLine + | Replace + | Visual + | Operator + | Select; + type formatType = | Indentation | Formatting; @@ -19,7 +28,7 @@ external vimInput: string => unit = "libvim_vimInput"; external vimKey: string => unit = "libvim_vimKey"; external vimCommand: string => unit = "libvim_vimCommand"; -external vimGetMode: unit => Types.mode = "libvim_vimGetMode"; +external vimGetMode: unit => mode = "libvim_vimGetMode"; external vimBufferOpen: string => buffer = "libvim_vimBufferOpen"; external vimBufferGetId: buffer => int = "libvim_vimBufferGetId"; diff --git a/src/reason-libvim/Types.re b/src/reason-libvim/Types.re index 946e903d67..288e03a101 100644 --- a/src/reason-libvim/Types.re +++ b/src/reason-libvim/Types.re @@ -16,15 +16,6 @@ type lineEnding = | LF | CRLF; -type mode = - | Normal - | Insert - | CommandLine - | Replace - | Visual - | Operator - | Select; - type cmdlineType = | Ex | SearchForward diff --git a/src/reason-libvim/Vim.re b/src/reason-libvim/Vim.re index ce190dfb50..614d9661e3 100644 --- a/src/reason-libvim/Vim.re +++ b/src/reason-libvim/Vim.re @@ -173,12 +173,10 @@ let runWith = (~context: Context.t, f) => { context.lineComment |> Option.iter(Options.setLineComment); let oldBuf = Buffer.getCurrent(); - let prevMode = Mode.getCurrent(); + let prevMode = Mode.current(); // let prevLocation = Cursor.get(); - let prevRange = Visual.getRange(); // let prevTopLine = Window.getTopLine(); // let prevLeftColumn = Window.getLeftColumn(); - let prevVisualMode = Visual.getType(); let prevModified = Buffer.isModified(oldBuf); let prevLineEndings = Buffer.getLineEndings(oldBuf); @@ -190,18 +188,16 @@ let runWith = (~context: Context.t, f) => { let newBuf = Buffer.getCurrent(); // let newLocation = Cursor.get(); - let newMode = Mode.getCurrent(); - let newRange = Visual.getRange(); + let newMode = Mode.current(); // let newLeftColumn = Window.getLeftColumn(); // let newTopLine = Window.getTopLine(); - let newVisualMode = Visual.getType(); let newModified = Buffer.isModified(newBuf); let newLineEndings = Buffer.getLineEndings(newBuf); BufferInternal.checkCurrentBufferForUpdate(); if (newMode != prevMode) { - Event.dispatch(newMode, Listeners.modeChanged); + Event.dispatch(Effect.ModeChanged(newMode), Listeners.effect); if (newMode == CommandLine) { Event.dispatch( @@ -218,27 +214,6 @@ let runWith = (~context: Context.t, f) => { ); }; - // if (BytePosition.(prevLocation == newLocation)) { - // Event.dispatch(newLocation, Listeners.cursorMoved); - // }; - // - // if (prevTopLine != newTopLine) { - // Event.dispatch(newTopLine, Listeners.topLineChanged); - // }; - // - // if (prevLeftColumn != newLeftColumn) { - // Event.dispatch(newLeftColumn, Listeners.leftColumnChanged); - // }; - - if (!ByteRange.equals(prevRange, newRange) - || newMode == Visual - && prevMode != Visual - || prevVisualMode != newVisualMode) { - let vr = - VisualRange.create(~range=newRange, ~visualType=newVisualMode, ()); - Event.dispatch(vr, Listeners.visualRangeChanged); - }; - let id = Buffer.getId(newBuf); if (prevModified != newModified) { Event.dispatch2(id, newModified, Listeners.bufferModifiedChanged); @@ -465,7 +440,7 @@ let init = () => { Native.vimInit(); - Event.dispatch(Mode.getCurrent(), Listeners.modeChanged); + Event.dispatch(Effect.ModeChanged(Mode.current()), Listeners.effect); BufferInternal.checkCurrentBufferForUpdate(); }; @@ -478,7 +453,7 @@ let inputCommon = (~inputFn, ~context=Context.current(), v: string) => { let runCursor = cursor => { Cursor.set(cursor); - if (Mode.getCurrent() == Types.Insert) { + if (Mode.current() == Mode.Insert) { let position: BytePosition.t = Cursor.get(); let line = Buffer.getLine(Buffer.getCurrent(), position.line); @@ -540,19 +515,19 @@ let inputCommon = (~inputFn, ~context=Context.current(), v: string) => { Cursor.get(); }; - let mode = Mode.getCurrent(); + let mode = Mode.current(); let cursors = Internal.getDefaultCursors(cursors); - if (mode == Types.Insert) { + if (mode == Mode.Insert) { // Run first command, verify we don't go back to normal mode switch (cursors) { | [hd, ...tail] => let newHead = runCursor(hd); - let newMode = Mode.getCurrent(); + let newMode = Mode.current(); // If we're still in insert mode, run the command for all the rest of the characters too let remainingCursors = switch (newMode) { - | Types.Insert => List.map(runCursor, tail) + | Mode.Insert => List.map(runCursor, tail) | _ => tail }; diff --git a/src/reason-libvim/Vim.rei b/src/reason-libvim/Vim.rei index 7b0436e00e..fb381a19e0 100644 --- a/src/reason-libvim/Vim.rei +++ b/src/reason-libvim/Vim.rei @@ -262,11 +262,28 @@ module Format: { }); }; +module Mode: { + type t = + | Normal + | Insert + | CommandLine + | Replace + | Visual({range: VisualRange.t}) + | Operator + | Select({range: VisualRange.t}); + + let current: unit => t; + + let isVisual: t => bool; + let isSelect: t => bool; +}; + module Effect: { type t = | Goto(Goto.effect) | TabPage(TabPage.effect) - | Format(Format.effect); + | Format(Format.effect) + | ModeChanged(Mode.t); }; /** @@ -384,7 +401,6 @@ module Clipboard = Clipboard; module CommandLine = CommandLine; module Cursor = Cursor; module Event = Event; -module Mode = Mode; module Options = Options; module Search = Search; module Types = Types; diff --git a/src/reason-libvim/Visual.re b/src/reason-libvim/Visual.re index b921bbb572..d41ee0226c 100644 --- a/src/reason-libvim/Visual.re +++ b/src/reason-libvim/Visual.re @@ -26,7 +26,3 @@ let getRange = () => { }; let getType = Native.vimVisualGetType; - -let onRangeChanged = f => { - Event.add(f, Listeners.visualRangeChanged); -}; diff --git a/test/reason-libvim/CommandLineTest.re b/test/reason-libvim/CommandLineTest.re index 96f3f8c8c0..7b2c411356 100644 --- a/test/reason-libvim/CommandLineTest.re +++ b/test/reason-libvim/CommandLineTest.re @@ -150,7 +150,7 @@ describe("CommandLine", ({describe, _}) => { input("g"); key(""); - expect.bool(Mode.getCurrent() == Normal).toBe(true); + expect.bool(Mode.current() == Normal).toBe(true); let line = Buffer.getLine(buffer, LineNumber.ofOneBased(3)); expect.string(line).toEqual("Dhis is the third line of a test file"); diff --git a/test/reason-libvim/FormatTest.re b/test/reason-libvim/FormatTest.re index 303622fcf9..86dd282114 100644 --- a/test/reason-libvim/FormatTest.re +++ b/test/reason-libvim/FormatTest.re @@ -19,9 +19,16 @@ describe("Format", ({test, _}) => { input("gg"); input("="); input("G"); - let formatEffect = List.hd(effects^); - - expect.int(List.length(effects^)).toBe(1); + let formatEffects = + effects^ + |> List.filter( + fun + | Effect.Format(_) => true + | _ => false, + ); + let formatEffect = List.hd(formatEffects); + + expect.int(List.length(formatEffects)).toBe(1); expect.equal( formatEffect, Effect.Format( @@ -47,7 +54,14 @@ describe("Format", ({test, _}) => { input("=="); let formatEffect = List.hd(effects^); - expect.int(List.length(effects^)).toBe(1); + let formatEffects = + effects^ + |> List.filter( + fun + | Effect.Format(_) => true + | _ => false, + ); + expect.int(List.length(formatEffects)).toBe(1); expect.equal( formatEffect, Effect.Format( @@ -75,9 +89,16 @@ describe("Format", ({test, _}) => { input("gg"); input("gq"); input("G"); - let formatEffect = List.hd(effects^); - - expect.int(List.length(effects^)).toBe(1); + let formatEffects = + effects^ + |> List.filter( + fun + | Effect.Format(_) => true + | _ => false, + ); + let formatEffect = List.hd(formatEffects); + + expect.int(List.length(formatEffects)).toBe(1); expect.equal( formatEffect, Effect.Format( @@ -103,9 +124,16 @@ describe("Format", ({test, _}) => { input("gg"); input("gw"); input("G"); - let formatEffect = List.hd(effects^); - - expect.int(List.length(effects^)).toBe(1); + let formatEffects = + effects^ + |> List.filter( + fun + | Effect.Format(_) => true + | _ => false, + ); + let formatEffect = List.hd(formatEffects); + + expect.int(List.length(formatEffects)).toBe(1); expect.equal( formatEffect, Effect.Format( diff --git a/test/reason-libvim/ModeTest.re b/test/reason-libvim/ModeTest.re index 36764877ee..149ce58647 100644 --- a/test/reason-libvim/ModeTest.re +++ b/test/reason-libvim/ModeTest.re @@ -10,7 +10,7 @@ describe("Mode", ({describe, _}) => { // Enter replace mode let _ = Vim.input("R"); - expect.equal(Vim.Mode.getCurrent(), Vim.Types.Replace); + expect.equal(Vim.Mode.current(), Vim.Mode.Replace); }) }); describe("select mode", ({test, _}) => { @@ -19,11 +19,11 @@ describe("Mode", ({describe, _}) => { // Enter replace mode let _ = Vim.input("V"); - expect.equal(Vim.Mode.getCurrent(), Vim.Types.Visual); + expect.equal(Vim.Mode.isVisual(Vim.Mode.current()), true); let _ = Vim.key(""); - expect.equal(Vim.Mode.getCurrent(), Vim.Types.Select); + expect.equal(Vim.Mode.isSelect(Vim.Mode.current()), true); }) }); }); diff --git a/test/reason-libvim/VisualTest.re b/test/reason-libvim/VisualTest.re index a34eb81cc6..a552de0a4a 100644 --- a/test/reason-libvim/VisualTest.re +++ b/test/reason-libvim/VisualTest.re @@ -68,38 +68,4 @@ describe("Visual", ({describe, _}) => { expect.bool(vt == None).toBe(true); }) ); - - describe("onRangeChanged", ({test, _}) => - test("dispatches on change", ({expect, _}) => { - let _ = resetBuffer(); - - let rangeChanges: ref(list(ByteRange.t)) = ref([]); - let dispose = - Visual.onRangeChanged(vr => { - open Vim.VisualRange; - let {range, _} = vr; - rangeChanges := [range, ...rangeChanges^]; - }); - - input("V"); - - expect.int(List.length(rangeChanges^)).toBe(1); - let r = List.hd(rangeChanges^); - expect.int(r.start.line |> lineNumberToInt).toBe(0); - expect.int(r.start.byte |> byteToInt).toBe(0); - expect.int(r.stop.line |> lineNumberToInt).toBe(0); - expect.int(r.stop.byte |> byteToInt).toBe(0); - - input("j"); - - expect.int(List.length(rangeChanges^)).toBe(2); - let r = List.hd(rangeChanges^); - expect.int(r.start.line |> lineNumberToInt).toBe(0); - expect.int(r.start.byte |> byteToInt).toBe(0); - expect.int(r.stop.line |> lineNumberToInt).toBe(1); - expect.int(r.stop.byte |> byteToInt).toBe(0); - - dispose(); - }) - ); }); diff --git a/test/test.sh b/test/test.sh new file mode 100644 index 0000000000..4c5bf8f7ea --- /dev/null +++ b/test/test.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +if [[ "$OSTYPE" == "darwin"* ]]; then + realpath() { [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"; } + ROOT=$(dirname $(dirname $(realpath "$0"))) +else + ROOT=$(dirname $(dirname $(readlink -f $0))) +fi + +DEVELOPER=$(xcode-select -print-path) +LIPO=$(xcrun -sdk iphoneos -find lipo) + +function code() { + cd $ROOT + + # Node modules + test -d node_modules || ./scripts/npm.sh install + + # Configuration + export NODE_ENV=development + + # Launch Code + if [[ "$OSTYPE" == "darwin"* ]]; then + exec ./.build/electron/Electron.app/Contents/MacOS/Electron . "$@" + else + exec ./.build/electron/electron . "$@" + fi +} + +code "$@" From 294c61c5392ea3bc0c22185f256c65f82667bfd6 Mon Sep 17 00:00:00 2001 From: Bryan Phelps Date: Wed, 26 Aug 2020 08:27:43 -0700 Subject: [PATCH 2/2] Remove test.sh --- test/test.sh | 30 ------------------------------ 1 file changed, 30 deletions(-) delete mode 100644 test/test.sh diff --git a/test/test.sh b/test/test.sh deleted file mode 100644 index 4c5bf8f7ea..0000000000 --- a/test/test.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env bash - -if [[ "$OSTYPE" == "darwin"* ]]; then - realpath() { [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"; } - ROOT=$(dirname $(dirname $(realpath "$0"))) -else - ROOT=$(dirname $(dirname $(readlink -f $0))) -fi - -DEVELOPER=$(xcode-select -print-path) -LIPO=$(xcrun -sdk iphoneos -find lipo) - -function code() { - cd $ROOT - - # Node modules - test -d node_modules || ./scripts/npm.sh install - - # Configuration - export NODE_ENV=development - - # Launch Code - if [[ "$OSTYPE" == "darwin"* ]]; then - exec ./.build/electron/Electron.app/Contents/MacOS/Electron . "$@" - else - exec ./.build/electron/electron . "$@" - fi -} - -code "$@"