CodeEdit icon indicating copy to clipboard operation
CodeEdit copied to clipboard

✨ Terminal Utility: Tabs & Split View

Open Angelk90 opened this issue 2 years ago • 21 comments

Describe the solution you'd like

Being able to have more than one shell in a project would be great.

image

Please note the following behaviors:

  • The plus icon adds a new terminal tab (not in a group).
  • The minus button closes the selected tab.
  • Press the delete key while terminal tab sidebar is in focus to close the selected tab.
  • Drag an ungrouped terminal tab on top of another ungrouped terminal tab to create a group.
  • Drag an ungrouped terminal tab into an existing group to add it to that group.
  • Drag a terminal tab within a group to reorder it.
  • Drag a grouped terminal tab to another group to move it to another group.

Describe alternatives you've considered

Here are some examples of how it handles Webstorm:

Schermata 2022-04-02 alle 09 40 31 Schermata 2022-04-02 alle 09 41 17 Schermata 2022-04-02 alle 09 42 11

https://user-images.githubusercontent.com/806104/161374050-7e8cc0b5-e731-49a3-a7de-6fd41328adea.mp4

Additional context

Schermata 2022-04-02 alle 09 37 02

Depends on

  • #350

Angelk90 avatar Apr 02 '22 07:04 Angelk90

@austincondiff : What program is that in the video?

Opening would be better like this:

https://user-images.githubusercontent.com/20476002/161380192-008982d6-21b6-4ff2-8dfd-be3218f894b3.mov

Angelk90 avatar Apr 02 '22 11:04 Angelk90

@Angelk90 I agree that it should open as a drawer like in your video. That video is from VSCode, and demonstrates how it handles terminal tabs and split terminal views. The question we need to answer for this is how are we going to do multiple terminals in this drawer? Will we use tabs? How will we handle split terminals? Will terminals be the only thing that exists in this drawer or will there be other kinds of things like output, issues, debug, console, etc.?

austincondiff avatar Apr 03 '22 05:04 austincondiff

This is the design that we will use for multiple terminals. We need this tab system in place in the status bar and the git controls moved up to the toolbar first, then in the terminal tab build the multiple terminal tabs UI, this is how this would look.

01-macOS-code-edit-alternate-ui-drawer-tabs-terminal

Please note the following behaviors:

  • The plus icon adds a new terminal tab (not in a group).
  • The minus button closes the selected tab.
  • Press the delete key while terminal tab sidebar is in focus to close the selected tab.
  • Drag an ungrouped terminal tab on top of another ungrouped terminal tab to create a group.
  • Drag an ungrouped terminal tab into an existing group to add it to that group.
  • Drag a terminal tab within a group to reorder it.
  • Drag a grouped terminal tab to another group to move it to another group.

(updated in issue description)

austincondiff avatar Apr 12 '22 15:04 austincondiff

I would like to work on this issue. Can you please assign this to me

amit-srt avatar Sep 02 '22 21:09 amit-srt

I'd like to work on this, can you please assign it to me? @austincondiff

ahmdyasser avatar Oct 04 '22 14:10 ahmdyasser

@ahmdyasser Assigned. Let me know if you have any questions.

austincondiff avatar Oct 04 '22 22:10 austincondiff

@ahmdyasser I just wanted to check if you were still working on this or if you needed any help with anything?

austincondiff avatar Nov 04 '22 20:11 austincondiff

HI @austincondiff, I got a bit busy, you can re-assign it if anyone is up to it.

ahmdyasser avatar Nov 05 '22 15:11 ahmdyasser

@austincondiff assign me this please!

bombardier200 avatar Nov 17 '22 13:11 bombardier200

@bombardier200 You have been assigned, might want to clone @ahmdyasser 's branch so you have some boilerplate.

matthijseikelenboom avatar Nov 17 '22 13:11 matthijseikelenboom

Can you assign me this issue. I will work on this @austincondiff

gokul1099 avatar Jun 19 '23 10:06 gokul1099

@gokul1099 done, if you have questions feel free to ping me,

bombardier200 avatar Jun 19 '23 12:06 bombardier200

