mchakravarty / CodeEditorView

SwiftUI code editor view for iOS, visionOS, and macOS
Apache License 2.0
685 stars 60 forks source link

Change to language configuration not properly propagated #108

Closed KrisSimon closed 2 months ago

KrisSimon commented 3 months ago

I habe embedded the editor like this:

        CodeEditor(
            text: $text,
            position: $position,
            messages: $messages,
            language: $langConfig.wrappedValue,
            layout: $layoutConfig.wrappedValue
        )
        .onChange(of: selectedItem){
            $text.wrappedValue = ""
            if let stringContent = selectedItem.stringContent {
                $text.wrappedValue = stringContent
            }
        }
        .onChange(of: $langConfig.wrappedValue.name){
            print("Changed \($langConfig.wrappedValue.name)")
        }
        .onAppear(){
            if let stringContent = selectedItem.stringContent {
                $text.wrappedValue = stringContent
            }
        }

if I change langConfig, i expect the editor to update, but it doesn't. How can I archive/trigger an update, when I change to a new language configuration?

mchakravarty commented 3 months ago

@KrisSimon Thanks for the bug report! A quick look at the code suggests that this is indeed an oversight. I will look into how to best fix this and let you know once I have got a solution.

ocapmycap commented 3 months ago

I have noticed a similar lack of propagation for font size:

struct Editor: View {
    @State private var text = "main = print 42"
    @State var position = CodeEditor.Position()
    @State var theme = CodeEditorView.Theme.brianTheme
    var body: some View {
        VStack {
            Button("Push me") {
                theme.fontSize = theme.fontSize + 1
            }
            CodeEditor(
                text: $text,
                position: $position,
                messages: .constant([])
            )
            .environment(\.codeEditorTheme, theme)
        }
    }
}

This change isn't reflected in the view.

mchakravarty commented 3 months ago

@ocapmycap Thanks for noticing that. That is in fact a more tricky problem. Theme's contain an id (which is a UUID). If the id changes, the view does update. However, your code modifies an existing theme, leaving the id as is.

The reason for this set up is that themes change rarely and I like to avoid a costly comparison of all the fields of a theme to happen in each SwiftUI update cycle.

I could force generating a new id on every change of any field of a theme by making all the properties let (instead of var) properties. However, that would make working with themes (e.g., in a theme editor) quite awkward.

An alternative might be to have a didSet at every property, which forces generating a new UUID. That makes each property update relatively expensive, but that should again not be a frequent operation.

mchakravarty commented 3 months ago

Additionally,

mchakravarty commented 2 months ago

@KrisSimon and @ocapmycap, the two bugs that you reported should be fixed in the latest commits on main. Please have a look and let me know if you still encounter any problems. Thanks again for the bug reports.

ocapmycap commented 2 months ago

@mchakravarty Apologies for the late reply and big thanks for addressing the issue! I will be able to check this later today and will report back.