Skip to content

Commit

Permalink
Navigation style setting and file history navigation improvements (#1603
Browse files Browse the repository at this point in the history
)

* Added navigation style setting

* Added navigation style setting

* If one editors tab bar should be shown, all tab bars should be shown across other editors

* Removed complete TODO comment

* When there is only one tab in an editor and the navigation style changes to open in place, we change the tab to be termporary so that tab bar will hide

* Invalidating flattenedEditors cache when editors change.

* New editors open first tab as a temporary tab.

* History improvements - if going back or forward in history to a file for a teb that was previously closed, we now open it as a temporary tab

* Update CodeEditSourceEditor dependency version

* Invalidating flattenedEditors cache when closing an editor

* Removing last change

* Fixed PR issue.
  • Loading branch information
austincondiff authored Mar 12, 2024
1 parent 7c773f9 commit 4d9a5d4
Show file tree
Hide file tree
Showing 17 changed files with 259 additions and 58 deletions.
36 changes: 30 additions & 6 deletions CodeEdit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,8 @@
B65B10FE2B08B07D002852CF /* SourceControlNavigatorChangesList.swift in Sources */ = {isa = PBXBuildFile; fileRef = B65B10FD2B08B07D002852CF /* SourceControlNavigatorChangesList.swift */; };
B65B11012B09D5D4002852CF /* GitClient+Pull.swift in Sources */ = {isa = PBXBuildFile; fileRef = B65B11002B09D5D4002852CF /* GitClient+Pull.swift */; };
B65B11042B09DB1C002852CF /* GitClient+Fetch.swift in Sources */ = {isa = PBXBuildFile; fileRef = B65B11032B09DB1C002852CF /* GitClient+Fetch.swift */; };
B664C3B02B965F6C00816B4E /* NavigationSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = B664C3AF2B965F6C00816B4E /* NavigationSettings.swift */; };
B664C3B32B96634F00816B4E /* NavigationSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B664C3B22B96634F00816B4E /* NavigationSettingsView.swift */; };
B66A4E4529C8E86D004573B4 /* CommandsFixes.swift in Sources */ = {isa = PBXBuildFile; fileRef = B66A4E4429C8E86D004573B4 /* CommandsFixes.swift */; };
B66A4E4C29C9179B004573B4 /* CodeEditApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = B66A4E4B29C9179B004573B4 /* CodeEditApp.swift */; };
B66A4E4F29C917B8004573B4 /* WelcomeWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B66A4E4E29C917B8004573B4 /* WelcomeWindow.swift */; };
Expand Down Expand Up @@ -953,6 +955,8 @@
B65B10FD2B08B07D002852CF /* SourceControlNavigatorChangesList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourceControlNavigatorChangesList.swift; sourceTree = "<group>"; };
B65B11002B09D5D4002852CF /* GitClient+Pull.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GitClient+Pull.swift"; sourceTree = "<group>"; };
B65B11032B09DB1C002852CF /* GitClient+Fetch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GitClient+Fetch.swift"; sourceTree = "<group>"; };
B664C3AF2B965F6C00816B4E /* NavigationSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationSettings.swift; sourceTree = "<group>"; };
B664C3B22B96634F00816B4E /* NavigationSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationSettingsView.swift; sourceTree = "<group>"; };
B66A4E4429C8E86D004573B4 /* CommandsFixes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CommandsFixes.swift; sourceTree = "<group>"; };
B66A4E4B29C9179B004573B4 /* CodeEditApp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CodeEditApp.swift; sourceTree = "<group>"; };
B66A4E4E29C917B8004573B4 /* WelcomeWindow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WelcomeWindow.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1218,13 +1222,13 @@
287776EA27E350A100D46668 /* NavigatorArea */ = {
isa = PBXGroup;
children = (
307AC4CB2ABABD9800163376 /* ViewModels */,
D7012EE627E757660001E1EF /* FindNavigator */,
581550CB29FBD30400684881 /* OutlineView */,
286471AC27ED52950039369D /* ProjectNavigator */,
201169D52837B29600F92B46 /* SourceControlNavigator */,
B67660682AA972D400CD56B0 /* Models */,
B67660692AA972DC00CD56B0 /* Views */,
307AC4CB2ABABD9800163376 /* ViewModels */,
);
path = NavigatorArea;
sourceTree = "<group>";
Expand Down Expand Up @@ -2494,16 +2498,17 @@
B61DA9DD29D929BF00BF4A43 /* Pages */ = {
isa = PBXGroup;
children = (
B664C3AD2B965F4500816B4E /* NavigationSettings */,
B61DA9E129D929F900BF4A43 /* GeneralSettings */,
B6E41C6E29DD15540088F9F4 /* AccountsSettings */,
58F2EAAE292FB2B0004A9BDE /* ThemeSettings */,
B6EA1FF329DA37D3001BF195 /* TextEditingSettings */,
5B698A082B262F8400DE9392 /* SearchSettings */,
6C5BE51A2A3D5419002DA0FC /* FeatureFlags */,
B6CF632629E5417C0085880A /* Keybindings */,
B6E41C6E29DD15540088F9F4 /* AccountsSettings */,
B6EA1FF329DA37D3001BF195 /* TextEditingSettings */,
B6F0516E29D9E35300D72287 /* LocationsSettings */,
B6F0516D29D9E34200D72287 /* SourceControlSettings */,
B6F0516C29D9E32700D72287 /* TerminalSettings */,
58F2EAAE292FB2B0004A9BDE /* ThemeSettings */,
B61DA9E129D929F900BF4A43 /* GeneralSettings */,
);
path = Pages;
sourceTree = "<group>";
Expand Down Expand Up @@ -2604,6 +2609,23 @@
path = "Preview Content";
sourceTree = "<group>";
};
B664C3AD2B965F4500816B4E /* NavigationSettings */ = {
isa = PBXGroup;
children = (
B664C3AE2B965F5500816B4E /* Models */,
B664C3B22B96634F00816B4E /* NavigationSettingsView.swift */,
);
path = NavigationSettings;
sourceTree = "<group>";
};
B664C3AE2B965F5500816B4E /* Models */ = {
isa = PBXGroup;
children = (
B664C3AF2B965F6C00816B4E /* NavigationSettings.swift */,
);
path = Models;
sourceTree = "<group>";
};
B66DD19E2B3C0E0C0004FFEC /* History */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -3215,6 +3237,7 @@
587B9E9229301D8F00AC7927 /* BitBucketAccount.swift in Sources */,
DE513F52281B672D002260B9 /* EditorTabBarAccessory.swift in Sources */,
2813F93927ECC4C300E305E4 /* NavigatorAreaView.swift in Sources */,
B664C3B02B965F6C00816B4E /* NavigationSettings.swift in Sources */,
5B698A0F2B2636A700DE9392 /* SearchSettingsIgnoreGlobPatternItemView.swift in Sources */,
587B9E8A29301D8F00AC7927 /* GitHubIssue.swift in Sources */,
EC0870F72A455F6400EB8692 /* ProjectNavigatorViewController+NSMenuDelegate.swift in Sources */,
Expand Down Expand Up @@ -3263,6 +3286,7 @@
611192042B08CCED00D4459B /* SearchIndexer+ProgressiveSearch.swift in Sources */,
611192022B08CCDC00D4459B /* SearchIndexer+Search.swift in Sources */,
04BA7C272AE2E9F100584E1C /* GitClient+Push.swift in Sources */,
B664C3B32B96634F00816B4E /* NavigationSettingsView.swift in Sources */,
2B7A583527E4BA0100D25D4E /* AppDelegate.swift in Sources */,
D7012EE827E757850001E1EF /* FindNavigatorView.swift in Sources */,
58A5DF8029325B5A00D1BD5D /* GitClient.swift in Sources */,
Expand Down Expand Up @@ -4593,7 +4617,7 @@
repositoryURL = "https://github.com/CodeEditApp/CodeEditSourceEditor";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 0.7.1;
minimumVersion = 0.7.2;
};
};
6CDEFC9429E22C2700B7C684 /* XCRemoteSwiftPackageReference "SwiftUI-Introspect" */ = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/CodeEditApp/CodeEditSourceEditor",
"state" : {
"revision" : "a72e6c9b5f38b00ea0b03da5e706e3c4d05c706e",
"version" : "0.7.1"
"revision" : "7360f00bf7ec8e93b4833357bd254bef7e5c943d",
"version" : "0.7.2"
}
},
{
Expand Down
2 changes: 1 addition & 1 deletion CodeEdit/Features/CodeEditUI/Views/SegmentedControl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ struct SegmentedControl: View {
}

var body: some View {
HStack(spacing: 8) {
HStack(spacing: 4) {
ForEach(options.indices, id: \.self) { index in
SegmentedControlItem(
label: options[index],
Expand Down
22 changes: 15 additions & 7 deletions CodeEdit/Features/Editor/Models/Editor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ final class Editor: ObservableObject, Identifiable {
let tab = history[historyOffset]

if !tabs.contains(tab) {
if let selectedTab {
openTab(file: tab.file, at: tabs.firstIndex(of: selectedTab), fromHistory: true)
} else {
openTab(file: tab.file, fromHistory: true)
if let temporaryTab, tabs.contains(temporaryTab) {
closeTab(file: temporaryTab.file, fromHistory: true)
}
temporaryTab = tab
openTab(file: tab.file, fromHistory: true)
}
selectedTab = tab
}
Expand All @@ -64,29 +64,34 @@ final class Editor: ObservableObject, Identifiable {

init() {
self.tabs = []
self.temporaryTab = nil
self.parent = nil
}

init(
files: OrderedSet<CEWorkspaceFile> = [],
selectedTab: Tab? = nil,
temporaryTab: Tab? = nil,
parent: SplitViewData? = nil
) {
self.tabs = []
self.parent = parent
files.forEach { openTab(file: $0) }
self.selectedTab = selectedTab ?? (files.isEmpty ? nil : Tab(file: files.first!))
self.temporaryTab = temporaryTab
}

init(
files: OrderedSet<Tab> = [],
selectedTab: Tab? = nil,
temporaryTab: Tab? = nil,
parent: SplitViewData? = nil
) {
self.tabs = []
self.parent = parent
files.forEach { openTab(file: $0.file) }
self.selectedTab = selectedTab ?? tabs.first
self.temporaryTab = temporaryTab
}

/// Closes the editor.
Expand All @@ -102,14 +107,15 @@ final class Editor: ObservableObject, Identifiable {
/// Closes a tab in the editor.
/// This will also write any changes to the file on disk and will add the tab to the tab history.
/// - Parameter item: the tab to close.
func closeTab(file: CEWorkspaceFile) {
func closeTab(file: CEWorkspaceFile, fromHistory: Bool = false) {
guard canCloseTab(file: file) else { return }

if temporaryTab?.file == file {
temporaryTab = nil
}

historyOffset = 0
if !fromHistory {
historyOffset = 0
}
if file != selectedTab?.file {
history.prepend(EditorInstance(file: file))
}
Expand Down Expand Up @@ -149,7 +155,9 @@ final class Editor: ObservableObject, Identifiable {
switch (temporaryTab, asTemporary) {
case (.some(let tab), true):
if let index = tabs.firstIndex(of: tab) {
history.removeFirst(historyOffset)
history.prepend(item)
historyOffset = 0
tabs.remove(tab)
tabs.insert(item, at: index)
self.selectedTab = item
Expand Down
18 changes: 18 additions & 0 deletions CodeEdit/Features/Editor/Models/EditorLayout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,24 @@ enum EditorLayout: Equatable {
}
}

/// Gets flattened splitviews.
func getFlattened(parent: SplitViewData) -> [Editor] {
switch self {
case .one(let editor):
return [editor]
case .horizontal(let data), .vertical(let data):
if data.editorLayouts.count == 1 {
let one = data.editorLayouts[0]
if case .one(let editor) = one {
return [editor]
}
return []
} else {
return data.getFlattened()
}
}
}

var isEmpty: Bool {
switch self {
case .one:
Expand Down
29 changes: 26 additions & 3 deletions CodeEdit/Features/Editor/Models/EditorManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,17 @@ class EditorManager: ObservableObject {
var tabBarTabIdSubject = PassthroughSubject<String?, Never>()
var cancellable: AnyCancellable?

// This caching mechanism is a temporary solution and is not optimized
@Published var updateCachedFlattenedEditors: Bool = true
var cachedFlettenedEditors: [Editor] = []
var flattenedEditors: [Editor] {
if updateCachedFlattenedEditors {
cachedFlettenedEditors = self.getFlattened()
updateCachedFlattenedEditors = false
}
return cachedFlettenedEditors
}

// MARK: - Init

init() {
Expand All @@ -61,10 +72,21 @@ class EditorManager: ObservableObject {

/// Flattens the splitviews.
func flatten() {
if case .horizontal(let data) = editorLayout {
data.flatten()
} else if case .vertical(let data) = editorLayout {
switch editorLayout {
case .horizontal(let data), .vertical(let data):
data.flatten()
default:
break
}
}

/// Returns and array of flattened splitviews.
func getFlattened() -> [Editor] {
switch editorLayout {
case .horizontal(let data), .vertical(let data):
return data.getFlattened()
default:
return []
}
}

Expand Down Expand Up @@ -99,6 +121,7 @@ class EditorManager: ObservableObject {

flatten()
objectWillChange.send()
updateCachedFlattenedEditors = true
}

/// Set a new active editor.
Expand Down
17 changes: 15 additions & 2 deletions CodeEdit/Features/Editor/PathBar/Views/EditorPathBarView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import SwiftUI

struct EditorPathBarView: View {
private let file: CEWorkspaceFile?
private let shouldShowTabBar: Bool
private let tappedOpenFile: (CEWorkspaceFile) -> Void

@Environment(\.colorScheme)
Expand All @@ -20,13 +21,15 @@ struct EditorPathBarView: View {
@Environment(\.controlActiveState)
private var activeState

static let height = 27.0
static let height = 28.0

init(
file: CEWorkspaceFile?,
shouldShowTabBar: Bool,
tappedOpenFile: @escaping (CEWorkspaceFile) -> Void
) {
self.file = file ?? nil
self.shouldShowTabBar = shouldShowTabBar
self.tappedOpenFile = tappedOpenFile
}

Expand Down Expand Up @@ -63,7 +66,17 @@ struct EditorPathBarView: View {
}
}
}
.padding(.horizontal, 10)
}
.padding(.horizontal, shouldShowTabBar ? (file == nil ? 10 : 4) : 0)
.safeAreaInset(edge: .leading, spacing: 0) {
if !shouldShowTabBar {
EditorTabBarLeadingAccessories()
}
}
.safeAreaInset(edge: .trailing, spacing: 0) {
if !shouldShowTabBar {
EditorTabBarTrailingAccessories()
}
}
.frame(height: Self.height, alignment: .center)
.opacity(activeState == .inactive ? 0.8 : 1.0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,9 @@ struct EditorTabBarLeadingAccessories: View {
}
} label: {
Image(systemName: "chevron.left")
.controlSize(.regular)
.opacity(
editor.historyOffset == editor.history.count-1 || editor.history.isEmpty
? 0.5 : 1.0
)
.opacity(editor.historyOffset == editor.history.count-1 || editor.history.isEmpty ? 0.5 : 1)
.frame(height: EditorTabBarView.height - 2)
.padding(.horizontal, 4)
} primaryAction: {
editorManager.activeEditor = editor
editor.goBackInHistory()
Expand All @@ -103,20 +101,19 @@ struct EditorTabBarLeadingAccessories: View {
}
} label: {
Image(systemName: "chevron.right")
.controlSize(.regular)
.opacity(editor.historyOffset == 0 ? 0.5 : 1.0)
.opacity(editor.historyOffset == 0 ? 0.5 : 1)
.frame(height: EditorTabBarView.height - 2)
.padding(.horizontal, 4)
} primaryAction: {
editorManager.activeEditor = editor
editor.goForwardInHistory()
}
.disabled(editor.historyOffset == 0)
.help("Navigate forward")
}
.buttonStyle(.icon)
.controlSize(.small)
.font(EditorTabBarAccessoryIcon.iconFont)
.frame(height: EditorTabBarView.height - 2)
.padding(.horizontal, 4)
.contentShape(Rectangle())
}
.foregroundColor(.secondary)
.buttonStyle(.plain)
Expand All @@ -136,9 +133,3 @@ struct EditorTabBarLeadingAccessories: View {
}
}
}

struct TabBarLeadingAccessories_Previews: PreviewProvider {
static var previews: some View {
EditorTabBarLeadingAccessories()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,12 @@ struct EditorTabBarTrailingAccessories: View {
func split(edge: Edge) {
let newEditor: Editor
if let tab = editor.selectedTab {
newEditor = .init(files: [tab])
newEditor = .init(files: [tab], temporaryTab: tab)
} else {
newEditor = .init()
}
splitEditor(edge, newEditor)
editorManager.updateCachedFlattenedEditors = true
editorManager.activeEditor = newEditor
}
}
Expand Down
Loading

0 comments on commit 4d9a5d4

Please sign in to comment.