diff --git a/CodeEdit/Features/CodeFile/CodeFile.swift b/CodeEdit/Features/CodeFile/CodeFile.swift index a1aff2149..36827c3dc 100644 --- a/CodeEdit/Features/CodeFile/CodeFile.swift +++ b/CodeEdit/Features/CodeFile/CodeFile.swift @@ -10,6 +10,7 @@ import Foundation import SwiftUI import UniformTypeIdentifiers import QuickLookUI +import CodeEditTextView import CodeEditLanguages enum CodeFileError: Error { @@ -28,6 +29,18 @@ final class CodeFileDocument: NSDocument, ObservableObject, QLPreviewItem { @Published var language: CodeLanguage? + /// Document-specific overriden indent option. + @Published + var indentOption: SettingsData.TextEditingSettings.IndentOption? + + /// Document-specific overriden tab width. + @Published + var defaultTabWidth: Int? + + /// Document-specific overriden line wrap preference. + @Published + var wrapLines: Bool? + /* This is the main type of the document. For example, if the file is end with '.png', it will be an image, diff --git a/CodeEdit/Features/CodeFile/CodeFileView.swift b/CodeEdit/Features/CodeFile/CodeFileView.swift index 210dc4248..4eccc55d3 100644 --- a/CodeEdit/Features/CodeFile/CodeFileView.swift +++ b/CodeEdit/Features/CodeFile/CodeFileView.swift @@ -17,7 +17,7 @@ struct CodeFileView: View { private var codeFile: CodeFileDocument @AppSettings(\.textEditing.defaultTabWidth) var defaultTabWidth - @AppSettings(\.textEditing.indentOption) var settingsIndentOption + @AppSettings(\.textEditing.indentOption) var indentOption @AppSettings(\.textEditing.lineHeightMultiple) var lineHeightMultiple @AppSettings(\.textEditing.wrapLinesToEditorWidth) var wrapLinesToEditorWidth @AppSettings(\.textEditing.font) var settingsFont @@ -88,17 +88,6 @@ struct CodeFileView: View { } }() - // Tab is a placeholder value, is overriden immediately in `init`. - @State - private var indentOption: IndentOption = { - switch Settings[\.textEditing].indentOption.indentType { - case .tab: - return .tab - case .spaces: - return .spaces(count: Settings[\.textEditing].indentOption.spaceCount) - } - }() - @Environment(\.edgeInsets) private var edgeInsets @@ -111,10 +100,10 @@ struct CodeFileView: View { language: getLanguage(), theme: selectedTheme.editor.editorTheme, font: font, - tabWidth: defaultTabWidth, - indentOption: indentOption, + tabWidth: codeFile.defaultTabWidth ?? defaultTabWidth, + indentOption: (codeFile.indentOption ?? indentOption).textViewOption(), lineHeight: lineHeightMultiple, - wrapLines: wrapLinesToEditorWidth, + wrapLines: codeFile.wrapLines ?? wrapLinesToEditorWidth, cursorPosition: $codeFile.cursorPosition, useThemeBackground: useThemeBackground, contentInsets: edgeInsets.nsEdgeInsets, @@ -148,14 +137,6 @@ struct CodeFileView: View { .onChange(of: bracketHighlight) { _ in bracketPairHighlight = getBracketPairHighlight() } - .onChange(of: settingsIndentOption) { option in - switch option.indentType { - case .tab: - self.indentOption = .tab - case .spaces: - self.indentOption = .spaces(count: option.spaceCount) - } - } } private func getLanguage() -> CodeLanguage { @@ -186,3 +167,16 @@ struct CodeFileView: View { } } } + +// This extension is kept here because it should not be used elsewhere in the app and may cause confusion +// due to the similar type name from the CETV module. +private extension SettingsData.TextEditingSettings.IndentOption { + func textViewOption() -> IndentOption { + switch self.indentType { + case .spaces: + return IndentOption.spaces(count: spaceCount) + case .tab: + return IndentOption.tab + } + } +} diff --git a/CodeEdit/Features/InspectorSidebar/Views/FileInspectorView.swift b/CodeEdit/Features/InspectorSidebar/Views/FileInspectorView.swift index e8d587097..3ba470e72 100644 --- a/CodeEdit/Features/InspectorSidebar/Views/FileInspectorView.swift +++ b/CodeEdit/Features/InspectorSidebar/Views/FileInspectorView.swift @@ -23,9 +23,20 @@ struct FileInspectorView: View { @State private var fileName: String = "" + // File settings overrides + @State private var language: CodeLanguage? + @State + var indentOption: SettingsData.TextEditingSettings.IndentOption = .init(indentType: .tab) + + @State + var defaultTabWidth: Int = 0 + + @State + var wrapLines: Bool = false + var body: some View { Group { if file != nil { @@ -40,7 +51,7 @@ struct FileInspectorView: View { Section("Text Settings") { indentUsing tabWidths - wrapLines + wrapLinesToggle } } } else { @@ -51,11 +62,22 @@ struct FileInspectorView: View { file = tabManager.activeTabGroup.selected fileName = file?.name ?? "" language = file?.fileDocument?.language + indentOption = file?.fileDocument?.indentOption ?? textEditing.indentOption + defaultTabWidth = file?.fileDocument?.defaultTabWidth ?? textEditing.defaultTabWidth + wrapLines = file?.fileDocument?.wrapLines ?? textEditing.wrapLinesToEditorWidth } .onAppear { file = tabManager.activeTabGroup.selected fileName = file?.name ?? "" language = file?.fileDocument?.language + indentOption = file?.fileDocument?.indentOption ?? textEditing.indentOption + defaultTabWidth = file?.fileDocument?.defaultTabWidth ?? textEditing.defaultTabWidth + wrapLines = file?.fileDocument?.wrapLines ?? textEditing.wrapLinesToEditorWidth + } + .onChange(of: textEditing) { newValue in + indentOption = file?.fileDocument?.indentOption ?? newValue.indentOption + defaultTabWidth = file?.fileDocument?.defaultTabWidth ?? newValue.defaultTabWidth + wrapLines = file?.fileDocument?.wrapLines ?? newValue.wrapLinesToEditorWidth } } @@ -147,15 +169,24 @@ struct FileInspectorView: View { } private var indentUsing: some View { - IndentOptionView() + IndentOptionView(indentOption: $indentOption) + .onChange(of: indentOption) { newValue in + file?.fileDocument?.indentOption = newValue == textEditing.indentOption ? nil : newValue + } } private var tabWidths: some View { - TabWidthOptionView() + TabWidthOptionView(defaultTabWidth: $defaultTabWidth) + .onChange(of: defaultTabWidth) { newValue in + file?.fileDocument?.defaultTabWidth = newValue == textEditing.defaultTabWidth ? nil : newValue + } } - private var wrapLines: some View { - Toggle("Wrap lines to editor width", isOn: $textEditing.wrapLinesToEditorWidth) + private var wrapLinesToggle: some View { + Toggle("Wrap lines to editor width", isOn: $wrapLines) + .onChange(of: wrapLines) { newValue in + file?.fileDocument?.wrapLines = newValue == textEditing.wrapLinesToEditorWidth ? nil : newValue + } } private func chooseNewFileLocation() -> URL? { diff --git a/CodeEdit/Features/Settings/Pages/TextEditingSettings/TextEditingSettingsView.swift b/CodeEdit/Features/Settings/Pages/TextEditingSettings/TextEditingSettingsView.swift index 14c5200ab..30077d9a0 100644 --- a/CodeEdit/Features/Settings/Pages/TextEditingSettings/TextEditingSettingsView.swift +++ b/CodeEdit/Features/Settings/Pages/TextEditingSettings/TextEditingSettingsView.swift @@ -86,26 +86,12 @@ private extension TextEditingSettingsView { @ViewBuilder private var indentOption: some View { - IndentOptionView() + IndentOptionView(indentOption: $textEditing.indentOption) } @ViewBuilder private var defaultTabWidth: some View { - HStack(alignment: .top) { - Stepper( - "Tab Width", - value: Binding( - get: { Double(textEditing.defaultTabWidth) }, - set: { textEditing.defaultTabWidth = Int($0) } - ), - in: 1...8, - step: 1, - format: .number - ) - Text("spaces") - .foregroundColor(.secondary) - } - .help("The visual width of tabs.") + TabWidthOptionView(defaultTabWidth: $textEditing.defaultTabWidth) } @ViewBuilder diff --git a/CodeEdit/Features/Settings/Pages/TextEditingSettings/Views/IndentOptionView.swift b/CodeEdit/Features/Settings/Pages/TextEditingSettings/Views/IndentOptionView.swift index 74cbd83bd..c49bfd098 100644 --- a/CodeEdit/Features/Settings/Pages/TextEditingSettings/Views/IndentOptionView.swift +++ b/CodeEdit/Features/Settings/Pages/TextEditingSettings/Views/IndentOptionView.swift @@ -8,23 +8,23 @@ import SwiftUI struct IndentOptionView: View { - @AppSettings(\.textEditing) private var textEditing + @Binding var indentOption: SettingsData.TextEditingSettings.IndentOption var body: some View { Group { - Picker("Prefer Indent Using", selection: $textEditing.indentOption.indentType) { + Picker("Prefer Indent Using", selection: $indentOption.indentType) { Text("Tabs") .tag(SettingsData.TextEditingSettings.IndentOption.IndentType.tab) Text("Spaces") .tag(SettingsData.TextEditingSettings.IndentOption.IndentType.spaces) } - if textEditing.indentOption.indentType == .spaces { + if indentOption.indentType == .spaces { HStack { Stepper( "Indent Width", value: Binding( - get: { Double(textEditing.indentOption.spaceCount) }, - set: { textEditing.indentOption.spaceCount = Int($0) } + get: { Double(indentOption.spaceCount) }, + set: { indentOption.spaceCount = Int($0) } ), in: 0...10, step: 1, diff --git a/CodeEdit/Features/Settings/Pages/TextEditingSettings/Views/TabWidthOptionView.swift b/CodeEdit/Features/Settings/Pages/TextEditingSettings/Views/TabWidthOptionView.swift index 2c9ca6251..526e92313 100644 --- a/CodeEdit/Features/Settings/Pages/TextEditingSettings/Views/TabWidthOptionView.swift +++ b/CodeEdit/Features/Settings/Pages/TextEditingSettings/Views/TabWidthOptionView.swift @@ -8,17 +8,17 @@ import SwiftUI struct TabWidthOptionView: View { - @AppSettings(\.textEditing) private var textEditing + @Binding var defaultTabWidth: Int var body: some View { HStack(alignment: .top) { Stepper( "Tab Width", value: Binding( - get: { Double(textEditing.defaultTabWidth) }, - set: { textEditing.defaultTabWidth = Int($0) } + get: { Double(defaultTabWidth) }, + set: { defaultTabWidth = Int($0) } ), - in: 1...8, + in: 1...16, step: 1, format: .number ) @@ -28,9 +28,3 @@ struct TabWidthOptionView: View { .help("The visual width of tabs.") } } - -struct TabWidthOptionView_Previews: PreviewProvider { - static var previews: some View { - TabWidthOptionView() - } -}