Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Fix Navigator Key Navigation Explosion#1803

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes fromall 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
Fix Navigator Key Navigation Explosion
  • Loading branch information
@thecoolwinter
thecoolwinter committedJul 10, 2024
commit23ddb2a2369feb3f743f87846a99df46abd553fc
8 changes: 8 additions & 0 deletionsCodeEdit.xcodeproj/project.pbxproj
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -380,6 +380,7 @@
6C5B63DE29C76213005454BA /* WindowCodeFileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C5B63DD29C76213005454BA /* WindowCodeFileView.swift */; };
6C5C891B2A3F736500A94FE1 /* FocusedValues.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C5C891A2A3F736500A94FE1 /* FocusedValues.swift */; };
6C5FDF7A29E6160000BC08C0 /* AppSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C5FDF7929E6160000BC08C0 /* AppSettings.swift */; };
6C6362D42C3E321A0025570D /* Editor+History.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C6362D32C3E321A0025570D /* Editor+History.swift */; };
6C66C31329D05CDC00DE9ED2 /* GRDB in Frameworks */ = {isa = PBXBuildFile; productRef = 6C66C31229D05CDC00DE9ED2 /* GRDB */; };
6C6BD6EF29CD12E900235D17 /* ExtensionManagerWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C6BD6EE29CD12E900235D17 /* ExtensionManagerWindow.swift */; };
6C6BD6F129CD13FA00235D17 /* ExtensionDiscovery.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C6BD6F029CD13FA00235D17 /* ExtensionDiscovery.swift */; };
Expand All@@ -402,6 +403,7 @@
6C85BB402C2105ED00EB5DEF /* CodeEditKit in Frameworks */ = {isa = PBXBuildFile; productRef = 6C85BB3F2C2105ED00EB5DEF /* CodeEditKit */; };
6C85BB412C21061A00EB5DEF /* GitHubComment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587B9E3C29301D8F00AC7927 /* GitHubComment.swift */; };
6C85BB442C210EFD00EB5DEF /* SwiftUIIntrospect in Frameworks */ = {isa = PBXBuildFile; productRef = 6C85BB432C210EFD00EB5DEF /* SwiftUIIntrospect */; };
6C85F7562C3CA638008E9836 /* EditorHistoryMenus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C85F7552C3CA638008E9836 /* EditorHistoryMenus.swift */; };
6C91D57229B176FF0059A90D /* EditorManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C91D57129B176FF0059A90D /* EditorManager.swift */; };
6C97EBCC2978760400302F95 /* AcknowledgementsWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C97EBCB2978760400302F95 /* AcknowledgementsWindowController.swift */; };
6CA1AE952B46950000378EAB /* EditorInstance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CA1AE942B46950000378EAB /* EditorInstance.swift */; };
Expand DownExpand Up@@ -997,6 +999,7 @@
6C5B63DD29C76213005454BA /* WindowCodeFileView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WindowCodeFileView.swift; sourceTree = "<group>"; };
6C5C891A2A3F736500A94FE1 /* FocusedValues.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FocusedValues.swift; sourceTree = "<group>"; };
6C5FDF7929E6160000BC08C0 /* AppSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSettings.swift; sourceTree = "<group>"; };
6C6362D32C3E321A0025570D /* Editor+History.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Editor+History.swift"; sourceTree = "<group>"; };
6C6BD6EE29CD12E900235D17 /* ExtensionManagerWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionManagerWindow.swift; sourceTree = "<group>"; };
6C6BD6F029CD13FA00235D17 /* ExtensionDiscovery.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionDiscovery.swift; sourceTree = "<group>"; };
6C6BD6F529CD145F00235D17 /* ExtensionInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionInfo.swift; sourceTree = "<group>"; };
Expand All@@ -1010,6 +1013,7 @@
6C82D6B829BFE34900495C54 /* HelpCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HelpCommands.swift; sourceTree = "<group>"; };
6C82D6BB29C00CD900495C54 /* FirstResponderPropertyWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirstResponderPropertyWrapper.swift; sourceTree = "<group>"; };
6C82D6C529C012AD00495C54 /* NSApp+openWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSApp+openWindow.swift"; sourceTree = "<group>"; };
6C85F7552C3CA638008E9836 /* EditorHistoryMenus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditorHistoryMenus.swift; sourceTree = "<group>"; };
6C91D57129B176FF0059A90D /* EditorManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditorManager.swift; sourceTree = "<group>"; };
6C97EBCB2978760400302F95 /* AcknowledgementsWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AcknowledgementsWindowController.swift; sourceTree = "<group>"; };
6CA1AE942B46950000378EAB /* EditorInstance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditorInstance.swift; sourceTree = "<group>"; };
Expand DownExpand Up@@ -2308,6 +2312,7 @@
DE6F77862813625500D00A76 /* EditorTabBarDivider.swift */,
287776E827E34BC700D46668 /* EditorTabBarView.swift */,
B6AB09A22AAABFEC0003A3A6 /* EditorTabBarLeadingAccessories.swift */,
6C85F7552C3CA638008E9836 /* EditorHistoryMenus.swift */,
B6AB09A42AAAC00F0003A3A6 /* EditorTabBarTrailingAccessories.swift */,
);
path = Views;
Expand DownExpand Up@@ -2973,6 +2978,7 @@
isa = PBXGroup;
children = (
6C147C3D29A3281D0089B630 /* Editor.swift */,
6C6362D32C3E321A0025570D /* Editor+History.swift */,
5994B6D92BD6B408006A4C5F /* Editor+TabSwitch.swift */,
6CA1AE942B46950000378EAB /* EditorInstance.swift */,
6C147C3E29A3281D0089B630 /* EditorLayout.swift */,
Expand DownExpand Up@@ -3941,6 +3947,7 @@
30B088162C0D53080063A882 /* LSPCache.swift in Sources */,
B6F0517929D9E3C900D72287 /* SourceControlGitView.swift in Sources */,
587B9E8329301D8F00AC7927 /* GitHubPullRequest.swift in Sources */,
6C85F7562C3CA638008E9836 /* EditorHistoryMenus.swift in Sources */,
5878DA82291863F900DD95A3 /* AcknowledgementsView.swift in Sources */,
587B9E8529301D8F00AC7927 /* GitHubReview.swift in Sources */,
58D01C9A293167DC00C5B6B4 /* CodeEditKeychain.swift in Sources */,
Expand DownExpand Up@@ -3975,6 +3982,7 @@
30B087FC2C0D53080063A882 /* LanguageServer+CallHierarchy.swift in Sources */,
6CFF967C29BEBD5200182D6F /* WindowCommands.swift in Sources */,
587B9E7229301D8F00AC7927 /* GitJSONPostRouter.swift in Sources */,
6C6362D42C3E321A0025570D /* Editor+History.swift in Sources */,
6C85BB412C21061A00EB5DEF /* GitHubComment.swift in Sources */,
5878DAB0291D627C00DD95A3 /* EditorPathBarMenu.swift in Sources */,
04BA7C242AE2E7CD00584E1C /* SourceControlNavigatorSyncView.swift in Sources */,
Expand Down
71 changes: 71 additions & 0 deletionsCodeEdit/Features/Editor/Models/Editor+History.swift
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
//
// Editor+History.swift
// CodeEdit
//
// Created by Khan Winter on 7/9/24.
//

import Foundation

/// Methods for modifying the history list on the editor.
extension Editor {
/// Add the tab to the history list.
/// - Parameter tab: The tab to add to the history.
func addToHistory(_ tab: Tab) {
if history.first != tab {
history.prepend(tab)
}
}

/// Clear any tabs in the "future" on the history list. Resets the history offset and removes any tabs that were
/// available to navigate forwards to.
func clearFuture() {
guard historyOffset > 0 else { return } // nothing to clear, avoid an out of bounds error
history.removeFirst(historyOffset)
historyOffset = 0
}

/// Move backwards in the history list by one place.
func goBackInHistory() {
if canGoBackInHistory {
historyOffset += 1
}
}

/// Move forwards in the history list by one place.
func goForwardInHistory() {
if canGoForwardInHistory {
historyOffset -= 1
}
}

// TODO: move to @Observable so this works better
/// Warning: NOT published!
var canGoBackInHistory: Bool {
historyOffset != history.count - 1 && !history.isEmpty
}

// TODO: move to @Observable so this works better
/// Warning: NOT published!
var canGoForwardInHistory: Bool {
historyOffset != 0
}

/// Called by the ``Editor`` class when the history offset is changed.
///
/// This method updates the selected tab to the current tab in the history offset.
/// If the tab is not opened, it is opened without modifying the history list.
/// - Warning: Do not use except in the ``historyOffset``'s `didSet`.
func historyOffsetDidChange() {
let tab = history[historyOffset]

if !tabs.contains(tab) {
if let temporaryTab, tabs.contains(temporaryTab) {
closeTab(file: temporaryTab.file, fromHistory: true)
}
temporaryTab = tab
openTab(file: tab.file, fromHistory: true)
}
selectedTab = tab
}
}
65 changes: 19 additions & 46 deletionsCodeEdit/Features/Editor/Models/Editor.swift
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -35,22 +35,16 @@ final class Editor: ObservableObject, Identifiable {
}

/// The current offset in the history list.
/// When set, updates the ``selectedTab`` to the tab indicated by the offset.
/// See the ``historyOffsetDidChange()`` method for more details.
@Published var historyOffset: Int = 0 {
didSet {
let tab = history[historyOffset]

if !tabs.contains(tab) {
if let temporaryTab, tabs.contains(temporaryTab) {
closeTab(file: temporaryTab.file, fromHistory: true)
}
temporaryTab = tab
openTab(file: tab.file, fromHistory: true)
}
selectedTab = tab
historyOffsetDidChange()
}
}

/// History of tab switching.
/// Maintains the list of tabs that have been switched to.
/// - Warning: Use the ``addToHistory(_:)`` or ``clearFuture()`` methods to modify this. Do not modify directly.
@Published var history: Deque<Tab> = []

/// Currently selected tab.
Expand DownExpand Up@@ -106,22 +100,26 @@ 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.
/// - Parameters:
/// - file: The tab to close
/// - fromHistory: If `true`, does not clear tabs ahead of the ``historyOffset``
/// Used when opening tabs from the history queue where tabs ahead of the ``historyOffset`` should
/// not be removed.
func closeTab(file: CEWorkspaceFile, fromHistory: Bool = false) {
guard canCloseTab(file: file) else { return }

if temporaryTab?.file == file {
temporaryTab = nil
}
if !fromHistory {
historyOffset = 0
clearFuture()
}
if file != selectedTab?.file {
history.prepend(EditorInstance(file: file))
addToHistory(EditorInstance(file: file))
}
removeTab(file)
if let selectedTab {
history.prepend(selectedTab)
addToHistory(selectedTab)
}
// Reset change count to 0
file.fileDocument?.updateChangeCount(.changeCleared)
Expand All@@ -148,16 +146,15 @@ final class Editor: ObservableObject, Identifiable {
// Item is already opened in a tab.
guard !tabs.contains(item) || !asTemporary else {
selectedTab = item
history.prepend(item)
addToHistory(item)
return
}

switch (temporaryTab, asTemporary) {
case (.some(let tab), true):
if let index = tabs.firstIndex(of: tab) {
history.removeFirst(historyOffset)
history.prepend(item)
historyOffset = 0
clearFuture()
addToHistory(item)
tabs.remove(tab)
tabs.insert(item, at: index)
self.selectedTab = item
Expand DownExpand Up@@ -198,9 +195,8 @@ final class Editor: ObservableObject, Identifiable {

selectedTab = item
if !fromHistory {
history.removeFirst(historyOffset)
history.prepend(item)
historyOffset = 0
clearFuture()
addToHistory(item)
}
do {
try openFile(item: item)
Expand All@@ -225,31 +221,8 @@ final class Editor: ObservableObject, Identifiable {
CodeEditDocumentController.shared.addDocument(codeFile)
}

func goBackInHistory() {
if canGoBackInHistory {
historyOffset += 1
}
}

func goForwardInHistory() {
if canGoForwardInHistory {
historyOffset -= 1
}
}

// TODO: move to @Observable so this works better
/// Warning: NOT published!
var canGoBackInHistory: Bool {
historyOffset != history.count-1 && !history.isEmpty
}

// TODO: move to @Observable so this works better
/// Warning: NOT published!
var canGoForwardInHistory: Bool {
historyOffset != 0
}

/// Check if tab can be closed
///
/// If document edited it will show dialog where user can save document before closing or cancel.
private func canCloseTab(file: CEWorkspaceFile) -> Bool {
guard let codeFile = file.fileDocument else { return true }
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -89,9 +89,8 @@ struct EditorTabView: View {
if editor.selectedTab?.file != item {
let tabItem = EditorInstance(file: item)
editor.selectedTab = tabItem
editor.history.removeFirst(editor.historyOffset)
editor.history.prepend(tabItem)
editor.historyOffset = 0
editor.clearFuture()
editor.addToHistory(tabItem)
}
}

Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
//
// EditorHistoryMenus.swift
// CodeEdit
//
// Created by Khan Winter on 7/8/24.
//

import SwiftUI

struct EditorHistoryMenus: View {
@EnvironmentObject private var editorManager: EditorManager
@EnvironmentObject private var editor: Editor

var body: some View {
Group {
Menu {
ForEach(
Array(editor.history.dropFirst(editor.historyOffset+1).enumerated()),
id: \.offset
) { index, tab in
Button {
editorManager.activeEditor = editor
editor.historyOffset += index + 1
} label: {
HStack {
tab.file.icon
Text(tab.file.name)
}
}
}
} label: {
Image(systemName: "chevron.left")
.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()
}
.disabled(editor.historyOffset == editor.history.count - 1 || editor.history.isEmpty)
.help("Navigate back")

Menu {
ForEach(
Array(editor.history.prefix(editor.historyOffset).reversed().enumerated()),
id: \.offset
) { index, tab in
Button {
editorManager.activeEditor = editor
editor.historyOffset -= index + 1
} label: {
HStack {
tab.file.icon
Text(tab.file.name)
}
}
}
} label: {
Image(systemName: "chevron.right")
.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)
}
}

#Preview {
EditorHistoryMenus()
}
Loading

[8]ページ先頭

©2009-2025 Movatter.jp