Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(tabs/#3150): Multiple 'editor tabs' open with tabnew/tabedit #3755

Merged
merged 4 commits into from
Jul 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES_CURRENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
- #3732 - Input: Fix remapped keys executing in wrong order (fixes #3729)
- #3747 - Layout: Implement Control+W, C binding (related #1721)
- #3746 - Extension: Fix edit application in trailing spaces plugin
- #3755 - Vim: Fix extra 'editor tab' with `:tabnew`/`:tabedit` (fixes #3150)

### Performance

Expand Down
51 changes: 51 additions & 0 deletions integration_test/RegressionLayoutTabSingleEditor.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Regression test for #3150:
// When running ':tabnew'/':tabedit' on a buffer, only a single
// editor tab should be visible.

open Oni_Core;
open Oni_Model;
open Oni_IntegrationTestLib;
module Editor = Feature_Editor.Editor;

runTest(~name="RegressionLayoutTabSingleEditor", ({wait, _}) => {
wait(~name="Wait for split to be created 1", (state: State.t) => {
let splitCount =
state.layout |> Feature_Layout.visibleEditors |> List.length;
splitCount == 1;
});

// Wait for initial buffer
wait(~name="Initial buffer", state => {
let maybeFilePath =
state |> Selectors.getActiveBuffer |> Option.map(Buffer.getFilePath);

maybeFilePath != None;
});

wait(
~name="Prior to new tab, there should be a single layout",
(state: State.t) => {
let layoutCount = state.layout |> Feature_Layout.layouts |> List.length;

layoutCount == 1;
});

/* :vsp with no arguments should create a second split w/ same buffer */
ignore(Vim.command("tabnew"): (Vim.Context.t, list(Vim.Effect.t)));

wait(~name="Wait for group to be created", (state: State.t) => {
let layoutCount = state.layout |> Feature_Layout.layouts |> List.length;

layoutCount == 2;
});

wait(
~name="There should only be a single editor in the new tab",
(state: State.t) => {
let group = state.layout |> Feature_Layout.activeGroup;

let editorCount = group |> Feature_Layout.Group.allEditors |> List.length;

editorCount == 1;
});
});
5 changes: 4 additions & 1 deletion integration_test/dune
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
Regression2988SwitchEditorTest Regression3084CommandLoopTest
Regression3323DiagnosticsTest RegressionCommandLineNoCompletionTest
RegressionFontFallbackTest RegressionFileModifiedIndicationTest
RegressionNonExistentDirectory RegressionVspEmptyInitialBufferTest
RegressionNonExistentDirectory
RegressionLayoutTabSingleEditor
RegressionVspEmptyInitialBufferTest
RegressionVspEmptyExistingBufferTest SCMGitTest SyntaxHighlightPhpTest
SyntaxHighlightTextMateTest SyntaxHighlightTreesitterTest
AddRemoveSplitTest TerminalSetPidTitleTest TerminalConfigurationTest
Expand Down Expand Up @@ -58,6 +60,7 @@
Regression3084CommandLoopTest.exe
RegressionCommandLineNoCompletionTest.exe
RegressionFileModifiedIndicationTest.exe RegressionFontFallbackTest.exe
RegressionLayoutTabSingleEditor.exe
RegressionVspEmptyInitialBufferTest.exe RegressionNonExistentDirectory.exe
RegressionVspEmptyExistingBufferTest.exe SCMGitTest.exe
SearchShowClearHighlightsTest.exe SyntaxHighlightTextMateTest.exe
Expand Down
4 changes: 3 additions & 1 deletion src/Feature/Layout/Feature_Layout.re
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,9 @@ let update = (~focus, model, msg) => {

| Command(ResetSizes) => (resetWeights(model), Nothing)

| Command(AddLayout) => (addLayoutTab(model), Nothing)
| Command(AddLayout) =>
let editor = Feature_Editor.Editor.copy(activeEditor(model));
(addLayoutTab(~editor, model), Nothing);

| Command(PreviousLayout) => (
{
Expand Down
11 changes: 10 additions & 1 deletion src/Feature/Layout/Feature_Layout.rei
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,21 @@ module Group: {
let allEditors: t => list(Editor.t);
};

module LayoutTab: {
type t;

let groups: t => list(Group.t);
};

type model;

let activeGroup: model => Group.t;
let activeLayoutGroups: model => list(Group.t);
let setActiveGroup: (Group.id, model) => model;

let layouts: model => list(LayoutTab.t);
let activeLayout: model => LayoutTab.t;

let initial: list(Editor.t) => model;

let visibleEditors: model => list(Editor.t);
Expand All @@ -47,7 +56,7 @@ let activeGroupEditors: model => list(Editor.t);
let openEditor: (~config: Config.resolver, Editor.t, model) => model;
let closeBuffer: (~force: bool, Vim.Types.buffer, model) => option(model);

let addLayoutTab: model => model;
let addLayoutTab: (~editor: Editor.t, model) => model;
let gotoLayoutTab: (int, model) => model;
let previousLayoutTab: (~count: int=?, model) => model;
let nextLayoutTab: (~count: int=?, model) => model;
Expand Down
13 changes: 10 additions & 3 deletions src/Feature/Layout/Model.re
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,12 @@ type layout = {
activeGroupId: int,
};

module LayoutTab = {
type t = layout;

let groups = ({groups, _}: layout) => groups;
};

let activeTree = layout =>
switch (layout.uncommittedTree) {
| `Resizing(tree)
Expand All @@ -199,6 +205,8 @@ let initial = editors => {
{layouts: [initialLayout], activeLayoutIndex: 0};
};

let layouts = ({layouts, _}) => layouts;

let groups = ({groups, _}) => groups;

let groupById = (id, layout) =>
Expand Down Expand Up @@ -471,9 +479,8 @@ let closeBuffer = (~force, buffer, model) => {
};
};

let addLayoutTab = model => {
let newEditor = activeEditor(model) |> Editor.copy;
let newGroup = Group.create([newEditor]);
let addLayoutTab = (~editor, model) => {
let newGroup = Group.create([editor]);

let newLayout = {
tree: Layout.singleton(newGroup.id),
Expand Down
3 changes: 2 additions & 1 deletion src/Store/Features.re
Original file line number Diff line number Diff line change
Expand Up @@ -1529,7 +1529,8 @@ let update =
)
| SplitDirection.Vertical({shouldReuse}) =>
Feature_Layout.split(~shouldReuse, ~editor, `Vertical, state.layout)
| SplitDirection.NewTab => Feature_Layout.addLayoutTab(state.layout)
| SplitDirection.NewTab =>
Feature_Layout.addLayoutTab(~editor, state.layout)
};

let editor' =
Expand Down