Skip to content

Commit

Permalink
Settings Search (#1312)
Browse files Browse the repository at this point in the history
* add support for searching settings

* code cleanup and fixes

* respond to some review comments from @austincondiff,

* highlight the containing letters/word

* partially working "non grouping" settings search

* fully working non grouping settings.

* fix swiftlint and remaining bugs

* final fixes and documentation

* bug fixes and remove swiftlint:disable

* remove uneeded code

* rename file and make text primary when there is no search text

* partially respond to @wouter's comments by adding a dictionary for settings translation and add locationsSettings for better search results

* changes

* fix swiftlint

* final fix for swiftlint

* refactoring

* edit docs for adding new setting/settings page

* refactoring

* fix swiftlint

* restructure SettingsPage.swift

* partially fix review

* fully fix review

* fix minor UI bugs

* remove uneeded font parameter

* fix weird looking text

* remove swiftlint disable

* fix remaining swiftlint errors

* Update CodeEdit/Features/Settings/Pages/AccountsSettings/Models/AccountsSettings.swift

Co-authored-by: Austin Condiff <austin.condiff@gmail.com>

* remove unneeded `internal`

* apply suggestions from 0xWDG's review

Co-authored-by: Wesley de Groot <email@wesleydegroot.nl>

* Fix swiftlint errors

---------

Co-authored-by: Austin Condiff <austin.condiff@gmail.com>
Co-authored-by: Wesley de Groot <email@wesleydegroot.nl>
  • Loading branch information
3 people authored Sep 30, 2023
1 parent 4ad6eb8 commit 5122227
Show file tree
Hide file tree
Showing 35 changed files with 662 additions and 292 deletions.
40 changes: 38 additions & 2 deletions CodeEdit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,12 @@
6CFF967C29BEBD5200182D6F /* WindowCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CFF967B29BEBD5200182D6F /* WindowCommands.swift */; };
850C631029D6B01D00E1444C /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 850C630F29D6B01D00E1444C /* SettingsView.swift */; };
850C631229D6B03400E1444C /* SettingsPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 850C631129D6B03400E1444C /* SettingsPage.swift */; };
852C7E332A587279006BA599 /* SearchableSettingsPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 852C7E322A587279006BA599 /* SearchableSettingsPage.swift */; };
852E62012A5C17E500447138 /* PageAndSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 852E62002A5C17E500447138 /* PageAndSettings.swift */; };
85745D632A38F8D900089AAB /* String+HighlightOccurrences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85745D622A38F8D900089AAB /* String+HighlightOccurrences.swift */; };
85773E1E2A3E0A1F00C5D926 /* SettingsSearchResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85773E1D2A3E0A1F00C5D926 /* SettingsSearchResult.swift */; };
85CD0C5F2A10CC3200E531FD /* URL+isImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85CD0C5E2A10CC3200E531FD /* URL+isImage.swift */; };
85E4122A2A46C8CA00183F2B /* LocationsSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85E412292A46C8CA00183F2B /* LocationsSettings.swift */; };
B6041F4D29D7A4E9000F3454 /* SettingsPageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6041F4C29D7A4E9000F3454 /* SettingsPageView.swift */; };
B6041F5229D7D6D6000F3454 /* SettingsWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6041F5129D7D6D6000F3454 /* SettingsWindow.swift */; };
B60BE8BD297A167600841125 /* AcknowledgementRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B60BE8BC297A167600841125 /* AcknowledgementRowView.swift */; };
Expand Down Expand Up @@ -782,7 +787,12 @@
6CFF967B29BEBD5200182D6F /* WindowCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowCommands.swift; sourceTree = "<group>"; };
850C630F29D6B01D00E1444C /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
850C631129D6B03400E1444C /* SettingsPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsPage.swift; sourceTree = "<group>"; };
852C7E322A587279006BA599 /* SearchableSettingsPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchableSettingsPage.swift; sourceTree = "<group>"; };
852E62002A5C17E500447138 /* PageAndSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageAndSettings.swift; sourceTree = "<group>"; };
85745D622A38F8D900089AAB /* String+HighlightOccurrences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+HighlightOccurrences.swift"; sourceTree = "<group>"; };
85773E1D2A3E0A1F00C5D926 /* SettingsSearchResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsSearchResult.swift; sourceTree = "<group>"; };
85CD0C5E2A10CC3200E531FD /* URL+isImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+isImage.swift"; sourceTree = "<group>"; };
85E412292A46C8CA00183F2B /* LocationsSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationsSettings.swift; sourceTree = "<group>"; };
B6041F4C29D7A4E9000F3454 /* SettingsPageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsPageView.swift; sourceTree = "<group>"; };
B6041F5129D7D6D6000F3454 /* SettingsWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsWindow.swift; sourceTree = "<group>"; };
B60BE8BC297A167600841125 /* AcknowledgementRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AcknowledgementRowView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1248,6 +1258,7 @@
isa = PBXGroup;
children = (
58F2EACD292FB2B0004A9BDE /* Loopable.swift */,
852C7E322A587279006BA599 /* SearchableSettingsPage.swift */,
);
path = Protocols;
sourceTree = "<group>";
Expand Down Expand Up @@ -1975,6 +1986,7 @@
6CED16E32A3E660D000EC962 /* String+Lines.swift */,
58D01C8D293167DC00C5B6B4 /* String+RemoveOccurrences.swift */,
58D01C8C293167DC00C5B6B4 /* String+SHA256.swift */,
85745D622A38F8D900089AAB /* String+HighlightOccurrences.swift */,
);
path = String;
sourceTree = "<group>";
Expand Down Expand Up @@ -2108,8 +2120,8 @@
6C5BE51A2A3D5419002DA0FC /* FeatureFlags */ = {
isa = PBXGroup;
children = (
85AEE8D42A474EEC009507BC /* Models */,
6C5BE51B2A3D542B002DA0FC /* FeatureFlagsSettingsView.swift */,
6C5BE51D2A3D545F002DA0FC /* FeatureFlagsSettings.swift */,
);
path = FeatureFlags;
sourceTree = "<group>";
Expand Down Expand Up @@ -2173,6 +2185,14 @@
path = Text;
sourceTree = "<group>";
};
85AEE8D42A474EEC009507BC /* Models */ = {
isa = PBXGroup;
children = (
6C5BE51D2A3D545F002DA0FC /* FeatureFlagsSettings.swift */,
);
path = Models;
sourceTree = "<group>";
};
85CD0C5D2A10CC2500E531FD /* URL */ = {
isa = PBXGroup;
children = (
Expand All @@ -2181,6 +2201,14 @@
path = URL;
sourceTree = "<group>";
};
85E412282A46C8B900183F2B /* Models */ = {
isa = PBXGroup;
children = (
85E412292A46C8CA00183F2B /* LocationsSettings.swift */,
);
path = Models;
sourceTree = "<group>";
};
B61DA9DD29D929BF00BF4A43 /* Pages */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -2228,6 +2256,8 @@
6CD03B6929FC773F001BD1D0 /* SettingsInjector.swift */,
6C0D0C6729E861B000AE4D3F /* SettingsSidebarFix.swift */,
850C631129D6B03400E1444C /* SettingsPage.swift */,
85773E1D2A3E0A1F00C5D926 /* SettingsSearchResult.swift */,
852E62002A5C17E500447138 /* PageAndSettings.swift */,
);
path = Models;
sourceTree = "<group>";
Expand Down Expand Up @@ -2547,6 +2577,7 @@
B6F0516E29D9E35300D72287 /* LocationsSettings */ = {
isa = PBXGroup;
children = (
85E412282A46C8B900183F2B /* Models */,
B6F0516F29D9E36800D72287 /* LocationsSettingsView.swift */,
);
path = LocationsSettings;
Expand All @@ -2556,8 +2587,8 @@
isa = PBXGroup;
children = (
58F2EAE0292FB2B0004A9BDE /* ThemeSettings.swift */,
B6EA1FE629DA341D001BF195 /* Theme.swift */,
B6EA1FE429DA33DB001BF195 /* ThemeModel.swift */,
B6EA1FE629DA341D001BF195 /* Theme.swift */,
);
path = Models;
sourceTree = "<group>";
Expand Down Expand Up @@ -2866,6 +2897,7 @@
6C0D0C6829E861B000AE4D3F /* SettingsSidebarFix.swift in Sources */,
587B9E8429301D8F00AC7927 /* GitHubUser.swift in Sources */,
2072FA13280D74ED00C7F8D4 /* HistoryInspectorModel.swift in Sources */,
852E62012A5C17E500447138 /* PageAndSettings.swift in Sources */,
587B9DA029300ABD00AC7927 /* PanelDivider.swift in Sources */,
58822534292C280D00E83CDE /* CursorLocation.swift in Sources */,
201169E52837B40300F92B46 /* SourceControlNavigatorRepositoriesView.swift in Sources */,
Expand Down Expand Up @@ -2933,6 +2965,7 @@
5878DAB1291D627C00DD95A3 /* EditorPathBarComponent.swift in Sources */,
587B9E6E29301D8F00AC7927 /* GitLabProject.swift in Sources */,
58798234292E30B90085B254 /* FeedbackIssueArea.swift in Sources */,
852C7E332A587279006BA599 /* SearchableSettingsPage.swift in Sources */,
587B9E5F29301D8F00AC7927 /* GitLabProjectRouter.swift in Sources */,
587B9E7329301D8F00AC7927 /* GitRouter.swift in Sources */,
6C2C156129B4F52F00EA60A5 /* SplitViewModifiers.swift in Sources */,
Expand Down Expand Up @@ -2970,6 +3003,7 @@
B61DA9DF29D929E100BF4A43 /* GeneralSettingsView.swift in Sources */,
B6D7EA5C297107DD00301FAC /* InspectorField.swift in Sources */,
043C321427E31FF6006AE443 /* CodeEditDocumentController.swift in Sources */,
85E4122A2A46C8CA00183F2B /* LocationsSettings.swift in Sources */,
581550D129FBD30400684881 /* TextTableViewCell.swift in Sources */,
587B9E6629301D8F00AC7927 /* GitLabProjectHook.swift in Sources */,
587B9E9329301D8F00AC7927 /* BitBucketOAuthConfiguration.swift in Sources */,
Expand All @@ -2982,6 +3016,7 @@
58798219292D92370085B254 /* SearchModeModel.swift in Sources */,
6C5C891B2A3F736500A94FE1 /* FocusedValues.swift in Sources */,
B62AEDD72A27B3D0009A9F52 /* UtilityAreaTabViewModel.swift in Sources */,
85773E1E2A3E0A1F00C5D926 /* SettingsSearchResult.swift in Sources */,
B66A4E4F29C917B8004573B4 /* WelcomeWindow.swift in Sources */,
58D01C9D293167DC00C5B6B4 /* KeychainSwiftAccessOptions.swift in Sources */,
B6E41C8B29DE7AE80088F9F4 /* AccountsSettingsSigninView.swift in Sources */,
Expand Down Expand Up @@ -3146,6 +3181,7 @@
B6D7EA592971078500301FAC /* InspectorSection.swift in Sources */,
B6AB09A32AAABFEC0003A3A6 /* EditorTabBarLeadingAccessories.swift in Sources */,
58F2EAEF292FB2B0004A9BDE /* ThemeSettingsView.swift in Sources */,
85745D632A38F8D900089AAB /* String+HighlightOccurrences.swift in Sources */,
B6EE989027E8879A00CDD8AB /* InspectorAreaView.swift in Sources */,
587B9DA229300ABD00AC7927 /* EffectView.swift in Sources */,
6C97EBCC2978760400302F95 /* AcknowledgementsWindowController.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
{
"identity" : "codeedittextview",
"kind" : "remoteSourceControl",
"location" : "https://github.com/CodeEditApp/CodeEditTextView",
"location" : "https://github.com/CodeEditApp/CodeEditTextView.git",
"state" : {
"revision" : "7f130bd50bb9eb6bacf6a42700cce571ec82bd64",
"version" : "0.6.7"
Expand Down Expand Up @@ -230,8 +230,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/siteline/SwiftUI-Introspect",
"state" : {
"revision" : "84196bab1c7f05ad8c3c2a5bfb3058b1211e189f",
"version" : "0.6.1"
"revision" : "6dce3c8f5bfa8bc20120c7497da27e984a8813aa",
"version" : "0.7.0"
}
},
{
Expand Down
4 changes: 0 additions & 4 deletions CodeEdit/Features/Git/Accounts/Networking/GitRouter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@ enum GitHTTPEncoding: Int {
struct GitHTTPHeader {
var headerField: String
var value: String
init(headerField: String, value: String) {
self.headerField = headerField
self.value = value
}
}

protocol GitRouterConfiguration {
Expand Down
5 changes: 0 additions & 5 deletions CodeEdit/Features/Keybindings/CommandManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,6 @@ struct Command: Identifiable, Hashable {
let id: String
let title: String
let closureWrapper: CommandClosureWrapper
init(id: String, title: String, closureWrapper: CommandClosureWrapper) {
self.id = id
self.title = title
self.closureWrapper = closureWrapper
}
}

/// A simple wrapper for command closure
Expand Down
5 changes: 0 additions & 5 deletions CodeEdit/Features/Keybindings/ModifierKeysObserver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,6 @@ extension NSEvent {
let scope: Scope
let matching: EventTypeMask

init(scope: Scope, matching: EventTypeMask) {
self.scope = scope
self.matching = matching
}

public func receive<S>(subscriber: S) where S: Subscriber, Self.Failure == S.Failure, Self.Output == S.Input {
let subscription = Subscription(scope: scope, matching: matching, subscriber: subscriber)
subscriber.receive(subscription: subscription)
Expand Down
19 changes: 19 additions & 0 deletions CodeEdit/Features/Settings/Models/PageAndSettings.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// PageAndSettings.swift
// CodeEdit
//
// Created by Raymond Vleeshouwer on 10/07/23.
//

import Foundation

struct PageAndSettings: Identifiable, Equatable {
let id: UUID = UUID()
let page: SettingsPage
let settings: [SettingsPage]

init(_ page: SettingsPage) {
self.page = page
self.settings = SettingsData().propertiesOf(page.name)
}
}
52 changes: 44 additions & 8 deletions CodeEdit/Features/Settings/Models/SettingsData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//

import SwiftUI
import Foundation

/// # Settings
///
Expand All @@ -22,28 +23,28 @@ import SwiftUI
/// and providing a default value. Otherwise all settings get overridden.
struct SettingsData: Codable, Hashable {

/// The general global setting
/// The general global settings
var general: GeneralSettings = .init()

/// The global settings for text editing
/// The global settings for accounts
var accounts: AccountsSettings = .init()

/// The global settings for themes
var theme: ThemeSettings = .init()

/// The global settings for the terminal emulator
var terminal: TerminalSettings = .init()

/// The global settings for text editing
var textEditing: TextEditingSettings = .init()

/// The global settings for text editing
/// The global settings for the terminal emulator
var terminal: TerminalSettings = .init()

/// The global settings for source control
var sourceControl: SourceControlSettings = .init()

/// The global settings for keybindings
var keybindings: KeybindingsSettings = .init()

/// Featureflags settings
/// Feature Flags settings
var featureFlags: FeatureFlagsSettings = .init()

/// Default initializer
Expand All @@ -61,7 +62,42 @@ struct SettingsData: Codable, Hashable {
SourceControlSettings.self,
forKey: .sourceControl
) ?? .init()
self.keybindings = try container.decodeIfPresent(KeybindingsSettings.self, forKey: .keybindings) ?? .init()
self.keybindings = try container.decodeIfPresent(
KeybindingsSettings.self,
forKey: .keybindings
) ?? .init()
self.featureFlags = try container.decodeIfPresent(FeatureFlagsSettings.self, forKey: .featureFlags) ?? .init()
}

// swiftlint:disable cyclomatic_complexity
func propertiesOf(_ name: SettingsPage.Name) -> [SettingsPage] {
var settings: [SettingsPage] = []

switch name {
case .general:
general.searchKeys.forEach { settings.append(.init(name, isSetting: true, settingName: $0)) }
case .accounts:
accounts.searchKeys.forEach { settings.append(.init(name, isSetting: true, settingName: $0)) }
case .theme:
theme.searchKeys.forEach { settings.append(.init(name, isSetting: true, settingName: $0)) }
case .textEditing:
textEditing.searchKeys.forEach { settings.append(.init(name, isSetting: true, settingName: $0)) }
case .terminal:
terminal.searchKeys.forEach { settings.append(.init(name, isSetting: true, settingName: $0)) }
case .sourceControl:
sourceControl.searchKeys.forEach { settings.append(.init(name, isSetting: true, settingName: $0)) }
case .location:
LocationsSettings().searchKeys.forEach { settings.append(.init(name, isSetting: true, settingName: $0)) }
case .featureFlags:
featureFlags.searchKeys.forEach { settings.append(.init(name, isSetting: true, settingName: $0)) }
case .behavior: return [.init(name, settingName: "Error")]
case .navigation: return [.init(name, settingName: "Error")]
case .components: return [.init(name, settingName: "Error")]
case .keybindings: return [.init(name, settingName: "Error")]
case .advanced: return [.init(name, settingName: "Error")]
}

return settings
}
// swiftlint:enable cyclomatic_complexity
}
56 changes: 28 additions & 28 deletions CodeEdit/Features/Settings/Models/SettingsPage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,42 +8,17 @@
import Foundation
import SwiftUI

/// A struct for a preferences tab
struct SettingsPage: Hashable, Identifiable {
/// Default intializer
internal init(
_ name: Name,
baseColor: Color? = nil,
icon: IconResource? = nil,
hideName: Bool? = false,
children: [SettingsPage] = []
) {
self.children = children
self.name = name
self.baseColor = baseColor ?? .red
self.icon = icon ?? .system("questionmark.app")
self.hideName = hideName
}

var id: String { name.rawValue }

let name: Name
let baseColor: Color
let children: [SettingsPage]
let hideName: Bool?
var nameString: LocalizedStringKey { LocalizedStringKey(name.rawValue) }
let icon: IconResource?

/// A struct for a settings page
struct SettingsPage: Hashable, Equatable, Identifiable {
/// A struct for a sidebar icon, with a base color and SF Symbol
enum IconResource: Equatable, Hashable {
case system(_ name: String)
case symbol(_ name: String)
case asset(_ name: String)
}

/// An enum of all the preferences tabs
/// An enum of all the settings pages
enum Name: String {
// MARK: - App Preferences
case general = "General"
case accounts = "Accounts"
case behavior = "Behaviors"
Expand All @@ -59,4 +34,29 @@ struct SettingsPage: Hashable, Identifiable {
case advanced = "Advanced"
}

let id: UUID = UUID()

let name: Name
let baseColor: Color?
let isSetting: Bool
let settingName: String
var nameString: LocalizedStringKey {
LocalizedStringKey(name.rawValue)
}
let icon: IconResource?

/// Default initializer
init(
_ name: Name,
baseColor: Color? = nil,
icon: IconResource? = nil,
isSetting: Bool = false,
settingName: String = ""
) {
self.name = name
self.baseColor = baseColor
self.icon = icon
self.isSetting = isSetting
self.settingName = settingName
}
}
Loading

0 comments on commit 5122227

Please sign in to comment.