diff --git a/CodeEdit.xcodeproj/project.pbxproj b/CodeEdit.xcodeproj/project.pbxproj index 4c3996deed..d7bcec78d7 100644 --- a/CodeEdit.xcodeproj/project.pbxproj +++ b/CodeEdit.xcodeproj/project.pbxproj @@ -331,14 +331,15 @@ 6C82D6B629BFDB5100495C54 /* SourceControlCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C82D6B529BFDB5100495C54 /* SourceControlCommands.swift */; }; 6C82D6B929BFE34900495C54 /* HelpCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C82D6B829BFE34900495C54 /* HelpCommands.swift */; }; 6C82D6BC29C00CD900495C54 /* FirstResponderPropertyWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C82D6BB29C00CD900495C54 /* FirstResponderPropertyWrapper.swift */; }; - 6C82D6C229C0110100495C54 /* AboutWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C82D6C129C0110100495C54 /* AboutWindow.swift */; }; 6C82D6C629C012AD00495C54 /* NSApp+openWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C82D6C529C012AD00495C54 /* NSApp+openWindow.swift */; }; 6C91D57229B176FF0059A90D /* TabManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C91D57129B176FF0059A90D /* TabManager.swift */; }; 6C97EBCC2978760400302F95 /* AcknowledgementsWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C97EBCB2978760400302F95 /* AcknowledgementsWindowController.swift */; }; - 6CAAF68A29BC9C2300A1F48A /* CodeEditApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CAAF68929BC9C2300A1F48A /* CodeEditApp.swift */; }; - 6CAAF69229BCC71C00A1F48A /* CodeEditCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CAAF69129BCC71C00A1F48A /* CodeEditCommands.swift */; }; - 6CAAF69429BCD78600A1F48A /* CommandsFixes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CAAF69329BCD78600A1F48A /* CommandsFixes.swift */; }; - 6CB9144B29BEC7F100BC47F2 /* WelcomeWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CB9144A29BEC7F100BC47F2 /* WelcomeWindow.swift */; }; + 6CAAF68A29BC9C2300A1F48A /* (null) in Sources */ = {isa = PBXBuildFile; }; + 6CAAF69229BCC71C00A1F48A /* (null) in Sources */ = {isa = PBXBuildFile; }; + 6CAAF69429BCD78600A1F48A /* (null) in Sources */ = {isa = PBXBuildFile; }; + 6CABB19E29C5591D00340467 /* NSTableViewWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CABB19C29C5591D00340467 /* NSTableViewWrapper.swift */; }; + 6CABB1A129C5593800340467 /* OverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CABB1A029C5593800340467 /* OverlayView.swift */; }; + 6CB9144B29BEC7F100BC47F2 /* (null) in Sources */ = {isa = PBXBuildFile; }; 6CBD1BC62978DE53006639D5 /* Font+Caption3.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CBD1BC52978DE53006639D5 /* Font+Caption3.swift */; }; 6CC9E4B229B5669900C97388 /* Environment+ActiveTabGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CC9E4B129B5669900C97388 /* Environment+ActiveTabGroup.swift */; }; 6CDA84AD284C1BA000C1CC3A /* TabBarContextMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CDA84AC284C1BA000C1CC3A /* TabBarContextMenu.swift */; }; @@ -351,6 +352,12 @@ B62617282964924E00E866AB /* CodeEditKit in Embed Frameworks */ = {isa = PBXBuildFile; productRef = 2801BB89290D5A8E00EBF552 /* CodeEditKit */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; B658FB3427DA9E1000EA4DBD /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B658FB3327DA9E1000EA4DBD /* Assets.xcassets */; }; B658FB3727DA9E1000EA4DBD /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B658FB3627DA9E1000EA4DBD /* Preview Assets.xcassets */; }; + 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 */; }; + B66A4E5129C917D5004573B4 /* AboutWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B66A4E5029C917D5004573B4 /* AboutWindow.swift */; }; + B66A4E5329C91831004573B4 /* CodeEditCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = B66A4E5229C91831004573B4 /* CodeEditCommands.swift */; }; + B66A4E5629C918A0004573B4 /* SceneID.swift in Sources */ = {isa = PBXBuildFile; fileRef = B66A4E5529C918A0004573B4 /* SceneID.swift */; }; B6C6A42A297716A500A3D28F /* TabBarItemCloseButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C6A429297716A500A3D28F /* TabBarItemCloseButton.swift */; }; B6C6A42E29771A8D00A3D28F /* TabBarItemButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C6A42D29771A8D00A3D28F /* TabBarItemButtonStyle.swift */; }; B6C6A43029771F7100A3D28F /* TabBarItemBackground.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C6A42F29771F7100A3D28F /* TabBarItemBackground.swift */; }; @@ -741,14 +748,11 @@ 6C82D6B529BFDB5100495C54 /* SourceControlCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourceControlCommands.swift; sourceTree = ""; }; 6C82D6B829BFE34900495C54 /* HelpCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HelpCommands.swift; sourceTree = ""; }; 6C82D6BB29C00CD900495C54 /* FirstResponderPropertyWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirstResponderPropertyWrapper.swift; sourceTree = ""; }; - 6C82D6C129C0110100495C54 /* AboutWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutWindow.swift; sourceTree = ""; }; 6C82D6C529C012AD00495C54 /* NSApp+openWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSApp+openWindow.swift"; sourceTree = ""; }; 6C91D57129B176FF0059A90D /* TabManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabManager.swift; sourceTree = ""; }; 6C97EBCB2978760400302F95 /* AcknowledgementsWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AcknowledgementsWindowController.swift; sourceTree = ""; }; - 6CAAF68929BC9C2300A1F48A /* CodeEditApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodeEditApp.swift; sourceTree = ""; }; - 6CAAF69129BCC71C00A1F48A /* CodeEditCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodeEditCommands.swift; sourceTree = ""; }; - 6CAAF69329BCD78600A1F48A /* CommandsFixes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommandsFixes.swift; sourceTree = ""; }; - 6CB9144A29BEC7F100BC47F2 /* WelcomeWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeWindow.swift; sourceTree = ""; }; + 6CABB19C29C5591D00340467 /* NSTableViewWrapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = NSTableViewWrapper.swift; path = CodeEdit/Features/QuickOpen/Views/NSTableViewWrapper.swift; sourceTree = SOURCE_ROOT; }; + 6CABB1A029C5593800340467 /* OverlayView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OverlayView.swift; sourceTree = ""; }; 6CBD1BC52978DE53006639D5 /* Font+Caption3.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Font+Caption3.swift"; sourceTree = ""; }; 6CC9E4B129B5669900C97388 /* Environment+ActiveTabGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Environment+ActiveTabGroup.swift"; sourceTree = ""; }; 6CDA84AC284C1BA000C1CC3A /* TabBarContextMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarContextMenu.swift; sourceTree = ""; }; @@ -765,6 +769,12 @@ B658FB3827DA9E1000EA4DBD /* CodeEdit.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = CodeEdit.entitlements; sourceTree = ""; }; B658FB3D27DA9E1000EA4DBD /* CodeEditTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CodeEditTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; B658FB4727DA9E1000EA4DBD /* CodeEditUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CodeEditUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + B66A4E4429C8E86D004573B4 /* CommandsFixes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CommandsFixes.swift; sourceTree = ""; }; + B66A4E4B29C9179B004573B4 /* CodeEditApp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CodeEditApp.swift; sourceTree = ""; }; + B66A4E4E29C917B8004573B4 /* WelcomeWindow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WelcomeWindow.swift; sourceTree = ""; }; + B66A4E5029C917D5004573B4 /* AboutWindow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AboutWindow.swift; sourceTree = ""; }; + B66A4E5229C91831004573B4 /* CodeEditCommands.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CodeEditCommands.swift; sourceTree = ""; }; + B66A4E5529C918A0004573B4 /* SceneID.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SceneID.swift; sourceTree = ""; }; B6C6A429297716A500A3D28F /* TabBarItemCloseButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarItemCloseButton.swift; sourceTree = ""; }; B6C6A42D29771A8D00A3D28F /* TabBarItemButtonStyle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabBarItemButtonStyle.swift; sourceTree = ""; }; B6C6A42F29771F7100A3D28F /* TabBarItemBackground.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarItemBackground.swift; sourceTree = ""; }; @@ -1080,9 +1090,9 @@ children = ( 6C186209298BF5A800C663EA /* RecentProjectsListView.swift */, 581BFB5A2926431000D251EC /* WelcomeWindowView.swift */, - 6CB9144A29BEC7F100BC47F2 /* WelcomeWindow.swift */, 581BFB5B2926431000D251EC /* WelcomeView.swift */, 581BFB5C2926431000D251EC /* WelcomeActionView.swift */, + B66A4E4E29C917B8004573B4 /* WelcomeWindow.swift */, 581BFB5E2926431000D251EC /* RecentProjectItem.swift */, ); path = Views; @@ -1103,7 +1113,7 @@ 6C4104E8297C970F00F472BA /* AboutDefaultView.swift */, 6C4104E5297C884F00F472BA /* AboutDetailView.swift */, 6C4104E2297C87A000F472BA /* BlurButtonStyle.swift */, - 6C82D6C129C0110100495C54 /* AboutWindow.swift */, + B66A4E5029C917D5004573B4 /* AboutWindow.swift */, ); path = Views; sourceTree = ""; @@ -1307,6 +1317,7 @@ 5878DAA9291D5CA100DD95A3 /* Views */ = { isa = PBXGroup; children = ( + 6CABB19C29C5591D00340467 /* NSTableViewWrapper.swift */, 5878DAA1291AE76700DD95A3 /* QuickOpenView.swift */, 5878DAA2291AE76700DD95A3 /* QuickOpenPreviewView.swift */, 5878DAA4291AE76700DD95A3 /* QuickOpenItem.swift */, @@ -1545,6 +1556,7 @@ 587B9D8629300ABD00AC7927 /* Views */ = { isa = PBXGroup; children = ( + 6CABB1A029C5593800340467 /* OverlayView.swift */, 587B9D8B29300ABD00AC7927 /* EffectView.swift */, 587B9D8729300ABD00AC7927 /* FontPickerView.swift */, 587B9D9029300ABD00AC7927 /* HelpButton.swift */, @@ -2271,7 +2283,7 @@ 6C82D6BF29C00EE300495C54 /* Utils */ = { isa = PBXGroup; children = ( - 6CAAF69329BCD78600A1F48A /* CommandsFixes.swift */, + B66A4E4429C8E86D004573B4 /* CommandsFixes.swift */, 6C82D6BB29C00CD900495C54 /* FirstResponderPropertyWrapper.swift */, ); path = Utils; @@ -2288,7 +2300,7 @@ 6CAAF68F29BCC6F900A1F48A /* WindowCommands */ = { isa = PBXGroup; children = ( - 6CAAF69129BCC71C00A1F48A /* CodeEditCommands.swift */, + B66A4E5229C91831004573B4 /* CodeEditCommands.swift */, 6CFF967729BEBCF600182D6F /* MainCommands.swift */, 6CFF967529BEBCD900182D6F /* FileCommands.swift */, 6CFF967929BEBD2400182D6F /* ViewCommands.swift */, @@ -2345,13 +2357,14 @@ D7211D4427E066D4008F2ED7 /* Localization */, B658FB3527DA9E1000EA4DBD /* Preview Content */, 58D01C85293167DC00C5B6B4 /* Utils */, - 6CAAF68929BC9C2300A1F48A /* CodeEditApp.swift */, 6C5AB9D629C1496E003B5F96 /* SceneID.swift */, 0468438427DC76E200F8E88E /* AppDelegate.swift */, 5C4BB1E028212B1E00A92FB2 /* World.swift */, B658FB3327DA9E1000EA4DBD /* Assets.xcassets */, B658FB3827DA9E1000EA4DBD /* CodeEdit.entitlements */, + B66A4E4B29C9179B004573B4 /* CodeEditApp.swift */, 04660F6027E3A68A00477777 /* Info.plist */, + B66A4E5529C918A0004573B4 /* SceneID.swift */, B658FB3127DA9E0F00EA4DBD /* WorkspaceView.swift */, 6C48D8F62972E5F300D6D205 /* WindowObserver.swift */, 28069DA527F5BD320016BC47 /* DefaultThemes */, @@ -2686,7 +2699,7 @@ 2813F93927ECC4C300E305E4 /* NavigatorSidebarView.swift in Sources */, 58F2EAF7292FB2B0004A9BDE /* SourceControlProvider.swift in Sources */, 587B9E8A29301D8F00AC7927 /* GitHubIssue.swift in Sources */, - 6CAAF69429BCD78600A1F48A /* CommandsFixes.swift in Sources */, + 6CAAF69429BCD78600A1F48A /* (null) in Sources */, DE513F54281DE5D0002260B9 /* TabBarXcode.swift in Sources */, 58798277292ECFD40085B254 /* LSPClient.swift in Sources */, 6C82D6C629C012AD00495C54 /* NSApp+openWindow.swift in Sources */, @@ -2715,6 +2728,7 @@ 58FD7609291EA1CB0051D6E4 /* CommandPaletteView.swift in Sources */, 58F2EAFC292FB2B0004A9BDE /* GitAccountItemView.swift in Sources */, 587B9E8F29301D8F00AC7927 /* BitBucketUserRouter.swift in Sources */, + B66A4E5129C917D5004573B4 /* AboutWindow.swift in Sources */, 58F2EB03292FB2B0004A9BDE /* Documentation.docc in Sources */, 2B7A583527E4BA0100D25D4E /* AppDelegate.swift in Sources */, D7012EE827E757850001E1EF /* FindNavigatorView.swift in Sources */, @@ -2752,12 +2766,12 @@ 587B9E9429301D8F00AC7927 /* BitBucketTokenConfiguration.swift in Sources */, 581BFB672926431000D251EC /* WelcomeWindowView.swift in Sources */, 58A5DFA329339F6400D1BD5D /* CommandManager.swift in Sources */, - 6C82D6C229C0110100495C54 /* AboutWindow.swift in Sources */, 58F2EAF5292FB2B0004A9BDE /* Theme.swift in Sources */, 2072FA1C280D874000C7F8D4 /* IndentUsing.swift in Sources */, 58798284292ED0FB0085B254 /* TerminalEmulatorView.swift in Sources */, 6C82D6B329BFD88700495C54 /* NavigateCommands.swift in Sources */, B6EE989227E887C600CDD8AB /* InspectorSidebarToolbarTop.swift in Sources */, + B66A4E4C29C9179B004573B4 /* CodeEditApp.swift in Sources */, 4E7F066629602E7B00BB3C12 /* CodeEditSplitViewController.swift in Sources */, 587B9E8D29301D8F00AC7927 /* GitHubAccount.swift in Sources */, 201169E72837B5CA00F92B46 /* SourceControlModel.swift in Sources */, @@ -2781,6 +2795,7 @@ 20EBB503280C327C00F3A5DA /* HistoryInspectorView.swift in Sources */, 587B9E7529301D8F00AC7927 /* String+QueryParameters.swift in Sources */, 58798219292D92370085B254 /* SearchModeModel.swift in Sources */, + B66A4E4F29C917B8004573B4 /* WelcomeWindow.swift in Sources */, 58D01C9D293167DC00C5B6B4 /* KeychainSwiftAccessOptions.swift in Sources */, 6C2C155A29B4F4CC00EA60A5 /* Variadic.swift in Sources */, 5882252B292C280D00E83CDE /* StatusBarCursorLocationLabel.swift in Sources */, @@ -2810,6 +2825,7 @@ 587B9E7A29301D8F00AC7927 /* GitHubReviewsRouter.swift in Sources */, 04540D5E27DD08C300E91B77 /* WorkspaceView.swift in Sources */, DE6F77872813625500D00A76 /* TabBarDivider.swift in Sources */, + 6CABB1A129C5593800340467 /* OverlayView.swift in Sources */, D7211D4327E066CE008F2ED7 /* Localized+Ex.swift in Sources */, 581BFB692926431000D251EC /* WelcomeActionView.swift in Sources */, 20D839AE280E0CA700B27357 /* HistoryPopoverView.swift in Sources */, @@ -2818,6 +2834,7 @@ 6CFF967A29BEBD2400182D6F /* ViewCommands.swift in Sources */, 2072FA1E280D891500C7F8D4 /* FileLocation.swift in Sources */, 587B9E6729301D8F00AC7927 /* GitLabEventData.swift in Sources */, + B66A4E4529C8E86D004573B4 /* CommandsFixes.swift in Sources */, 5882252F292C280D00E83CDE /* StatusBarClearButton.swift in Sources */, 58F2EB04292FB2B0004A9BDE /* SourceControlPreferences.swift in Sources */, 582213F0291834A500EFE361 /* AboutView.swift in Sources */, @@ -2825,7 +2842,9 @@ 6CC9E4B229B5669900C97388 /* Environment+ActiveTabGroup.swift in Sources */, 58822526292C280D00E83CDE /* StatusBarBreakpointButton.swift in Sources */, 58D01C96293167DC00C5B6B4 /* Date+Formatted.swift in Sources */, + B66A4E5629C918A0004573B4 /* SceneID.swift in Sources */, 6C53AAD829A6C4FD00EE9ED6 /* SplitView.swift in Sources */, + B66A4E5329C91831004573B4 /* CodeEditCommands.swift in Sources */, 587B9D9E29300ABD00AC7927 /* FontPickerView.swift in Sources */, 58822529292C280D00E83CDE /* StatusBarLineEndSelector.swift in Sources */, 58F2EAE7292FB2B0004A9BDE /* GeneralPreferencesView.swift in Sources */, @@ -2835,7 +2854,7 @@ B60BE8BD297A167600841125 /* AcknowledgementRowView.swift in Sources */, 587B9E6329301D8F00AC7927 /* GitLabAccount.swift in Sources */, 285FEC7027FE4B9800E57D53 /* OutlineTableViewCell.swift in Sources */, - 6CB9144B29BEC7F100BC47F2 /* WelcomeWindow.swift in Sources */, + 6CB9144B29BEC7F100BC47F2 /* (null) in Sources */, 58F2EAF8292FB2B0004A9BDE /* AccountListItemView.swift in Sources */, 587B9E7429301D8F00AC7927 /* URL+URLParameters.swift in Sources */, 581BFB6B2926431000D251EC /* RecentProjectItem.swift in Sources */, @@ -2856,7 +2875,7 @@ 587B9E8029301D8F00AC7927 /* GitHubConfiguration.swift in Sources */, 58822524292C280D00E83CDE /* StatusBarView.swift in Sources */, 587B9E7E29301D8F00AC7927 /* GitHubGistRouter.swift in Sources */, - 6CAAF69229BCC71C00A1F48A /* CodeEditCommands.swift in Sources */, + 6CAAF69229BCC71C00A1F48A /* (null) in Sources */, 581BFB682926431000D251EC /* WelcomeView.swift in Sources */, 6CFF967829BEBCF600182D6F /* MainCommands.swift in Sources */, 587B9E7129301D8F00AC7927 /* GitURLSession.swift in Sources */, @@ -2874,7 +2893,7 @@ 587B9E9529301D8F00AC7927 /* BitBucketUser.swift in Sources */, 587B9E7C29301D8F00AC7927 /* GitHubRepositoryRouter.swift in Sources */, 286471AB27ED51FD0039369D /* ProjectNavigatorView.swift in Sources */, - 6CAAF68A29BC9C2300A1F48A /* CodeEditApp.swift in Sources */, + 6CAAF68A29BC9C2300A1F48A /* (null) in Sources */, 6CFF967629BEBCD900182D6F /* FileCommands.swift in Sources */, 58798264292EC4080085B254 /* Plugin.swift in Sources */, 587B9DA629300ABD00AC7927 /* ToolbarBranchPicker.swift in Sources */, @@ -2894,6 +2913,7 @@ 58798218292D92370085B254 /* String+SafeOffset.swift in Sources */, 587B9E6129301D8F00AC7927 /* GitLabOAuthConfiguration.swift in Sources */, 587B9E6229301D8F00AC7927 /* GitLabConfiguration.swift in Sources */, + 6CABB19E29C5591D00340467 /* NSTableViewWrapper.swift in Sources */, 5879821B292D92370085B254 /* SearchResultMatchModel.swift in Sources */, 587B9E5929301D8F00AC7927 /* GitCheckoutBranchView+CheckoutBranch.swift in Sources */, 58F2EB09292FB2B0004A9BDE /* TerminalPreferences.swift in Sources */, @@ -3911,7 +3931,7 @@ repositoryURL = "https://github.com/CodeEditApp/CodeEditTextView.git"; requirement = { kind = exactVersion; - version = 0.4.0; + version = 0.5.0; }; }; 58F2EB18292FB91C004A9BDE /* XCRemoteSwiftPackageReference "Preferences" */ = { diff --git a/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index c6a1898b11..5775f34f10 100644 --- a/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -32,8 +32,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/CodeEditApp/CodeEditTextView.git", "state" : { - "revision" : "f4f2fcd856d28ba28b29574dd90a49ca27eb73ff", - "version" : "0.4.0" + "revision" : "4ff2df56b94c822e834353ce9f74836f700bff1c", + "version" : "0.5.0" } }, { diff --git a/CodeEdit/Features/CodeEditUI/Views/OverlayView.swift b/CodeEdit/Features/CodeEditUI/Views/OverlayView.swift new file mode 100644 index 0000000000..704374e09f --- /dev/null +++ b/CodeEdit/Features/CodeEditUI/Views/OverlayView.swift @@ -0,0 +1,177 @@ +// +// OverlayWindow.swift +// CodeEdit +// +// Created by Khan Winter on 3/17/23. +// + +import Foundation +import SwiftUI + +struct OverlayView: View { + @ViewBuilder + let rowViewBuilder: ((Option) -> RowView) + + @ViewBuilder + let previewViewBuilder: ((Option) -> PreviewView)? + + @Binding + var options: [Option] + + @State + var selection: Option? + + @Binding + var text: String + let title: String + let image: Image + let showsPreview: Bool + let onRowClick: ((Option) -> Void) + let onClose: (() -> Void) + let alwaysShowOptions: Bool + let optionRowHeight: CGFloat + + init( + title: String, + image: Image, + options: Binding<[Option]>, + text: Binding, + alwaysShowOptions: Bool = false, + optionRowHeight: CGFloat = 30, + content: @escaping ((Option) -> RowView), + preview: ((Option) -> PreviewView)? = nil, + onRowClick: @escaping ((Option) -> Void), + onClose: @escaping () -> Void + ) { + self.title = title + self.image = image + self._options = options + self._text = text + self.rowViewBuilder = content + self.previewViewBuilder = preview + self.onRowClick = onRowClick + self.onClose = onClose + self.showsPreview = preview != nil + self.alwaysShowOptions = alwaysShowOptions + self.optionRowHeight = optionRowHeight + } + + var body: some View { + VStack(spacing: 0) { + VStack { + HStack(alignment: .center, spacing: 0) { + image + .font(.system(size: 18)) + .foregroundColor(.secondary) + .padding(.leading, 1) + .padding(.trailing, 10) + TextField(title, text: $text) + .font(.system(size: 20, weight: .light, design: .default)) + .textFieldStyle(.plain) + .onSubmit { + if let selection { + onRowClick(selection) + } else { + NSSound.beep() + } + } + .task(id: options) { + if options.isEmpty { + selection = nil + } else { + if !options.isEmpty { + selection = options.first + } + } + } + } + .padding(.vertical, 12) + .padding(.horizontal, 12) + .foregroundColor(.primary.opacity(0.85)) + .background(EffectView(.sidebar, blendingMode: .behindWindow)) + } + if !text.isEmpty || alwaysShowOptions == true { + Divider() + .padding(0) + HStack(spacing: 0) { + if options.isEmpty { + Text("No matching options") + .font(.system(size: 17)) + .foregroundColor(.secondary) + .frame(maxWidth: showsPreview ? 272 : .infinity, maxHeight: .infinity) + } else { + NSTableViewWrapper( + data: options, + rowHeight: optionRowHeight, + selection: $selection, + itemView: rowViewBuilder + ) + .frame(maxWidth: showsPreview ? 272 : .infinity) + } + if showsPreview { + Divider() + if options.isEmpty { + Spacer() + .frame(maxWidth: .infinity) + } else { + if let selection, let previewViewBuilder { + previewViewBuilder(selection) + .frame(maxWidth: .infinity) + } else { + Text("Select an option to preview") + .frame(maxWidth: .infinity) + } + } + } + } + } + } + .overlay { + keyHandlers + } + .background(EffectView(.sidebar, blendingMode: .behindWindow)) + .edgesIgnoringSafeArea(.vertical) + .frame( + minWidth: 680, + minHeight: text.isEmpty && !alwaysShowOptions ? 19 : 400, + maxHeight: text.isEmpty && !alwaysShowOptions ? 19 : .infinity + ) + } + + @ViewBuilder + var keyHandlers: some View { + Button { + onClose() + } label: { EmptyView() } + .opacity(0) + .keyboardShortcut(.escape, modifiers: []) + .accessibilityLabel("Close Overlay") + Button { + guard selection != options.first else { + return + } + if let selection, let index = options.firstIndex(of: selection) { + self.selection = options[index-1] + } else { + selection = options.first + } + } label: { EmptyView() } + .opacity(0) + .keyboardShortcut(.upArrow, modifiers: []) + .accessibilityLabel("Select Up") + Button { + guard selection != options.last else { + return + } + if let selection, let index = options.firstIndex(of: selection) { + + self.selection = options[index+1] + } else { + selection = options.first + } + } label: { EmptyView() } + .opacity(0) + .keyboardShortcut(.downArrow, modifiers: []) + .accessibilityLabel("Select Down") + } +} diff --git a/CodeEdit/Features/CodeFile/CodeFileView.swift b/CodeEdit/Features/CodeFile/CodeFileView.swift index 28051daf80..743bd4409b 100644 --- a/CodeEdit/Features/CodeFile/CodeFileView.swift +++ b/CodeEdit/Features/CodeFile/CodeFileView.swift @@ -24,11 +24,11 @@ struct CodeFileView: View { private var cancellables = [AnyCancellable]() - private let editable: Bool + private let isEditable: Bool - init(codeFile: CodeFileDocument, editable: Bool = true) { + init(codeFile: CodeFileDocument, isEditable: Bool = true) { self.codeFile = codeFile - self.editable = editable + self.isEditable = isEditable codeFile .$content @@ -75,9 +75,10 @@ struct CodeFileView: View { tabWidth: $prefs.preferences.textEditing.defaultTabWidth, lineHeight: $prefs.preferences.textEditing.lineHeightMultiple, wrapLines: $prefs.preferences.textEditing.wrapLinesToEditorWidth, - cursorPosition: codeFile.$cursorPosition, + cursorPosition: $codeFile.cursorPosition, useThemeBackground: prefs.preferences.theme.useThemeBackground, - contentInsets: edgeInsets.nsEdgeInsets + contentInsets: edgeInsets.nsEdgeInsets, + isEditable: isEditable ) .id(codeFile.fileURL) .background { @@ -96,7 +97,6 @@ struct CodeFileView: View { } } - .disabled(!editable) // minHeight zero fixes a bug where the app would freeze if the contents of the file are empty. .frame(minHeight: .zero, maxHeight: .infinity) .onChange(of: ThemeModel.shared.selectedTheme) { newValue in diff --git a/CodeEdit/Features/Commands/ViewModels/CommandPaletteViewModel.swift b/CodeEdit/Features/Commands/ViewModels/CommandPaletteViewModel.swift index 67ebc66afc..f0b0fafe01 100644 --- a/CodeEdit/Features/Commands/ViewModels/CommandPaletteViewModel.swift +++ b/CodeEdit/Features/Commands/ViewModels/CommandPaletteViewModel.swift @@ -28,12 +28,12 @@ final class CommandPaletteViewModel: ObservableObject { func reset() { commandQuery = "" selected = nil - filteredCommands = [] + filteredCommands = CommandManager.shared.commands } func fetchMatchingCommands(val: String) { if val == "" { - self.filteredCommands = [] + self.filteredCommands = CommandManager.shared.commands return } self.filteredCommands = CommandManager.shared.commands.filter { $0.title.localizedCaseInsensitiveContains(val) } diff --git a/CodeEdit/Features/Commands/Views/CommandPaletteView.swift b/CodeEdit/Features/Commands/Views/CommandPaletteView.swift index cadb3433a8..3ad6cc8d49 100644 --- a/CodeEdit/Features/Commands/Views/CommandPaletteView.swift +++ b/CodeEdit/Features/Commands/Views/CommandPaletteView.swift @@ -27,90 +27,18 @@ struct CommandPaletteView: View { private let closePalette: () -> Void - private var commandsList: [Command] { - return $state.filteredCommands.wrappedValue.isEmpty && $state.commandQuery.wrappedValue.isEmpty ? - commandManager.commands : state.filteredCommands - } - init(state: CommandPaletteViewModel, closePalette: @escaping () -> Void) { self.state = state self.closePalette = closePalette - self.selectedItem = commandsList.first - } - - func resetState() { - self.selectedItem = nil - self.state.commandQuery = "" + state.filteredCommands = commandManager.commands } func callHandler(command: Command) { closePalette() command.closureWrapper.call() - resetState() - } - - func selectNext() { - if commandsList.isEmpty { - self.selectedItem = nil - return - } - - var idx = -1 - if self.selectedItem != nil { - idx = commandsList.firstIndex(of: self.selectedItem!) ?? -1 - } - - if idx + 1 == commandsList.count { - idx = -1 - } - - self.selectedItem = commandsList[idx + 1] - } - - func selectPrev() { - if commandsList.isEmpty { - self.selectedItem = nil - return - } - - var idx = -1 - if self.selectedItem != nil { - idx = commandsList.firstIndex(of: self.selectedItem!) ?? -1 - } - - if idx - 1 < 0 { - idx = commandsList.count - } - - self.selectedItem = commandsList[idx - 1] - } - - /// It should return bool value in order to notify underlying handler if event was handled or not. - /// So returning true - means you need to break the chain and do not pass event down the line - func onKeyDown(with event: NSEvent) -> Bool { - - switch event.keyCode { - // down arrow button - case 125: - selectNext() - return true - // up arrow button - case 126: - selectPrev() - return true - // enter button - case 36: - if let command = self.selectedItem { - callHandler(command: command) - } - return true - // esc button - case 53: - closePalette() - return true - default: - return false - } + selectedItem = nil + state.commandQuery = "" + state.filteredCommands = [] } func onQueryChange(text: String) { @@ -118,105 +46,25 @@ struct CommandPaletteView: View { state.fetchMatchingCommands(val: text) } - func onCommandClick(command: Command) { - self.selectedItem = command - callHandler(command: command) - } - - func textColor(command: Command) -> Color { - if self.selectedItem == command { - return .white - } - - return colorScheme == .dark ? .white : .black - } - var body: some View { - VStack(spacing: 0.0) { - HStack(alignment: .center, spacing: 0) { - Image(systemName: "command") - .resizable() - .scaledToFit() - .frame(width: 16, height: 16) - .padding(.leading, 20) - .offset(x: 0, y: 1) - ActionAwareInput( - text: $state.commandQuery, onDown: onKeyDown, - onTextChange: onQueryChange - ) - .font(.system(size: 24, weight: .light, design: .default)) - .padding(16) - .frame(height: 52, alignment: .center) - .foregroundColor(Color(.systemGray).opacity(0.85)) - .background(EffectView(.sidebar, blendingMode: .behindWindow)) - } - - Divider() - VStack(spacing: 0) { - List(commandsList, selection: $state.selected) { command in - // swiftlint:disable multiple_closures_with_trailing_closure - Button(action: { onCommandClick(command: command) }) { - VStack { - SearchResultLabel( - labelName: command.title, - textToMatch: state.commandQuery, - fontColor: textColor(command: command) - ) - .padding(.zero) - } - .frame(maxWidth: .infinity, maxHeight: 15, alignment: .leading) - } - .frame(maxWidth: .infinity, maxHeight: 15, alignment: .leading) - .listRowInsets(.init(top: 0, leading: 0, bottom: 0, trailing: 0)) - .padding(.init(top: 5, leading: 5, bottom: 5, trailing: 0)) - .buttonStyle(.borderless) - .background( - self.selectedItem == command ? RoundedRectangle(cornerRadius: 5, style: .continuous) - .fill(Color(red: 0, green: 0.38, blue: 0.816, opacity: 0.85)) : - RoundedRectangle(cornerRadius: 5, style: .continuous) - .fill(Color.clear) - ) - .onHover(perform: { _ in self.selectedItem = command }) - } - .listStyle(SidebarListStyle()) - } + OverlayView( + title: "Commands", + image: Image(systemName: "magnifyingglass"), + options: $state.filteredCommands, + text: $state.commandQuery, + alwaysShowOptions: true, + optionRowHeight: 30 + ) { command in + SearchResultLabel(labelName: command.title, textToMatch: state.commandQuery) + } onRowClick: { command in + callHandler(command: command) + } onClose: { + closePalette() } - .background(EffectView(.sidebar, blendingMode: .behindWindow)) - .foregroundColor(.gray) - .edgesIgnoringSafeArea(.vertical) - .frame( - minWidth: 600, - minHeight: self.state.isShowingCommandsList ? 400 : 28, - maxHeight: self.state.isShowingCommandsList ? .infinity : 28 - ) - } -} - -private class ActionAwareInputView: NSTextView, NSTextFieldDelegate { - - var onDown: ((NSEvent) -> Bool)? - var onTextChange: ((String) -> Void)? - - func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool { - return true - } - - override var acceptsFirstResponder: Bool { return true } - - override public func keyDown(with event: NSEvent) { - if onDown!(event) { - // We don't want to pass event down the pipe if it was handled. - // By handled I mean its keycode was used for something else than typing - return + .onReceive(state.$commandQuery.debounce(for: 0.2, scheduler: DispatchQueue.main)) { _ in + state.fetchMatchingCommands(val: state.commandQuery) } - - super.keyDown(with: event) - } - - override public func didChangeText() { - onTextChange?(self.string) } - } /// Implementation of command palette entity. While swiftui does not allow to use NSMutableAttributeStrings, @@ -227,16 +75,14 @@ struct SearchResultLabel: NSViewRepresentable { var labelName: String var textToMatch: String - var fontColor: Color public func makeNSView(context: Context) -> some NSTextField { let label = NSTextField(wrappingLabelWithString: labelName) label.translatesAutoresizingMaskIntoConstraints = false label.drawsBackground = false - label.textColor = NSColor(fontColor.opacity(0.55)) + label.textColor = .labelColor label.isEditable = false label.isSelectable = false - label.layer?.cornerRadius = 10.0 label.font = .labelFont(ofSize: 13) label.allowsDefaultTighteningForTruncation = false label.cell?.truncatesLastVisibleLine = true @@ -247,57 +93,20 @@ struct SearchResultLabel: NSViewRepresentable { } func highlight() -> NSAttributedString { - let attribText = NSMutableAttributedString(string: self.labelName) let range: NSRange = attribText.mutableString.range( of: self.textToMatch, options: NSString.CompareOptions.caseInsensitive ) - attribText.addAttribute(.foregroundColor, value: NSColor(fontColor.opacity(0.85)), range: range) + attribText.addAttribute(.foregroundColor, value: NSColor(Color(.labelColor)), range: range) + attribText.addAttribute(.font, value: NSFont.boldSystemFont(ofSize: NSFont.systemFontSize), range: range) return attribText } func updateNSView(_ nsView: NSViewType, context: Context) { - nsView.textColor = NSColor(fontColor.opacity(0.55)) + nsView.textColor = textToMatch.isEmpty ? .labelColor : .secondaryLabelColor nsView.attributedStringValue = highlight() } } - -/// A special NSTextView based input that allows to override onkeyDown events and add according handlers. -/// Very useful when need to use arrows to navigate through the list of items that matches entered text -private struct ActionAwareInput: NSViewRepresentable { - - @Environment(\.colorScheme) var colorScheme: ColorScheme - var fontColor: Color { - colorScheme == .dark ? .white : .black - } - - @Binding - var text: String - - var onDown: ((NSEvent) -> Bool)? - var onTextChange: ((String) -> Void) - - func makeNSView(context: Context) -> some NSTextView { - let input = ActionAwareInputView() - input.textContainer?.maximumNumberOfLines = 1 - input.onTextChange = onTextChange - input.string = text - input.onDown = onDown - input.font = .systemFont(ofSize: 20, weight: .light) - input.textColor = NSColor(fontColor) - input.drawsBackground = false - input.becomeFirstResponder() - input.invalidateIntrinsicContentSize() - - return input - } - - func updateNSView(_ nsView: NSViewType, context: Context) { - nsView.textContainer?.textView?.string = text - // This way we can update light/dark mode font color - nsView.textContainer?.textView?.textColor = NSColor(fontColor) - } -} diff --git a/CodeEdit/Features/Documents/Views/WorkspaceCodeFileView.swift b/CodeEdit/Features/Documents/Views/WorkspaceCodeFileView.swift index b9df358624..0c8323f6cc 100644 --- a/CodeEdit/Features/Documents/Views/WorkspaceCodeFileView.swift +++ b/CodeEdit/Features/Documents/Views/WorkspaceCodeFileView.swift @@ -9,13 +9,6 @@ import SwiftUI import UniformTypeIdentifiers struct WorkspaceCodeFileView: View { - - @EnvironmentObject - private var tabManager: TabManager - - @EnvironmentObject - private var tabgroup: TabGroupData - var file: WorkspaceClient.FileItem @StateObject diff --git a/CodeEdit/Features/QuickOpen/Views/NSTableViewWrapper.swift b/CodeEdit/Features/QuickOpen/Views/NSTableViewWrapper.swift new file mode 100644 index 0000000000..c538f8e0fd --- /dev/null +++ b/CodeEdit/Features/QuickOpen/Views/NSTableViewWrapper.swift @@ -0,0 +1,142 @@ +// +// NotList.swift +// CodeEdit +// +// Created by Wouter Hennen on 18/03/2023. +// + +import SwiftUI +import AppKit + +struct NSTableViewWrapper: NSViewRepresentable { + + var data: [Item] + var rowHeight: CGFloat = 50 + + @Binding var selection: Item? + + var itemView: (Item) -> Content + + class NonRespondingScrollView: NSScrollView { + override var acceptsFirstResponder: Bool { false } + } + + class NonRespondingTableView: NSTableView { + override var acceptsFirstResponder: Bool { false } + } + + func makeNSView(context: Context) -> NSScrollView { + let scrollView = NonRespondingScrollView() + scrollView.hasVerticalScroller = true + scrollView.verticalScroller?.controlSize = .mini + + let tableView = NonRespondingTableView() + tableView.headerView = nil + + let column = NSTableColumn(identifier: NSUserInterfaceItemIdentifier("column")) + column.width = tableView.frame.width + + tableView.addTableColumn(column) + tableView.delegate = context.coordinator + tableView.dataSource = context.coordinator + + scrollView.documentView = tableView + + return scrollView + } + + func updateNSView(_ nsView: NSScrollView, context: Context) { + context.coordinator.parent = self + + if let view = nsView.documentView as? NSTableView { + view.reloadData() + if let selection, let item = data.firstIndex(of: selection) { + view.selectRowIndexes([item], byExtendingSelection: false) + view.scrollRowToVisible(item) + } else { + view.selectRowIndexes([], byExtendingSelection: false) + } + } + } + + func makeCoordinator() -> Coordinator { + Coordinator(parent: self) + } + + class Coordinator: NSObject, NSTableViewDelegate, NSTableViewDataSource { + + var parent: NSTableViewWrapper + + init(parent: NSTableViewWrapper) { + self.parent = parent + } + + func numberOfRows(in tableView: NSTableView) -> Int { + return parent.data.count + } + + class AlwaysActiveTableRowView: NSTableRowView { + override var isEmphasized: Bool { + get { true } + set { } + } + } + + func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? { + AlwaysActiveTableRowView() + } + + func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat { + parent.rowHeight + } + + func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { + let view = NSHostingView(rootView: parent.itemView(parent.data[row])) + view.translatesAutoresizingMaskIntoConstraints = false + + let cell = NSTableCellView() + cell.addSubview(view) + + NSLayoutConstraint.activate([ + .init( + item: view, + attribute: .centerY, + relatedBy: .equal, + toItem: cell, + attribute: .centerY, + multiplier: 1, + constant: 0 + ), + .init( + item: view, + attribute: .left, + relatedBy: .equal, + toItem: cell, + attribute: .left, + multiplier: 1, + constant: 0 + ), + .init( + item: view, + attribute: .right, + relatedBy: .equal, + toItem: cell, + attribute: .right, + multiplier: 1, + constant: 0 + ) + ]) + + return cell + } + + func tableViewSelectionDidChange(_ notification: Notification) { + if let view = notification.object as? NSTableView { + let newSelection = parent.data[view.selectedRow] + if newSelection != parent.selection { + parent.selection = newSelection + } + } + } + } +} diff --git a/CodeEdit/Features/QuickOpen/Views/QuickOpenItem.swift b/CodeEdit/Features/QuickOpen/Views/QuickOpenItem.swift index bf2843afe1..2470c74ccd 100644 --- a/CodeEdit/Features/QuickOpen/Views/QuickOpenItem.swift +++ b/CodeEdit/Features/QuickOpen/Views/QuickOpenItem.swift @@ -20,21 +20,27 @@ struct QuickOpenItem: View { self.fileItem = fileItem } + var relativePathComponents: ArraySlice { + return fileItem.url.pathComponents.dropFirst(baseDirectory.pathComponents.count).dropLast() + } + var body: some View { HStack(spacing: 8) { Image(nsImage: NSWorkspace.shared.icon(forFile: fileItem.url.path)) .resizable() .aspectRatio(contentMode: .fit) - .frame(width: 32, height: 32) + .frame(width: 24, height: 24) VStack(alignment: .leading, spacing: 0) { Text(fileItem.url.lastPathComponent).font(.system(size: 13)) .lineLimit(1) - Text(fileItem.url.path.replacingOccurrences(of: baseDirectory.path, with: "")) - .font(.system(size: 11)) + Text(relativePathComponents.joined(separator: " ▸ ")) + .font(.system(size: 10.5)) + .foregroundColor(.secondary) .lineLimit(1) - .truncationMode(.tail) - }.padding(.trailing, 15) - Spacer() + .truncationMode(.middle) + } + .frame(maxWidth: .infinity, alignment: .leading) } + .frame(maxWidth: .infinity) } } diff --git a/CodeEdit/Features/QuickOpen/Views/QuickOpenPreviewView.swift b/CodeEdit/Features/QuickOpen/Views/QuickOpenPreviewView.swift index 6de0a18a3c..493fcbf0c4 100644 --- a/CodeEdit/Features/QuickOpen/Views/QuickOpenPreviewView.swift +++ b/CodeEdit/Features/QuickOpen/Views/QuickOpenPreviewView.swift @@ -34,7 +34,7 @@ struct QuickOpenPreviewView: View { withContentsOf: item.url, ofType: "public.source-code" ), loaded { - CodeFileView(codeFile: codeFile, editable: false) + CodeFileView(codeFile: codeFile, isEditable: false) } else if let error = error { Text(error) } else { diff --git a/CodeEdit/Features/QuickOpen/Views/QuickOpenView.swift b/CodeEdit/Features/QuickOpen/Views/QuickOpenView.swift index 40138b445f..cc8536976d 100644 --- a/CodeEdit/Features/QuickOpen/Views/QuickOpenView.swift +++ b/CodeEdit/Features/QuickOpen/Views/QuickOpenView.swift @@ -29,59 +29,24 @@ struct QuickOpenView: View { } var body: some View { - VStack(spacing: 0.0) { - VStack { - HStack(alignment: .center, spacing: 0) { - Image(systemName: "doc.text.magnifyingglass") - .resizable() - .scaledToFit() - .frame(width: 20, height: 20) - .padding(.trailing, 12) - .offset(x: 0, y: 1) - TextField("Open Quickly", text: $state.openQuicklyQuery) - .font(.system(size: 20, weight: .light, design: .default)) - .textFieldStyle(.plain) - .onReceive( - state.$openQuicklyQuery - .debounce(for: .seconds(0.4), scheduler: DispatchQueue.main) - ) { _ in - state.fetchOpenQuickly() - } - } - .padding(16) - .foregroundColor(.primary.opacity(0.85)) - .background(EffectView(.sidebar, blendingMode: .behindWindow)) - } - Divider() - NavigationView { - List(state.openQuicklyFiles, id: \.id) { file in - NavigationLink(tag: file, selection: $selectedItem) { - QuickOpenPreviewView(item: file) - } label: { - QuickOpenItem(baseDirectory: state.fileURL, fileItem: file) - } - .onTapGesture(count: 2) { - self.openFile(file) - self.onClose() - } - .onTapGesture(count: 1) { - self.selectedItem = file - } - } - .frame(minWidth: 250, maxWidth: 250) - if state.openQuicklyFiles.isEmpty { - EmptyView() - } else { - Text("Select a file to preview") - } - } + OverlayView( + title: "Open Quickly", + image: Image(systemName: "magnifyingglass"), + options: $state.openQuicklyFiles, + text: $state.openQuicklyQuery, + optionRowHeight: 40 + ) { file in + QuickOpenItem(baseDirectory: state.fileURL, fileItem: file) + } preview: { file in + QuickOpenPreviewView(item: file) + } onRowClick: { file in + openFile(file) + onClose() + } onClose: { + onClose() + } + .onReceive(state.$openQuicklyQuery.debounce(for: 0.2, scheduler: DispatchQueue.main)) { _ in + state.fetchOpenQuickly() } - .background(EffectView(.sidebar, blendingMode: .behindWindow)) - .edgesIgnoringSafeArea(.vertical) - .frame( - minWidth: 600, - minHeight: self.state.isShowingOpenQuicklyFiles ? 400 : 28, - maxHeight: self.state.isShowingOpenQuicklyFiles ? .infinity : 28 - ) } } diff --git a/CodeEdit/Features/WindowCommands/ViewCommands.swift b/CodeEdit/Features/WindowCommands/ViewCommands.swift index 54311d8a09..44e44b2b16 100644 --- a/CodeEdit/Features/WindowCommands/ViewCommands.swift +++ b/CodeEdit/Features/WindowCommands/ViewCommands.swift @@ -13,7 +13,7 @@ struct ViewCommands: Commands { Button("Show Command Palette") { NSApp.sendAction(#selector(CodeEditWindowController.openCommandPalette(_:)), to: nil, from: nil) } - .keyboardShortcut("p") + .keyboardShortcut("p", modifiers: [.shift, .command]) Button("Customize Toolbar...") {