From d7bade63ed0485f748c230d1746abf88b07c06a5 Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Thu, 9 Mar 2023 16:55:49 -0600 Subject: [PATCH 01/32] Update feature_request.yml --- .github/ISSUE_TEMPLATE/feature_request.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index d861e8d3f3..82ea0e1881 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -4,22 +4,23 @@ title: ✨ YOUR_DESCRIPTION labels: enhancement body: - - type: input + - type: markdown attributes: label: Is your feature request related to a problem? Please describe. placeholder: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] validations: required: false - - type: textarea + - type: markdown attributes: label: Describe the solution you'd like + value: "### Description" placeholder: >- - A clear and concise description of what you want to happen. + A clear and concise description of what you would like to happen. validations: required: true - - type: textarea + - type: markdown attributes: label: Describe alternatives you've considered placeholder: >- @@ -27,7 +28,7 @@ body: validations: required: true - - type: textarea + - type: markdown attributes: label: Additional context placeholder: >- From 03120733552b25ad2088047ece1d1dba87b4c2d2 Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Thu, 9 Mar 2023 16:56:46 -0600 Subject: [PATCH 02/32] Update feature_request.yml --- .github/ISSUE_TEMPLATE/feature_request.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 82ea0e1881..9c6f09777a 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -7,6 +7,7 @@ body: - type: markdown attributes: label: Is your feature request related to a problem? Please describe. + value: "### Problem" placeholder: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] validations: required: false @@ -23,6 +24,7 @@ body: - type: markdown attributes: label: Describe alternatives you've considered + value: "### Alternatives" placeholder: >- A clear and concise description of any alternative solutions or features you've considered. validations: @@ -31,6 +33,7 @@ body: - type: markdown attributes: label: Additional context + value: "### Context" placeholder: >- Add any other context or screenshots about the feature request here. validations: From 513663a590a68136ff2fb911a4e34d17d77c40c6 Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Thu, 9 Mar 2023 17:00:58 -0600 Subject: [PATCH 03/32] Update feature_request.yml --- .github/ISSUE_TEMPLATE/feature_request.yml | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 9c6f09777a..fbf6f92634 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -4,36 +4,33 @@ title: ✨ YOUR_DESCRIPTION labels: enhancement body: - - type: markdown + - type: textarea attributes: label: Is your feature request related to a problem? Please describe. - value: "### Problem" + render: "TEST" placeholder: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] validations: required: false - - type: markdown + - type: textarea attributes: label: Describe the solution you'd like - value: "### Description" placeholder: >- A clear and concise description of what you would like to happen. validations: required: true - - type: markdown + - type: textarea attributes: label: Describe alternatives you've considered - value: "### Alternatives" placeholder: >- A clear and concise description of any alternative solutions or features you've considered. validations: required: true - - type: markdown + - type: textarea attributes: label: Additional context - value: "### Context" placeholder: >- Add any other context or screenshots about the feature request here. validations: From de404d22a45eabcc05e306a20bee3ea755063454 Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Thu, 9 Mar 2023 17:34:34 -0600 Subject: [PATCH 04/32] Update feature_request.yml --- .github/ISSUE_TEMPLATE/feature_request.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index fbf6f92634..df3a9b327d 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -1,13 +1,12 @@ name: ✨ Feature request description: Suggest an idea for this project -title: ✨ YOUR_DESCRIPTION +title: ✨ labels: enhancement body: - type: textarea attributes: label: Is your feature request related to a problem? Please describe. - render: "TEST" placeholder: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] validations: required: false From 56930e6ebac21da075ae6685ce782261121cb9ed Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Thu, 9 Mar 2023 17:40:09 -0600 Subject: [PATCH 05/32] Update feature_request.yml --- .github/ISSUE_TEMPLATE/feature_request.yml | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index df3a9b327d..da7229448c 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -6,14 +6,7 @@ labels: enhancement body: - type: textarea attributes: - label: Is your feature request related to a problem? Please describe. - placeholder: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - validations: - required: false - - - type: textarea - attributes: - label: Describe the solution you'd like + label: Description placeholder: >- A clear and concise description of what you would like to happen. validations: @@ -21,16 +14,18 @@ body: - type: textarea attributes: - label: Describe alternatives you've considered + label: Alternatives considered placeholder: >- A clear and concise description of any alternative solutions or features you've considered. - validations: - required: true - type: textarea attributes: label: Additional context placeholder: >- Add any other context or screenshots about the feature request here. - validations: - required: true + + - type: textarea + attributes: + label: Screenshots + placeholder: >- + If applicable, please provide relevant screenshots or screen recordings. From f4d400817b14b01edd3c7e065c9db9990f0abc71 Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Thu, 9 Mar 2023 17:42:17 -0600 Subject: [PATCH 06/32] Update feature_request.yml --- .github/ISSUE_TEMPLATE/feature_request.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index da7229448c..af1b7c0314 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -8,7 +8,7 @@ body: attributes: label: Description placeholder: >- - A clear and concise description of what you would like to happen. + A clear and concise description of what you would like to happen... validations: required: true @@ -16,16 +16,16 @@ body: attributes: label: Alternatives considered placeholder: >- - A clear and concise description of any alternative solutions or features you've considered. + A clear and concise description of any alternative solutions or features you've considered... - type: textarea attributes: label: Additional context placeholder: >- - Add any other context or screenshots about the feature request here. + Any other context or considerations about the feature request... - type: textarea attributes: label: Screenshots placeholder: >- - If applicable, please provide relevant screenshots or screen recordings. + If applicable, please provide relevant screenshots or screen recordings... From 8f7552d61676120482b91ea865060089ff72bc98 Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Thu, 9 Mar 2023 22:37:08 -0600 Subject: [PATCH 07/32] Update bug_report.yml --- .github/ISSUE_TEMPLATE/bug_report.yml | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 1e7fca8443..ca2b45df83 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,14 +1,14 @@ name: 🐞 Bug report description: Something is not working as expected. -title: 🐞 YOUR_DESCRIPTION +title: 🐞 labels: bug body: - type: textarea attributes: label: Description - description: >- - A clear and concise description of what the bug is. + placeholder: >- + A clear and concise description of what the bug is... validations: required: true @@ -40,13 +40,19 @@ body: click on the version number on the welcome screen value: | CodeEdit: [e.g. 1.0] - macOS: [e.g. 12.3.0] - Xcode: [e.g. 13.3] + macOS: [e.g. 13.2.1] + Xcode: [e.g. 14.2] validations: required: true - + - type: textarea attributes: label: Additional context - description: >- - Add any other context about the problem here. \ No newline at end of file + placeholder: >- + Any other context or considerations about the bug... + + - type: textarea + attributes: + label: Screenshots + placeholder: >- + If applicable, please provide relevant screenshots or screen recordings... From ef4b8e3b0468a2679c252b1ef07663acd64fdf05 Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Thu, 9 Mar 2023 22:37:41 -0600 Subject: [PATCH 08/32] Update bug_report.yml --- .github/ISSUE_TEMPLATE/bug_report.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index ca2b45df83..09c35a8e52 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -28,8 +28,8 @@ body: - type: textarea attributes: label: Expected behavior - description: >- - A clear and concise description of what you expected to happen. + placeholder: >- + A clear and concise description of what you expected to happen... validations: required: true From f701ba60b4878353b6e436077b9725f3d253a123 Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Thu, 9 Mar 2023 22:38:41 -0600 Subject: [PATCH 09/32] Update bug_report.yml --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 09c35a8e52..cc0510b789 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -16,7 +16,7 @@ body: attributes: label: To Reproduce description: >- - Steps to reproduce the behavior. + Steps to reliably reproduce the behavior. placeholder: | 1. Go to '...' 2. Click on '....' From 4d8d2416ab55703f41ed5d3cdc1955fab3a742a8 Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Thu, 9 Mar 2023 22:40:27 -0600 Subject: [PATCH 10/32] Update bug_report.yml --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index cc0510b789..2949cc3d75 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -42,8 +42,6 @@ body: CodeEdit: [e.g. 1.0] macOS: [e.g. 13.2.1] Xcode: [e.g. 14.2] - validations: - required: true - type: textarea attributes: From 085a4655e9cc82d3bd9607cbfc733333735d9660 Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Thu, 9 Mar 2023 23:03:12 -0600 Subject: [PATCH 11/32] Update pull_request_template.md --- .github/pull_request_template.md | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 0190a6c1b1..78776cac3d 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,22 +1,29 @@ -# Description + + +### Description -# Related Issue +### Related Issue + + + + - * #ISSUE_NUMBER -# Checklist +### Checklist + - [ ] I read and understood the [contributing guide](https://github.com/CodeEditApp/CodeEdit/blob/main/CONTRIBUTING.md) as well as the [code of conduct](https://github.com/CodeEditApp/CodeEdit/blob/main/CODE_OF_CONDUCT.md) - [ ] My changes generate no new warnings - [ ] My code builds and runs on my machine +- [ ] My changes are all related to the related issue above +- [ ] The issues this PR address are releated to each other - [ ] I documented my code -- [ ] Review requested -# Screenshots +### Screenshots From b8bf8b8a9446b065a44776c920f23444b17b1d7c Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Thu, 9 Mar 2023 23:03:37 -0600 Subject: [PATCH 12/32] Update pull_request_template.md --- .github/pull_request_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 78776cac3d..dcce0ba38d 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -17,10 +17,10 @@ - [ ] I read and understood the [contributing guide](https://github.com/CodeEditApp/CodeEdit/blob/main/CONTRIBUTING.md) as well as the [code of conduct](https://github.com/CodeEditApp/CodeEdit/blob/main/CODE_OF_CONDUCT.md) +- [ ] The issues this PR address are releated to each other - [ ] My changes generate no new warnings - [ ] My code builds and runs on my machine - [ ] My changes are all related to the related issue above -- [ ] The issues this PR address are releated to each other - [ ] I documented my code ### Screenshots From 720775f67a48c10f98b1e3159a9667e36fe3451b Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Thu, 9 Mar 2023 23:12:45 -0600 Subject: [PATCH 13/32] Update feature_request.yml --- .github/ISSUE_TEMPLATE/feature_request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index af1b7c0314..c60ee8b497 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -16,7 +16,7 @@ body: attributes: label: Alternatives considered placeholder: >- - A clear and concise description of any alternative solutions or features you've considered... + Any alternative solutions or features you've considered... - type: textarea attributes: From 9606db74761f65be951eb6cf00fccbacd409f054 Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Thu, 9 Mar 2023 23:29:17 -0600 Subject: [PATCH 14/32] Update bug_report.yml --- .github/ISSUE_TEMPLATE/bug_report.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 2949cc3d75..1b6c45b532 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -27,7 +27,7 @@ body: - type: textarea attributes: - label: Expected behavior + label: Expected Behavior placeholder: >- A clear and concise description of what you expected to happen... validations: @@ -35,7 +35,7 @@ body: - type: textarea attributes: - label: Version information + label: Version Information description: >- click on the version number on the welcome screen value: | @@ -45,7 +45,7 @@ body: - type: textarea attributes: - label: Additional context + label: Additional Context placeholder: >- Any other context or considerations about the bug... From 7d184d9eea54a74a56960d1a83e72ec409b74afa Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Thu, 9 Mar 2023 23:29:33 -0600 Subject: [PATCH 15/32] Update feature_request.yml --- .github/ISSUE_TEMPLATE/feature_request.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index c60ee8b497..476a7721e5 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -14,13 +14,13 @@ body: - type: textarea attributes: - label: Alternatives considered + label: Alternatives Considered placeholder: >- Any alternative solutions or features you've considered... - type: textarea attributes: - label: Additional context + label: Additional Context placeholder: >- Any other context or considerations about the feature request... From b0fa00697301afd87d30873f412f98b2dcac1eb3 Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Thu, 9 Mar 2023 23:30:37 -0600 Subject: [PATCH 16/32] Update pull_request_template.md --- .github/pull_request_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index dcce0ba38d..f9c6c130fa 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -4,7 +4,7 @@ -### Related Issue +### Related Issues From dca5c5ee2d3d4f3459963dc336c0ef3df19e3cc3 Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Fri, 10 Mar 2023 02:47:56 -0600 Subject: [PATCH 17/32] Update .github/pull_request_template.md Co-authored-by: Lukas Pistrol --- .github/pull_request_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index f9c6c130fa..d976c3fa5f 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -17,7 +17,7 @@ - [ ] I read and understood the [contributing guide](https://github.com/CodeEditApp/CodeEdit/blob/main/CONTRIBUTING.md) as well as the [code of conduct](https://github.com/CodeEditApp/CodeEdit/blob/main/CODE_OF_CONDUCT.md) -- [ ] The issues this PR address are releated to each other +- [ ] The issues this PR addresses are related to each other - [ ] My changes generate no new warnings - [ ] My code builds and runs on my machine - [ ] My changes are all related to the related issue above From 08b2494008e96236219aaed36e218b85ad23cbc9 Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Fri, 10 Mar 2023 02:48:41 -0600 Subject: [PATCH 18/32] Update .github/ISSUE_TEMPLATE/bug_report.yml Co-authored-by: Lukas Pistrol --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 1b6c45b532..1b03cbdd8c 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -39,7 +39,7 @@ body: description: >- click on the version number on the welcome screen value: | - CodeEdit: [e.g. 1.0] + CodeEdit: [e.g. 0.0.x-alpha.y] macOS: [e.g. 13.2.1] Xcode: [e.g. 14.2] From 6399b78f18503bf3bb764a424bfab92a560eb278 Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Sun, 12 Mar 2023 23:43:11 -0500 Subject: [PATCH 19/32] Refactored quick open view to not use a navigation view so that it looks right. Other UI corrections to improve the design of the overlay. --- CodeEdit/Features/CodeFile/CodeFileView.swift | 10 +-- .../Views/WorkspaceCodeFileView.swift | 7 -- .../QuickOpen/Views/QuickOpenItem.swift | 9 +-- .../Views/QuickOpenPreviewView.swift | 2 +- .../QuickOpen/Views/QuickOpenView.swift | 65 ++++++++++--------- 5 files changed, 47 insertions(+), 46 deletions(-) diff --git a/CodeEdit/Features/CodeFile/CodeFileView.swift b/CodeEdit/Features/CodeFile/CodeFileView.swift index 28051daf80..e2bd9ae109 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 @@ -77,7 +77,8 @@ struct CodeFileView: View { wrapLines: $prefs.preferences.textEditing.wrapLinesToEditorWidth, 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/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/QuickOpenItem.swift b/CodeEdit/Features/QuickOpen/Views/QuickOpenItem.swift index bf2843afe1..f821ee7769 100644 --- a/CodeEdit/Features/QuickOpen/Views/QuickOpenItem.swift +++ b/CodeEdit/Features/QuickOpen/Views/QuickOpenItem.swift @@ -29,12 +29,13 @@ struct QuickOpenItem: View { VStack(alignment: .leading, spacing: 0) { Text(fileItem.url.lastPathComponent).font(.system(size: 13)) .lineLimit(1) - Text(fileItem.url.path.replacingOccurrences(of: baseDirectory.path, with: "")) + Text(fileItem.url.deletingLastPathComponent().path.replacingOccurrences(of: baseDirectory.path, with: "")) .font(.system(size: 11)) .lineLimit(1) - .truncationMode(.tail) - }.padding(.trailing, 15) - Spacer() + .truncationMode(.head) + } + .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..9c7de171ba 100644 --- a/CodeEdit/Features/QuickOpen/Views/QuickOpenView.swift +++ b/CodeEdit/Features/QuickOpen/Views/QuickOpenView.swift @@ -32,12 +32,11 @@ struct QuickOpenView: 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) + Image(systemName: "magnifyingglass") + .font(.system(size: 18)) + .foregroundColor(.secondary) + .padding(.leading, 1) + .padding(.trailing, 10) TextField("Open Quickly", text: $state.openQuicklyQuery) .font(.system(size: 20, weight: .light, design: .default)) .textFieldStyle(.plain) @@ -48,40 +47,48 @@ struct QuickOpenView: View { state.fetchOpenQuickly() } } - .padding(16) + .padding(.vertical, 12) + .padding(.horizontal, 12) .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) { + if self.state.isShowingOpenQuicklyFiles { + Divider() + } + HStack(spacing: 0) { + List(state.openQuicklyFiles, id: \.self, selection: $selectedItem) { file in + QuickOpenItem(baseDirectory: state.fileURL, fileItem: file) + } + .contextMenu(forSelectionType: WorkspaceClient.FileItem.self, menu: { _ in + EmptyView() + }, primaryAction: { files in + if let file = files.first { self.openFile(file) self.onClose() } - .onTapGesture(count: 1) { - self.selectedItem = file - } - } - .frame(minWidth: 250, maxWidth: 250) + }) + .frame(maxWidth: 272) + Divider() if state.openQuicklyFiles.isEmpty { EmptyView() + .frame(maxWidth: .infinity) } else { - Text("Select a file to preview") + if let selectedItem { + QuickOpenPreviewView(item: selectedItem) + .frame(maxWidth: .infinity) + } else { + Text("Select a file to preview") + .frame(maxWidth: .infinity) + } } } } - .background(EffectView(.sidebar, blendingMode: .behindWindow)) - .edgesIgnoringSafeArea(.vertical) - .frame( - minWidth: 600, - minHeight: self.state.isShowingOpenQuicklyFiles ? 400 : 28, - maxHeight: self.state.isShowingOpenQuicklyFiles ? .infinity : 28 - ) + .background(EffectView(.sidebar, blendingMode: .behindWindow)) + .edgesIgnoringSafeArea(.vertical) + .frame( + minWidth: 680, + minHeight: self.state.isShowingOpenQuicklyFiles ? 400 : 19, + maxHeight: self.state.isShowingOpenQuicklyFiles ? .infinity : 19 + ) } } From 24040b09a1950397db7fb4c05e6162bcd1313d72 Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Mon, 13 Mar 2023 23:45:14 -0500 Subject: [PATCH 20/32] Improved open quickly list items path design --- .../Features/QuickOpen/Views/QuickOpenItem.swift | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/CodeEdit/Features/QuickOpen/Views/QuickOpenItem.swift b/CodeEdit/Features/QuickOpen/Views/QuickOpenItem.swift index f821ee7769..fdaf5748b8 100644 --- a/CodeEdit/Features/QuickOpen/Views/QuickOpenItem.swift +++ b/CodeEdit/Features/QuickOpen/Views/QuickOpenItem.swift @@ -18,6 +18,11 @@ struct QuickOpenItem: View { ) { self.baseDirectory = baseDirectory self.fileItem = fileItem + print(type(of: fileItem.url.pathComponents.dropFirst(baseDirectory.pathComponents.count-1).dropLast())) + } + + var relativePathComponents: ArraySlice { + return fileItem.url.pathComponents.dropFirst(baseDirectory.pathComponents.count).dropLast() } var body: some View { @@ -25,14 +30,15 @@ struct QuickOpenItem: View { 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.deletingLastPathComponent().path.replacingOccurrences(of: baseDirectory.path, with: "")) - .font(.system(size: 11)) + Text(relativePathComponents.joined(separator: " ▸ ")) + .font(.system(size: 10.5)) + .foregroundColor(.secondary) .lineLimit(1) - .truncationMode(.head) + .truncationMode(.middle) } .frame(maxWidth: .infinity, alignment: .leading) } From c01087902aa2b11ba7bc93c53c256d6995ba36cd Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Fri, 17 Mar 2023 11:20:01 -0500 Subject: [PATCH 21/32] Cleaned up Open Quickly overlay view. Made UI improvements for command palette. --- .../Commands/Views/CommandPaletteView.swift | 104 ++++++++++-------- .../QuickOpen/Views/QuickOpenItem.swift | 1 - .../QuickOpen/Views/QuickOpenView.swift | 8 +- 3 files changed, 63 insertions(+), 50 deletions(-) diff --git a/CodeEdit/Features/Commands/Views/CommandPaletteView.swift b/CodeEdit/Features/Commands/Views/CommandPaletteView.swift index cadb3433a8..5baf6f232e 100644 --- a/CodeEdit/Features/Commands/Views/CommandPaletteView.swift +++ b/CodeEdit/Features/Commands/Views/CommandPaletteView.swift @@ -133,61 +133,56 @@ struct CommandPaletteView: View { var body: some View { VStack(spacing: 0.0) { + VStack { HStack(alignment: .center, spacing: 0) { - Image(systemName: "command") - .resizable() - .scaledToFit() - .frame(width: 16, height: 16) - .padding(.leading, 20) - .offset(x: 0, y: 1) + Image(systemName: "magnifyingglass") + .font(.system(size: 18)) + .foregroundColor(.secondary) + .padding(.leading, 1) + .padding(.trailing, 5) + 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)) } - + .padding(.vertical, 12) + .padding(.horizontal, 12) + .foregroundColor(.primary) + .background(EffectView(.sidebar, blendingMode: .behindWindow)) + } + .frame(height: 48) 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) + ScrollView { + VStack(spacing: 0) { + ForEach(commandsList) { command in + // swiftlint:disable multiple_closures_with_trailing_closure + Button(action: { onCommandClick(command: command) }) { + SearchResultLabel( + labelName: command.title, + textToMatch: state.commandQuery + ) } - .frame(maxWidth: .infinity, maxHeight: 15, alignment: .leading) + .padding(.init(top: 8, leading: 10, bottom: 8, trailing: 8)) + .frame(maxWidth: .infinity, alignment: .leading) + .buttonStyle(.borderless) + .background( + Color(self.selectedItem == command ? .selectedContentBackgroundColor : .clear) + ) + .cornerRadius(5) + .onHover(perform: { _ in self.selectedItem = command }) } - .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()) + .padding(8) } } .background(EffectView(.sidebar, blendingMode: .behindWindow)) - .foregroundColor(.gray) .edgesIgnoringSafeArea(.vertical) .frame( - minWidth: 600, - minHeight: self.state.isShowingCommandsList ? 400 : 28, - maxHeight: self.state.isShowingCommandsList ? .infinity : 28 + minWidth: 680, + minHeight: self.state.isShowingCommandsList ? 400 : 19, + maxHeight: self.state.isShowingCommandsList ? .infinity : 19 ) } } @@ -217,6 +212,24 @@ private class ActionAwareInputView: NSTextView, NSTextFieldDelegate { onTextChange?(self.string) } + var placeholderString: String = "" + + override func draw(_ dirtyRect: NSRect) { + super.draw(dirtyRect) + + if string.isEmpty && !placeholderString.isEmpty { + let paragraphStyle = NSMutableParagraphStyle() + paragraphStyle.alignment = .left + let attrs: [NSAttributedString.Key: Any] = [ + .foregroundColor: NSColor.placeholderTextColor, + .font: font ?? NSFont.systemFont(ofSize: 12), + .paragraphStyle: paragraphStyle + ] + let attributedPlaceholder = NSAttributedString(string: placeholderString, attributes: attrs) + attributedPlaceholder.draw(in: dirtyRect.insetBy(dx: 6, dy: 0)) + } + } + } /// Implementation of command palette entity. While swiftui does not allow to use NSMutableAttributeStrings, @@ -227,16 +240,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,19 +258,21 @@ 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)) + if textToMatch == "" { + nsView.textColor = .labelColor + } nsView.attributedStringValue = highlight() } @@ -291,6 +304,7 @@ private struct ActionAwareInput: NSViewRepresentable { input.drawsBackground = false input.becomeFirstResponder() input.invalidateIntrinsicContentSize() + input.placeholderString = "Commands" return input } diff --git a/CodeEdit/Features/QuickOpen/Views/QuickOpenItem.swift b/CodeEdit/Features/QuickOpen/Views/QuickOpenItem.swift index fdaf5748b8..2470c74ccd 100644 --- a/CodeEdit/Features/QuickOpen/Views/QuickOpenItem.swift +++ b/CodeEdit/Features/QuickOpen/Views/QuickOpenItem.swift @@ -18,7 +18,6 @@ struct QuickOpenItem: View { ) { self.baseDirectory = baseDirectory self.fileItem = fileItem - print(type(of: fileItem.url.pathComponents.dropFirst(baseDirectory.pathComponents.count-1).dropLast())) } var relativePathComponents: ArraySlice { diff --git a/CodeEdit/Features/QuickOpen/Views/QuickOpenView.swift b/CodeEdit/Features/QuickOpen/Views/QuickOpenView.swift index 9c7de171ba..03b667649b 100644 --- a/CodeEdit/Features/QuickOpen/Views/QuickOpenView.swift +++ b/CodeEdit/Features/QuickOpen/Views/QuickOpenView.swift @@ -47,10 +47,10 @@ struct QuickOpenView: View { state.fetchOpenQuickly() } } - .padding(.vertical, 12) - .padding(.horizontal, 12) - .foregroundColor(.primary.opacity(0.85)) - .background(EffectView(.sidebar, blendingMode: .behindWindow)) + .padding(.vertical, 12) + .padding(.horizontal, 12) + .foregroundColor(.primary.opacity(0.85)) + .background(EffectView(.sidebar, blendingMode: .behindWindow)) } if self.state.isShowingOpenQuicklyFiles { Divider() From 0b246da951f617f2383937867aa0d3306c65feca Mon Sep 17 00:00:00 2001 From: Khan Winter <35942988+thecoolwinter@users.noreply.github.com> Date: Fri, 17 Mar 2023 19:06:43 -0500 Subject: [PATCH 22/32] Add `OverlayView` --- .../CodeEditUI/Views/OverlayView.swift | 202 +++++++++++++++ .../Commands/Views/CommandPaletteView.swift | 238 ++---------------- .../QuickOpen/Views/QuickOpenView.swift | 77 ++---- 3 files changed, 235 insertions(+), 282 deletions(-) create mode 100644 CodeEdit/Features/CodeEditUI/Views/OverlayView.swift diff --git a/CodeEdit/Features/CodeEditUI/Views/OverlayView.swift b/CodeEdit/Features/CodeEditUI/Views/OverlayView.swift new file mode 100644 index 0000000000..8ffb1c067f --- /dev/null +++ b/CodeEdit/Features/CodeEditUI/Views/OverlayView.swift @@ -0,0 +1,202 @@ +// +// OverlayWindow.swift +// CodeEdit +// +// Created by Khan Winter on 3/17/23. +// + +import Foundation +import SwiftUI + +struct OverlayView: View { + @ViewBuilder + let rowViewBuilder: ((Data) -> RowView) + + @ViewBuilder + let previewViewBuilder: ((Data) -> PreviewView)? + + @Binding + var data: [Data] + + @State + var selectedItem: Data? + + @Binding + var queryContent: String + + let title: String + let image: Image + let showsPreview: Bool + let onRowClick: ((Data) -> Void) + let onClose: (() -> Void) + + init( + title: String, + image: Image, + data: Binding<[Data]>, + queryContent: Binding, + content: @escaping ((Data) -> RowView), + preview: ((Data) -> PreviewView)? = nil, + onRowClick: @escaping ((Data) -> Void), + onClose: @escaping () -> Void + ) { + self.title = title + self.image = image + self._data = data + self._queryContent = queryContent + self.rowViewBuilder = content + self.previewViewBuilder = preview + self.onRowClick = onRowClick + self.onClose = onClose + self.showsPreview = preview != nil + } + + 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: $queryContent) + .font(.system(size: 20, weight: .light, design: .default)) + .textFieldStyle(.plain) + .onReceive(queryContent.publisher) { _ in + if queryContent.isEmpty { + selectedItem = nil + } else { + // Select the first item by default to indicate the "enter" action + if selectedItem == nil { + selectedItem = data.first + } + } + } + .onSubmit { + if queryContent.isEmpty { + // Nothing to select! + NSSound.beep() + } else { + // Handle enter pressed in the text view + if let dataItem = selectedItem ?? data.first { + onRowClick(dataItem) + } + } + } + } + .padding(.vertical, 12) + .padding(.horizontal, 12) + .foregroundColor(.primary.opacity(0.85)) + .background(EffectView(.sidebar, blendingMode: .behindWindow)) + } + if !queryContent.isEmpty { + ScrollViewReader { scrollReader in + ZStack { + // Hide these buttons (they're just keyboard shortcuts) + Button { + if let selectedItem, let index = data.firstIndex(of: selectedItem) { + if index > 0 { + self.selectedItem = data[index - 1] + withAnimation(.default) { + scrollReader.scrollTo(data[index - 1]) + } + } else { + NSSound.beep() + } + } + } label: { EmptyView() } + .opacity(0) + .keyboardShortcut(.upArrow, modifiers: []) + .accessibilityLabel("Select Up") + + Button { + if let selectedItem, let index = data.firstIndex(of: selectedItem) { + if data.count > index + 1 { + self.selectedItem = data[index + 1] + withAnimation(.default) { + scrollReader.scrollTo(data[index + 1]) + } + } else { + NSSound.beep() + } + } + } label: { EmptyView() } + .opacity(0) + .keyboardShortcut(.downArrow, modifiers: []) + .accessibilityLabel("Select Down") + + Button { + onClose() + } label: { EmptyView() } + .opacity(0) + .keyboardShortcut(.escape, modifiers: []) + .accessibilityLabel("Close Overlay") + } + Group { + // The real content. + Divider() + .padding(0) + HStack(spacing: 0) { + ScrollView { + LazyVStack( + alignment: .leading, + spacing: 0 + ) { + ForEach(data) { dataItem in + rowViewBuilder(dataItem) + .onTapGesture { + onRowClick(dataItem) + } + .padding([.trailing, .vertical], 8) + .padding(.leading, 10) + .frame(maxWidth: .infinity, alignment: .leading) + .buttonStyle(.borderless) + .background( + Color( + self.selectedItem == dataItem + ? .selectedContentBackgroundColor : .clear + ) + ) + .cornerRadius(5) + .onHover { isHovering in + if isHovering { + selectedItem = dataItem + } + } + .id(dataItem) + } + } + .frame(maxWidth: showsPreview ? 272 : .infinity) + .padding(.horizontal, 8) + } + if showsPreview { + Divider() + if data.isEmpty { + EmptyView() + .frame(maxWidth: .infinity) + } else { + if let selectedItem, let previewViewBuilder { + previewViewBuilder(selectedItem) + .frame(maxWidth: .infinity) + } else { + Text("Select a file to preview") + .frame(maxWidth: .infinity) + } + } + } + } + } + } + .frame(maxHeight: .infinity) + } + } + .background(EffectView(.sidebar, blendingMode: .behindWindow)) + .edgesIgnoringSafeArea(.vertical) + .frame( + minWidth: 680, + minHeight: queryContent.isEmpty ? 19 : 400, + maxHeight: queryContent.isEmpty ? 19 : .infinity + ) + } +} diff --git a/CodeEdit/Features/Commands/Views/CommandPaletteView.swift b/CodeEdit/Features/Commands/Views/CommandPaletteView.swift index 5baf6f232e..e78680d1c6 100644 --- a/CodeEdit/Features/Commands/Views/CommandPaletteView.swift +++ b/CodeEdit/Features/Commands/Views/CommandPaletteView.swift @@ -27,90 +27,17 @@ 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 = "" } 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,118 +45,23 @@ 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) { - VStack { - HStack(alignment: .center, spacing: 0) { - Image(systemName: "magnifyingglass") - .font(.system(size: 18)) - .foregroundColor(.secondary) - .padding(.leading, 1) - .padding(.trailing, 5) - - ActionAwareInput( - text: $state.commandQuery, onDown: onKeyDown, - onTextChange: onQueryChange - ) - .font(.system(size: 24, weight: .light, design: .default)) - } - .padding(.vertical, 12) - .padding(.horizontal, 12) - .foregroundColor(.primary) - .background(EffectView(.sidebar, blendingMode: .behindWindow)) - } - .frame(height: 48) - Divider() - ScrollView { - VStack(spacing: 0) { - ForEach(commandsList) { command in - // swiftlint:disable multiple_closures_with_trailing_closure - Button(action: { onCommandClick(command: command) }) { - SearchResultLabel( - labelName: command.title, - textToMatch: state.commandQuery - ) - } - .padding(.init(top: 8, leading: 10, bottom: 8, trailing: 8)) - .frame(maxWidth: .infinity, alignment: .leading) - .buttonStyle(.borderless) - .background( - Color(self.selectedItem == command ? .selectedContentBackgroundColor : .clear) - ) - .cornerRadius(5) - .onHover(perform: { _ in self.selectedItem = command }) - } - } - .padding(8) - } + OverlayView( + title: "Commands", + image: Image(systemName: "magnifyingglass"), + data: $state.filteredCommands, + queryContent: $state.commandQuery + ) { command in + SearchResultLabel(labelName: command.title, textToMatch: state.commandQuery) + } onRowClick: { command in + callHandler(command: command) + } onClose: { + closePalette() } - .background(EffectView(.sidebar, blendingMode: .behindWindow)) - .edgesIgnoringSafeArea(.vertical) - .frame( - minWidth: 680, - minHeight: self.state.isShowingCommandsList ? 400 : 19, - maxHeight: self.state.isShowingCommandsList ? .infinity : 19 - ) - } -} - -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) } - - var placeholderString: String = "" - - override func draw(_ dirtyRect: NSRect) { - super.draw(dirtyRect) - - if string.isEmpty && !placeholderString.isEmpty { - let paragraphStyle = NSMutableParagraphStyle() - paragraphStyle.alignment = .left - let attrs: [NSAttributedString.Key: Any] = [ - .foregroundColor: NSColor.placeholderTextColor, - .font: font ?? NSFont.systemFont(ofSize: 12), - .paragraphStyle: paragraphStyle - ] - let attributedPlaceholder = NSAttributedString(string: placeholderString, attributes: attrs) - attributedPlaceholder.draw(in: dirtyRect.insetBy(dx: 6, dy: 0)) - } - } - } /// Implementation of command palette entity. While swiftui does not allow to use NSMutableAttributeStrings, @@ -277,41 +109,3 @@ struct SearchResultLabel: NSViewRepresentable { } } - -/// 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() - input.placeholderString = "Commands" - - 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/QuickOpen/Views/QuickOpenView.swift b/CodeEdit/Features/QuickOpen/Views/QuickOpenView.swift index 03b667649b..d3d4780506 100644 --- a/CodeEdit/Features/QuickOpen/Views/QuickOpenView.swift +++ b/CodeEdit/Features/QuickOpen/Views/QuickOpenView.swift @@ -29,66 +29,23 @@ struct QuickOpenView: View { } var body: some View { - VStack(spacing: 0.0) { - VStack { - HStack(alignment: .center, spacing: 0) { - Image(systemName: "magnifyingglass") - .font(.system(size: 18)) - .foregroundColor(.secondary) - .padding(.leading, 1) - .padding(.trailing, 10) - 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(.vertical, 12) - .padding(.horizontal, 12) - .foregroundColor(.primary.opacity(0.85)) - .background(EffectView(.sidebar, blendingMode: .behindWindow)) - } - if self.state.isShowingOpenQuicklyFiles { - Divider() - } - HStack(spacing: 0) { - List(state.openQuicklyFiles, id: \.self, selection: $selectedItem) { file in - QuickOpenItem(baseDirectory: state.fileURL, fileItem: file) - } - .contextMenu(forSelectionType: WorkspaceClient.FileItem.self, menu: { _ in - EmptyView() - }, primaryAction: { files in - if let file = files.first { - self.openFile(file) - self.onClose() - } - }) - .frame(maxWidth: 272) - Divider() - if state.openQuicklyFiles.isEmpty { - EmptyView() - .frame(maxWidth: .infinity) - } else { - if let selectedItem { - QuickOpenPreviewView(item: selectedItem) - .frame(maxWidth: .infinity) - } else { - Text("Select a file to preview") - .frame(maxWidth: .infinity) - } - } - } + OverlayView( + title: "Open Quickly", + image: Image(systemName: "magnifyingglass"), + data: $state.openQuicklyFiles, + queryContent: $state.openQuicklyQuery + ) { 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: 680, - minHeight: self.state.isShowingOpenQuicklyFiles ? 400 : 19, - maxHeight: self.state.isShowingOpenQuicklyFiles ? .infinity : 19 - ) } } From d3a9b989d9b96ad07cf31eab94fc2fb451901098 Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Sat, 18 Mar 2023 03:52:31 +0100 Subject: [PATCH 23/32] Moved to NSTableView for palette results Signed-off-by: Wouter01 --- CodeEdit.xcodeproj/project.pbxproj | 14 +- .../CodeEditUI/Views/OverlayView.swift | 173 +++++++----------- CodeEdit/Features/CodeFile/CodeFileView.swift | 3 +- .../QuickOpen/Views/NSTableViewWrapper.swift | 142 ++++++++++++++ .../QuickOpen/Views/PaletteTextField.swift | 72 ++++++++ 5 files changed, 287 insertions(+), 117 deletions(-) create mode 100644 CodeEdit/Features/QuickOpen/Views/NSTableViewWrapper.swift create mode 100644 CodeEdit/Features/QuickOpen/Views/PaletteTextField.swift diff --git a/CodeEdit.xcodeproj/project.pbxproj b/CodeEdit.xcodeproj/project.pbxproj index 4c3996deed..8a0ed42559 100644 --- a/CodeEdit.xcodeproj/project.pbxproj +++ b/CodeEdit.xcodeproj/project.pbxproj @@ -339,6 +339,9 @@ 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 */; }; + 6CABB19E29C5591D00340467 /* NSTableViewWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CABB19C29C5591D00340467 /* NSTableViewWrapper.swift */; }; + 6CABB19F29C5591D00340467 /* PaletteTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CABB19D29C5591D00340467 /* PaletteTextField.swift */; }; + 6CABB1A129C5593800340467 /* OverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CABB1A029C5593800340467 /* OverlayView.swift */; }; 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 */; }; @@ -745,10 +748,7 @@ 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 = ""; }; + 6C97EBCE297876E500302F95 /* AboutWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutWindowController.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 = ""; }; @@ -1307,6 +1307,8 @@ 5878DAA9291D5CA100DD95A3 /* Views */ = { isa = PBXGroup; children = ( + 6CABB19C29C5591D00340467 /* NSTableViewWrapper.swift */, + 6CABB19D29C5591D00340467 /* PaletteTextField.swift */, 5878DAA1291AE76700DD95A3 /* QuickOpenView.swift */, 5878DAA2291AE76700DD95A3 /* QuickOpenPreviewView.swift */, 5878DAA4291AE76700DD95A3 /* QuickOpenItem.swift */, @@ -1545,6 +1547,7 @@ 587B9D8629300ABD00AC7927 /* Views */ = { isa = PBXGroup; children = ( + 6CABB1A029C5593800340467 /* OverlayView.swift */, 587B9D8B29300ABD00AC7927 /* EffectView.swift */, 587B9D8729300ABD00AC7927 /* FontPickerView.swift */, 587B9D9029300ABD00AC7927 /* HelpButton.swift */, @@ -2808,8 +2811,10 @@ 58AFAA2E2933C69E00482B53 /* TabBarItemRepresentable.swift in Sources */, 6C4104E6297C884F00F472BA /* AboutDetailView.swift in Sources */, 587B9E7A29301D8F00AC7927 /* GitHubReviewsRouter.swift in Sources */, + 6CABB19F29C5591D00340467 /* PaletteTextField.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 */, @@ -2894,6 +2899,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 */, diff --git a/CodeEdit/Features/CodeEditUI/Views/OverlayView.swift b/CodeEdit/Features/CodeEditUI/Views/OverlayView.swift index 8ffb1c067f..f578fe61cf 100644 --- a/CodeEdit/Features/CodeEditUI/Views/OverlayView.swift +++ b/CodeEdit/Features/CodeEditUI/Views/OverlayView.swift @@ -23,7 +23,6 @@ struct OverlayView 0 { - self.selectedItem = data[index - 1] - withAnimation(.default) { - scrollReader.scrollTo(data[index - 1]) - } - } else { - NSSound.beep() - } - } - } label: { EmptyView() } - .opacity(0) - .keyboardShortcut(.upArrow, modifiers: []) - .accessibilityLabel("Select Up") - Button { - if let selectedItem, let index = data.firstIndex(of: selectedItem) { - if data.count > index + 1 { - self.selectedItem = data[index + 1] - withAnimation(.default) { - scrollReader.scrollTo(data[index + 1]) - } - } else { - NSSound.beep() - } - } - } label: { EmptyView() } - .opacity(0) - .keyboardShortcut(.downArrow, modifiers: []) - .accessibilityLabel("Select Down") - - Button { - onClose() - } label: { EmptyView() } - .opacity(0) - .keyboardShortcut(.escape, modifiers: []) - .accessibilityLabel("Close Overlay") - } - Group { - // The real content. Divider() .padding(0) - HStack(spacing: 0) { - ScrollView { - LazyVStack( - alignment: .leading, - spacing: 0 - ) { - ForEach(data) { dataItem in - rowViewBuilder(dataItem) - .onTapGesture { - onRowClick(dataItem) - } - .padding([.trailing, .vertical], 8) - .padding(.leading, 10) - .frame(maxWidth: .infinity, alignment: .leading) - .buttonStyle(.borderless) - .background( - Color( - self.selectedItem == dataItem - ? .selectedContentBackgroundColor : .clear - ) - ) - .cornerRadius(5) - .onHover { isHovering in - if isHovering { - selectedItem = dataItem - } - } - .id(dataItem) - } - } - .frame(maxWidth: showsPreview ? 272 : .infinity) - .padding(.horizontal, 8) - } - if showsPreview { - Divider() - if data.isEmpty { - EmptyView() - .frame(maxWidth: .infinity) - } else { - if let selectedItem, let previewViewBuilder { - previewViewBuilder(selectedItem) - .frame(maxWidth: .infinity) - } else { - Text("Select a file to preview") - .frame(maxWidth: .infinity) - } - } + HStack(spacing: 0) { + NSTableViewWrapper(data: data, rowHeight: 50, selection: $selectedItem, itemView: rowViewBuilder) + .frame(maxWidth: showsPreview ? 272 : .infinity) + if showsPreview { + Divider() + if data.isEmpty { + EmptyView() + .frame(maxWidth: .infinity) + } else { + if let selectedItem, let previewViewBuilder { + previewViewBuilder(selectedItem) + .frame(maxWidth: .infinity) + } else { + Text("Select a file to preview") + .frame(maxWidth: .infinity) } } } } - .frame(maxHeight: .infinity) } } + .overlay { + Button { + onClose() + } label: { EmptyView() } + .opacity(0) + .keyboardShortcut(.escape, modifiers: []) + .accessibilityLabel("Close Overlay") + } .background(EffectView(.sidebar, blendingMode: .behindWindow)) .edgesIgnoringSafeArea(.vertical) .frame( @@ -199,4 +117,37 @@ struct OverlayView: 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/PaletteTextField.swift b/CodeEdit/Features/QuickOpen/Views/PaletteTextField.swift new file mode 100644 index 0000000000..9e8187e8f6 --- /dev/null +++ b/CodeEdit/Features/QuickOpen/Views/PaletteTextField.swift @@ -0,0 +1,72 @@ +// +// PaletteTextField.swift +// CodeEdit +// +// Created by Wouter Hennen on 18/03/2023. +// + +import SwiftUI + +struct PaletteTextField: NSViewRepresentable { + @Binding var text: String + + var overruleKeyCode: (Int) -> Void + + func makeNSView(context: Context) -> PaletteNSTextView { + let view = PaletteNSTextView() + view.overruleKeyCode = overruleKeyCode + + view.string = text + view.font = .systemFont(ofSize: 20, weight: .light) + view.drawsBackground = false + view.becomeFirstResponder() + view.invalidateIntrinsicContentSize() + view.textContainer!.maximumNumberOfLines = 1 + view.delegate = context.coordinator + + return view + } + + func updateNSView(_ view: PaletteNSTextView, context: Context) { + view.string = text + view.overruleKeyCode = overruleKeyCode + } + + func makeCoordinator() -> Delegate { + Delegate(parent: self) + } +} + +extension PaletteTextField { + class Delegate: NSObject, NSTextViewDelegate { + var parent: PaletteTextField + + init(parent: PaletteTextField) { + self.parent = parent + } + + func textDidChange(_ notification: Notification) { + if let textview = notification.object as? NSTextView { + parent.text = textview.string + } + } + } +} + +extension PaletteTextField { + class PaletteNSTextView: NSTextView { + + var overruleKeyCode: ((Int) -> Void)? + + override var acceptsFirstResponder: Bool { return true } + + override public func keyDown(with event: NSEvent) { + switch event.keyCode { + case 36, 125, 126: + overruleKeyCode?(Int(event.keyCode)) + default: + super.keyDown(with: event) + } + } + } +} From f7ed7b2c250c9174cbe0840c0696252612bd980b Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Sat, 18 Mar 2023 04:02:45 +0100 Subject: [PATCH 24/32] Add isEditable back Signed-off-by: Wouter01 --- CodeEdit/Features/CodeFile/CodeFileView.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CodeEdit/Features/CodeFile/CodeFileView.swift b/CodeEdit/Features/CodeFile/CodeFileView.swift index e8651c8455..e2bd9ae109 100644 --- a/CodeEdit/Features/CodeFile/CodeFileView.swift +++ b/CodeEdit/Features/CodeFile/CodeFileView.swift @@ -77,7 +77,8 @@ struct CodeFileView: View { wrapLines: $prefs.preferences.textEditing.wrapLinesToEditorWidth, cursorPosition: codeFile.$cursorPosition, useThemeBackground: prefs.preferences.theme.useThemeBackground, - contentInsets: edgeInsets.nsEdgeInsets + contentInsets: edgeInsets.nsEdgeInsets, + isEditable: isEditable ) .id(codeFile.fileURL) .background { From f6a8c7f4c0420b81b7ad950b927dc121a0584485 Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Sat, 18 Mar 2023 12:41:30 +0100 Subject: [PATCH 25/32] Reverted custom textfield to swiftui textfield Signed-off-by: Wouter01 --- CodeEdit.xcodeproj/project.pbxproj | 5 +- .../CodeEditUI/Views/OverlayView.swift | 63 ++++++++-------- .../QuickOpen/Views/PaletteTextField.swift | 72 ------------------- 3 files changed, 37 insertions(+), 103 deletions(-) delete mode 100644 CodeEdit/Features/QuickOpen/Views/PaletteTextField.swift diff --git a/CodeEdit.xcodeproj/project.pbxproj b/CodeEdit.xcodeproj/project.pbxproj index 8a0ed42559..18ed7c9ea5 100644 --- a/CodeEdit.xcodeproj/project.pbxproj +++ b/CodeEdit.xcodeproj/project.pbxproj @@ -340,7 +340,6 @@ 6CAAF69429BCD78600A1F48A /* CommandsFixes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CAAF69329BCD78600A1F48A /* CommandsFixes.swift */; }; 6CB9144B29BEC7F100BC47F2 /* WelcomeWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CB9144A29BEC7F100BC47F2 /* WelcomeWindow.swift */; }; 6CABB19E29C5591D00340467 /* NSTableViewWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CABB19C29C5591D00340467 /* NSTableViewWrapper.swift */; }; - 6CABB19F29C5591D00340467 /* PaletteTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CABB19D29C5591D00340467 /* PaletteTextField.swift */; }; 6CABB1A129C5593800340467 /* OverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CABB1A029C5593800340467 /* OverlayView.swift */; }; 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 */; }; @@ -749,6 +748,8 @@ 6C91D57129B176FF0059A90D /* TabManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabManager.swift; sourceTree = ""; }; 6C97EBCB2978760400302F95 /* AcknowledgementsWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AcknowledgementsWindowController.swift; sourceTree = ""; }; 6C97EBCE297876E500302F95 /* AboutWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutWindowController.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 = ""; }; @@ -1308,7 +1309,6 @@ isa = PBXGroup; children = ( 6CABB19C29C5591D00340467 /* NSTableViewWrapper.swift */, - 6CABB19D29C5591D00340467 /* PaletteTextField.swift */, 5878DAA1291AE76700DD95A3 /* QuickOpenView.swift */, 5878DAA2291AE76700DD95A3 /* QuickOpenPreviewView.swift */, 5878DAA4291AE76700DD95A3 /* QuickOpenItem.swift */, @@ -2811,7 +2811,6 @@ 58AFAA2E2933C69E00482B53 /* TabBarItemRepresentable.swift in Sources */, 6C4104E6297C884F00F472BA /* AboutDetailView.swift in Sources */, 587B9E7A29301D8F00AC7927 /* GitHubReviewsRouter.swift in Sources */, - 6CABB19F29C5591D00340467 /* PaletteTextField.swift in Sources */, 04540D5E27DD08C300E91B77 /* WorkspaceView.swift in Sources */, DE6F77872813625500D00A76 /* TabBarDivider.swift in Sources */, 6CABB1A129C5593800340467 /* OverlayView.swift in Sources */, diff --git a/CodeEdit/Features/CodeEditUI/Views/OverlayView.swift b/CodeEdit/Features/CodeEditUI/Views/OverlayView.swift index f578fe61cf..266d8b5eaf 100644 --- a/CodeEdit/Features/CodeEditUI/Views/OverlayView.swift +++ b/CodeEdit/Features/CodeEditUI/Views/OverlayView.swift @@ -59,8 +59,16 @@ struct OverlayView Void - - func makeNSView(context: Context) -> PaletteNSTextView { - let view = PaletteNSTextView() - view.overruleKeyCode = overruleKeyCode - - view.string = text - view.font = .systemFont(ofSize: 20, weight: .light) - view.drawsBackground = false - view.becomeFirstResponder() - view.invalidateIntrinsicContentSize() - view.textContainer!.maximumNumberOfLines = 1 - view.delegate = context.coordinator - - return view - } - - func updateNSView(_ view: PaletteNSTextView, context: Context) { - view.string = text - view.overruleKeyCode = overruleKeyCode - } - - func makeCoordinator() -> Delegate { - Delegate(parent: self) - } -} - -extension PaletteTextField { - class Delegate: NSObject, NSTextViewDelegate { - var parent: PaletteTextField - - init(parent: PaletteTextField) { - self.parent = parent - } - - func textDidChange(_ notification: Notification) { - if let textview = notification.object as? NSTextView { - parent.text = textview.string - } - } - } -} - -extension PaletteTextField { - class PaletteNSTextView: NSTextView { - - var overruleKeyCode: ((Int) -> Void)? - - override var acceptsFirstResponder: Bool { return true } - - override public func keyDown(with event: NSEvent) { - switch event.keyCode { - case 36, 125, 126: - overruleKeyCode?(Int(event.keyCode)) - default: - super.keyDown(with: event) - } - } - } -} From b4d24fbcb699cc9e5f9dbb017e9990d516f7d511 Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Mon, 20 Mar 2023 12:46:17 -0500 Subject: [PATCH 26/32] =?UTF-8?q?Changed=20command=20palette=20keybinding?= =?UTF-8?q?=20to=20=E2=8C=98=E2=87=A7P.=20Renamed=20data=20to=20options.?= =?UTF-8?q?=20Renamed=20queryContent=20to=20text.=20Added=20alwaysShowOpti?= =?UTF-8?q?ons=20parameter.=20Added=20optionRowHeight=20parameter.=20Showi?= =?UTF-8?q?ng=20commands=20by=20default=20when=20there=20is=20no=20text=20?= =?UTF-8?q?in=20command=20palette.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CodeEditUI/Views/OverlayView.swift | 99 +++++++++++-------- .../ViewModels/CommandPaletteViewModel.swift | 4 +- .../Commands/Views/CommandPaletteView.swift | 7 +- .../QuickOpen/Views/QuickOpenView.swift | 5 +- 4 files changed, 68 insertions(+), 47 deletions(-) diff --git a/CodeEdit/Features/CodeEditUI/Views/OverlayView.swift b/CodeEdit/Features/CodeEditUI/Views/OverlayView.swift index 266d8b5eaf..b3a7a5abe2 100644 --- a/CodeEdit/Features/CodeEditUI/Views/OverlayView.swift +++ b/CodeEdit/Features/CodeEditUI/Views/OverlayView.swift @@ -8,46 +8,52 @@ import Foundation import SwiftUI -struct OverlayView: View { +struct OverlayView: View { @ViewBuilder - let rowViewBuilder: ((Data) -> RowView) + let rowViewBuilder: ((Option) -> RowView) @ViewBuilder - let previewViewBuilder: ((Data) -> PreviewView)? + let previewViewBuilder: ((Option) -> PreviewView)? @Binding - var data: [Data] + var options: [Option] @State - var selectedItem: Data? + var selection: Option? @Binding - var queryContent: String + var text: String let title: String let image: Image let showsPreview: Bool - let onRowClick: ((Data) -> Void) + let onRowClick: ((Option) -> Void) let onClose: (() -> Void) + let alwaysShowOptions: Bool + let optionRowHeight: CGFloat init( title: String, image: Image, - data: Binding<[Data]>, - queryContent: Binding, - content: @escaping ((Data) -> RowView), - preview: ((Data) -> PreviewView)? = nil, - onRowClick: @escaping ((Data) -> Void), + 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._data = data - self._queryContent = queryContent + 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 { @@ -59,22 +65,22 @@ struct OverlayView Void) { self.state = state self.closePalette = closePalette + state.filteredCommands = commandManager.commands } func callHandler(command: Command) { @@ -49,8 +50,10 @@ struct CommandPaletteView: View { OverlayView( title: "Commands", image: Image(systemName: "magnifyingglass"), - data: $state.filteredCommands, - queryContent: $state.commandQuery + options: $state.filteredCommands, + text: $state.commandQuery, + alwaysShowOptions: true, + optionRowHeight: 30 ) { command in SearchResultLabel(labelName: command.title, textToMatch: state.commandQuery) } onRowClick: { command in diff --git a/CodeEdit/Features/QuickOpen/Views/QuickOpenView.swift b/CodeEdit/Features/QuickOpen/Views/QuickOpenView.swift index d3d4780506..cc8536976d 100644 --- a/CodeEdit/Features/QuickOpen/Views/QuickOpenView.swift +++ b/CodeEdit/Features/QuickOpen/Views/QuickOpenView.swift @@ -32,8 +32,9 @@ struct QuickOpenView: View { OverlayView( title: "Open Quickly", image: Image(systemName: "magnifyingglass"), - data: $state.openQuicklyFiles, - queryContent: $state.openQuicklyQuery + options: $state.openQuicklyFiles, + text: $state.openQuicklyQuery, + optionRowHeight: 40 ) { file in QuickOpenItem(baseDirectory: state.fileURL, fileItem: file) } preview: { file in From dddf6aa1f3b5d72bd17c214d277e273929336ddd Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Mon, 20 Mar 2023 13:13:19 -0500 Subject: [PATCH 27/32] Change text color when text is present to make highlighted text stand out in open quickly overlay --- CodeEdit/Features/Commands/Views/CommandPaletteView.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CodeEdit/Features/Commands/Views/CommandPaletteView.swift b/CodeEdit/Features/Commands/Views/CommandPaletteView.swift index 751b5cb696..ef1c5304b1 100644 --- a/CodeEdit/Features/Commands/Views/CommandPaletteView.swift +++ b/CodeEdit/Features/Commands/Views/CommandPaletteView.swift @@ -107,6 +107,8 @@ struct SearchResultLabel: NSViewRepresentable { func updateNSView(_ nsView: NSViewType, context: Context) { if textToMatch == "" { nsView.textColor = .labelColor + } else { + nsView.textColor = .secondaryLabelColor } nsView.attributedStringValue = highlight() } From f4557e0d4388277ccf3fcc8ca9d5ee4e09d21d46 Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Mon, 20 Mar 2023 13:49:04 -0500 Subject: [PATCH 28/32] Selecting the first item automatically in the OverlayView --- CodeEdit/Features/CodeEditUI/Views/OverlayView.swift | 4 ++-- CodeEdit/Features/Commands/Views/CommandPaletteView.swift | 6 +----- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/CodeEdit/Features/CodeEditUI/Views/OverlayView.swift b/CodeEdit/Features/CodeEditUI/Views/OverlayView.swift index b3a7a5abe2..704374e09f 100644 --- a/CodeEdit/Features/CodeEditUI/Views/OverlayView.swift +++ b/CodeEdit/Features/CodeEditUI/Views/OverlayView.swift @@ -75,8 +75,8 @@ struct OverlayView Date: Mon, 20 Mar 2023 17:19:34 -0500 Subject: [PATCH 29/32] Merged with latest master --- CodeEdit.xcodeproj/project.pbxproj | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/CodeEdit.xcodeproj/project.pbxproj b/CodeEdit.xcodeproj/project.pbxproj index 18ed7c9ea5..3599ff6812 100644 --- a/CodeEdit.xcodeproj/project.pbxproj +++ b/CodeEdit.xcodeproj/project.pbxproj @@ -335,12 +335,12 @@ 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 */; }; @@ -353,6 +353,7 @@ 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 */; }; 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 */; }; @@ -747,7 +748,6 @@ 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 = ""; }; - 6C97EBCE297876E500302F95 /* AboutWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutWindowController.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 = ""; }; @@ -766,6 +766,7 @@ 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 = ""; }; 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 = ""; }; @@ -1081,7 +1082,6 @@ children = ( 6C186209298BF5A800C663EA /* RecentProjectsListView.swift */, 581BFB5A2926431000D251EC /* WelcomeWindowView.swift */, - 6CB9144A29BEC7F100BC47F2 /* WelcomeWindow.swift */, 581BFB5B2926431000D251EC /* WelcomeView.swift */, 581BFB5C2926431000D251EC /* WelcomeActionView.swift */, 581BFB5E2926431000D251EC /* RecentProjectItem.swift */, @@ -2274,7 +2274,7 @@ 6C82D6BF29C00EE300495C54 /* Utils */ = { isa = PBXGroup; children = ( - 6CAAF69329BCD78600A1F48A /* CommandsFixes.swift */, + B66A4E4429C8E86D004573B4 /* CommandsFixes.swift */, 6C82D6BB29C00CD900495C54 /* FirstResponderPropertyWrapper.swift */, ); path = Utils; @@ -2291,7 +2291,6 @@ 6CAAF68F29BCC6F900A1F48A /* WindowCommands */ = { isa = PBXGroup; children = ( - 6CAAF69129BCC71C00A1F48A /* CodeEditCommands.swift */, 6CFF967729BEBCF600182D6F /* MainCommands.swift */, 6CFF967529BEBCD900182D6F /* FileCommands.swift */, 6CFF967929BEBD2400182D6F /* ViewCommands.swift */, @@ -2348,7 +2347,6 @@ D7211D4427E066D4008F2ED7 /* Localization */, B658FB3527DA9E1000EA4DBD /* Preview Content */, 58D01C85293167DC00C5B6B4 /* Utils */, - 6CAAF68929BC9C2300A1F48A /* CodeEditApp.swift */, 6C5AB9D629C1496E003B5F96 /* SceneID.swift */, 0468438427DC76E200F8E88E /* AppDelegate.swift */, 5C4BB1E028212B1E00A92FB2 /* World.swift */, @@ -2689,7 +2687,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 */, @@ -2822,6 +2820,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 */, @@ -2839,7 +2838,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 */, @@ -2860,7 +2859,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 */, @@ -2878,7 +2877,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 */, From e2a51e91b06b04ffbf7691dbee46e5dddf2a5410 Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Mon, 20 Mar 2023 17:49:30 -0500 Subject: [PATCH 30/32] =?UTF-8?q?Merged=20conflicts,=20fixed=20resulting?= =?UTF-8?q?=20issues,=20changed=20keybinding=20for=20command=20pallet=20to?= =?UTF-8?q?=20=E2=8C=98=E2=87=A7P?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CodeEdit.xcodeproj/project.pbxproj | 24 +++++++++++++++---- .../WindowCommands/ViewCommands.swift | 2 +- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/CodeEdit.xcodeproj/project.pbxproj b/CodeEdit.xcodeproj/project.pbxproj index 3599ff6812..3927760ab8 100644 --- a/CodeEdit.xcodeproj/project.pbxproj +++ b/CodeEdit.xcodeproj/project.pbxproj @@ -331,7 +331,6 @@ 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 */; }; @@ -354,6 +353,11 @@ 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 */; }; @@ -744,7 +748,6 @@ 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 = ""; }; @@ -767,6 +770,11 @@ 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 = ""; }; @@ -1084,6 +1092,7 @@ 581BFB5A2926431000D251EC /* WelcomeWindowView.swift */, 581BFB5B2926431000D251EC /* WelcomeView.swift */, 581BFB5C2926431000D251EC /* WelcomeActionView.swift */, + B66A4E4E29C917B8004573B4 /* WelcomeWindow.swift */, 581BFB5E2926431000D251EC /* RecentProjectItem.swift */, ); path = Views; @@ -1104,7 +1113,7 @@ 6C4104E8297C970F00F472BA /* AboutDefaultView.swift */, 6C4104E5297C884F00F472BA /* AboutDetailView.swift */, 6C4104E2297C87A000F472BA /* BlurButtonStyle.swift */, - 6C82D6C129C0110100495C54 /* AboutWindow.swift */, + B66A4E5029C917D5004573B4 /* AboutWindow.swift */, ); path = Views; sourceTree = ""; @@ -2291,6 +2300,7 @@ 6CAAF68F29BCC6F900A1F48A /* WindowCommands */ = { isa = PBXGroup; children = ( + B66A4E5229C91831004573B4 /* CodeEditCommands.swift */, 6CFF967729BEBCF600182D6F /* MainCommands.swift */, 6CFF967529BEBCD900182D6F /* FileCommands.swift */, 6CFF967929BEBD2400182D6F /* ViewCommands.swift */, @@ -2352,7 +2362,9 @@ 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 */, @@ -2716,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 */, @@ -2753,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 */, @@ -2782,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 */, @@ -2828,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 */, 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...") { From 42ce1d3119c0a6114b42d44bf8834459ad6d6f09 Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Mon, 20 Mar 2023 18:12:10 -0500 Subject: [PATCH 31/32] Updated CodeEditTextView version --- CodeEdit.xcodeproj/project.pbxproj | 2 +- .../project.xcworkspace/xcshareddata/swiftpm/Package.resolved | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CodeEdit.xcodeproj/project.pbxproj b/CodeEdit.xcodeproj/project.pbxproj index 3927760ab8..d7bcec78d7 100644 --- a/CodeEdit.xcodeproj/project.pbxproj +++ b/CodeEdit.xcodeproj/project.pbxproj @@ -3931,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" } }, { From 710b5eded2ba85f755116b34d15eb4426c6bfac1 Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Tue, 21 Mar 2023 00:39:58 +0100 Subject: [PATCH 32/32] Fixed build issue Signed-off-by: Wouter01 --- CodeEdit/Features/CodeFile/CodeFileView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CodeEdit/Features/CodeFile/CodeFileView.swift b/CodeEdit/Features/CodeFile/CodeFileView.swift index e2bd9ae109..743bd4409b 100644 --- a/CodeEdit/Features/CodeFile/CodeFileView.swift +++ b/CodeEdit/Features/CodeFile/CodeFileView.swift @@ -75,7 +75,7 @@ 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, isEditable: isEditable