From 9780995247900e01ff2391a2ac7366e95cbc9898 Mon Sep 17 00:00:00 2001 From: ayush-that Date: Sun, 8 Mar 2026 12:31:48 +0530 Subject: [PATCH] Fix Language Servers settings page UI and search - Replace broken ZStack overlay in LanguageServerRowView with clean VStack layout and single-line description - Replace .searchable() toolbar search with SearchField in a Section to match other settings pages - Replace List with LazyVStack for scroll performance - Replace fuzzy search with word-prefix matching for more intuitive filtering results - Style warning banner inline with small yellow icon matching Apple System Settings pattern - Remove unused getInfoString() --- .../Extensions/LanguageServerRowView.swift | 49 +------- .../Extensions/LanguageServersView.swift | 106 +++++++++--------- 2 files changed, 59 insertions(+), 96 deletions(-) diff --git a/CodeEdit/Features/Settings/Pages/Extensions/LanguageServerRowView.swift b/CodeEdit/Features/Settings/Pages/Extensions/LanguageServerRowView.swift index 02f423f8a0..e60aac6a93 100644 --- a/CodeEdit/Features/Settings/Pages/Extensions/LanguageServerRowView.swift +++ b/CodeEdit/Features/Settings/Pages/Extensions/LanguageServerRowView.swift @@ -27,8 +27,6 @@ struct LanguageServerRowView: View, Equatable { @State private var removalError: Error? @State private var showingRemovalError = false - @State private var showMore: Bool = false - @EnvironmentObject var registryManager: RegistryManager init( @@ -46,49 +44,10 @@ struct LanguageServerRowView: View, Equatable { Label { VStack(alignment: .leading) { Text(package.sanitizedName) - - ZStack(alignment: .leadingLastTextBaseline) { - VStack(alignment: .leading) { - Text(package.sanitizedDescription) - .font(.footnote) - .foregroundColor(.secondary) - .lineLimit(showMore ? nil : 1) - .truncationMode(.tail) - if showMore { - Button(package.homepagePretty) { - guard let url = package.homepageURL else { return } - NSWorkspace.shared.open(url) - } - .buttonStyle(.plain) - .foregroundColor(Color(NSColor.linkColor)) - .font(.footnote) - .cursor(.pointingHand) - if let installerName = package.installMethod?.packageManagerType?.rawValue { - Text("Install using \(installerName)") - .font(.footnote) - .foregroundColor(.secondary) - } - } - } - if isHovering { - HStack { - Spacer() - Button { - showMore.toggle() - } label: { - Text(showMore ? "Show Less" : "Show More") - .font(.footnote) - } - .buttonStyle(.plain) - .background( - Rectangle() - .inset(by: -2) - .fill(.clear) - .background(Color(NSColor.windowBackgroundColor)) - ) - } - } - } + Text(package.sanitizedDescription) + .font(.footnote) + .foregroundColor(.secondary) + .lineLimit(1) } } icon: { letterIcon() diff --git a/CodeEdit/Features/Settings/Pages/Extensions/LanguageServersView.swift b/CodeEdit/Features/Settings/Pages/Extensions/LanguageServersView.swift index 44cd02aafb..744af35ef4 100644 --- a/CodeEdit/Features/Settings/Pages/Extensions/LanguageServersView.swift +++ b/CodeEdit/Features/Settings/Pages/Extensions/LanguageServersView.swift @@ -10,51 +10,72 @@ import SwiftUI /// Displays a searchable list of packages from the ``RegistryManager``. struct LanguageServersView: View { @StateObject var registryManager: RegistryManager = .shared - @StateObject private var searchModel = FuzzySearchUIModel() @State private var searchText: String = "" + @State private var filteredItems: [RegistryItem]? @State private var selectedInstall: PackageManagerInstallOperation? - @State private var showingInfoPanel = false - var body: some View { - Group { + VStack { SettingsForm { - if registryManager.isDownloadingRegistry { - HStack { - Spacer() - ProgressView() - .controlSize(.small) - Spacer() - } + Section { + SearchField("Search", text: $searchText) } Section { - List(searchModel.items ?? registryManager.registryItems, id: \.name) { item in - LanguageServerRowView( - package: item, - onCancel: { - registryManager.cancelInstallation() - }, - onInstall: { [item] in - do { - selectedInstall = try registryManager.installOperation(package: item) - } catch { - // Display the error - NSAlert(error: error).runModal() - } + HStack(alignment: .firstTextBaseline, spacing: 4) { + Image(systemName: "exclamationmark.triangle.fill") + .font(.footnote) + .foregroundColor(.yellow) + Text("Warning: Language server installation is experimental. Use at your own risk.") + .font(.subheadline) + .foregroundColor(.secondary) + } + if registryManager.isDownloadingRegistry { + HStack { + Spacer() + ProgressView() + .controlSize(.small) + Spacer() + } + } else { + LazyVStack(spacing: 0) { + ForEach( + filteredItems ?? registryManager.registryItems, + id: \.name + ) { item in + Divider().padding(.horizontal, 10) + LanguageServerRowView( + package: item, + onCancel: { + registryManager.cancelInstallation() + }, + onInstall: { [item] in + do { + selectedInstall = try registryManager.installOperation( + package: item + ) + } catch { + NSAlert(error: error).runModal() + } + } + ) + .padding(10) } - ) - .listRowInsets(EdgeInsets(top: 8, leading: 8, bottom: 8, trailing: 8)) + } + .padding(-10) } - .searchable(text: $searchText) - .onChange(of: searchText) { _, newValue in - searchModel.searchTextUpdated(searchText: newValue, allItems: registryManager.registryItems) + } + } + .onChange(of: searchText) { _, newValue in + if newValue.isEmpty { + filteredItems = nil + } else { + let query = newValue.lowercased() + filteredItems = registryManager.registryItems.filter { item in + item.sanitizedName.lowercased().split(separator: " ").contains { + $0.hasPrefix(query) + } } - } header: { - Label( - "Warning: Language server installation is experimental. Use at your own risk.", - systemImage: "exclamationmark.triangle.fill" - ) } } .sheet(item: $selectedInstall) { operation in @@ -63,21 +84,4 @@ struct LanguageServersView: View { } .environmentObject(registryManager) } - - private func getInfoString() -> AttributedString { - let string = "CodeEdit makes use of the Mason Registry for language server installation. To install a package, " - + "CodeEdit uses the package manager directed by the Mason Registry, and installs a copy of " - + "the language server in Application Support.\n\n" - + "Language server installation is still experimental, there may be bugs and expect this flow " - + "to change over time." - - var attrString = AttributedString(string) - - if let linkRange = attrString.range(of: "Mason Registry") { - attrString[linkRange].link = URL(string: "https://mason-registry.dev/") - attrString[linkRange].foregroundColor = NSColor.linkColor - } - - return attrString - } }