@bombardier200 I am working on the Drag to group functionality. Currently I implemented onDrag and onDrop on the terminal list view and wrote the DropDelagate. Dragging is working, while dropping I can access the terminal being dragged. But I could not access the terminal or group on which dragged terminal is dropped. Do you have any idea on how to get that? here is my link to file where I have added the DropDelegate https://github.com/gokul1099/CodeEdit/blob/terminal-tabs-split-view/CodeEdit/Features/DebugArea/Views/DebugAreaTerminalView.swift

gokul1099 avatar Jun 28 '23 16:06 gokul1099

@gokul1099 can you include a video? It will help me see what exactly you are talking about

bombardier200 avatar Jun 28 '23 16:06 bombardier200

https://github.com/CodeEditApp/CodeEdit/assets/42144106/d1125933-7c33-4394-a2f6-e4e913be7fd2

In the above video, while dragging I could access the terminal being dragged (third terminal). I want to access the second terminal also(as the dragged terminal is dropped on this), So that I can group both of them.

gokul1099 avatar Jun 28 '23 16:06 gokul1099

Hi @austincondiff, I'd like to tackle this!

Here are a few assumptions I'm going with, based on what I've read here so far or what I think. Please correct me if any of them are wrong.

  • Groups cannot be nested
  • If there's multiple terminals/groups selected, show CEContentUnavailableView("Multiple Selection")
  • Selecting a group focuses the first terminal in that group
  • Selecting a terminal focuses that terminal, unless its in a different group, in which case it switches to that group

Here's an alternative, which is what I was expecting until I saw your design which contradicted with it:

  • Selecting a group displays all of its terminals on the right-hand side, the first terminal starts focused
  • Selecting a terminal displays only that terminal on the right-hand side

Lancelotbronner avatar Dec 23 '23 11:12 Lancelotbronner

Since names are getting quite long in this area, I have a little rename suggestion. It would also make sense with the way the folders are laid out.

Here's what I mean:

  • UtilityAreaTerminalView -> TerminalUtilityView
  • UtilityAreaTerminalTab -> TerminalUtilityTab
  • UtilityAreaDebugView -> DebugUtilityView
  • UtilityAreaOutputView -> OutputUtilityView

That way things which relate to the utility area as a whole are prefixed with UtilityArea while individual utilities have shorter names.

I'm suggesting this because I'm getting names like

  • UtilityAreaTerminalSelection -> TerminalUtilitySelection
  • UtilityAreaTerminalGroup -> TerminalUtilityGroup
  • UtilityAreaTerminalTerminalView -> TerminalUtilityTerminalView

Lancelotbronner avatar Dec 23 '23 12:12 Lancelotbronner

I am in favor of those name changes. We still need to figure out a good way to represent the groups. Since the creation of this issue, our utility area has changed quite a bit. If you are able to join our weekly meetup at 3 PM UTC on Discord (15 minutes after the time of posting) we can discuss this as a group.

austincondiff avatar Dec 23 '23 15:12 austincondiff

Okay so I think this is how we should represent groups (I've also updated the issue description with this)...

image

As you can see, when a tab is split, both are under a group. By default the name of the group reflects how many terminals are in the split. The user can later however rename the group to whatever they want.

austincondiff avatar Dec 23 '23 18:12 austincondiff

Ah sorry I hadn't seen your message earlier I would've liked to be at that meeting!

Great for the naming changes, I'll make a separate PR for that later.

The rest seems good, I got terminals side-by-side and grouping with a few small issues left.

I should be able to finish this tomorrow!

Lancelotbronner avatar Dec 23 '23 20:12 Lancelotbronner

Forgot about Christmas and somehow this counts the contents of the disclosure group as separate indices in the onMove function. This may take longer than expected.

List(selection: $model.selectedTerminals) {
  ForEach(model.terminalGroups) { group
    UtilityAreaTerminalTab(group)
  }
}

// UtilityAreaTerminalTab
if group.children.count == 1 {
    /* Terminal cell */
        .id(group.children[0])
} else {
    DisclosureGroup {
        ForEach(group.children) { terminal in
            /* Terminal cell */ 
        }
    } label: {
        /* Terminal group title cell */
    }
}

Lancelotbronner avatar Dec 24 '23 21:12 Lancelotbronner