From 04e87cef10c9a919ba39b9e173616bcbef41ea3f Mon Sep 17 00:00:00 2001 From: Abe M Date: Wed, 7 Feb 2024 01:15:52 -0800 Subject: [PATCH 01/20] Updated packages --- CodeEdit.xcodeproj/project.pbxproj | 33 +++---- .../xcshareddata/swiftpm/Package.resolved | 96 +++---------------- .../xcshareddata/xcschemes/CodeEdit.xcscheme | 2 +- 3 files changed, 27 insertions(+), 104 deletions(-) diff --git a/CodeEdit.xcodeproj/project.pbxproj b/CodeEdit.xcodeproj/project.pbxproj index 9a13156059..0eb8ef73bc 100644 --- a/CodeEdit.xcodeproj/project.pbxproj +++ b/CodeEdit.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 55; + objectVersion = 60; objects = { /* Begin PBXBuildFile section */ @@ -288,7 +288,6 @@ 6C092EDA2A53A58600489202 /* EditorLayout+StateRestoration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C092ED92A53A58600489202 /* EditorLayout+StateRestoration.swift */; }; 6C092EE02A53BFCF00489202 /* WorkspaceStateKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C092EDF2A53BFCF00489202 /* WorkspaceStateKey.swift */; }; 6C0D0C6829E861B000AE4D3F /* SettingsSidebarFix.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C0D0C6729E861B000AE4D3F /* SettingsSidebarFix.swift */; }; - 6C0F3A3C2A1D0D5000223D19 /* CodeEditKit in Frameworks */ = {isa = PBXBuildFile; productRef = 6C0F3A3B2A1D0D5000223D19 /* CodeEditKit */; }; 6C147C4029A328BC0089B630 /* SplitViewData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C147C3F29A328560089B630 /* SplitViewData.swift */; }; 6C147C4129A328BF0089B630 /* EditorLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C147C3E29A3281D0089B630 /* EditorLayout.swift */; }; 6C147C4229A328C10089B630 /* Editor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C147C3D29A3281D0089B630 /* Editor.swift */; }; @@ -1065,7 +1064,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 6C0F3A3C2A1D0D5000223D19 /* CodeEditKit in Frameworks */, 6C5BE5222A3D5666002DA0FC /* WindowManagement in Frameworks */, 6C66C31329D05CDC00DE9ED2 /* GRDB in Frameworks */, 58F2EB1E292FB954004A9BDE /* Sparkle in Frameworks */, @@ -3030,7 +3028,6 @@ 6C66C31229D05CDC00DE9ED2 /* GRDB */, 6C2149402A1BB9AB00748382 /* LogStream */, 6CDEFC9529E22C2700B7C684 /* Introspect */, - 6C0F3A3B2A1D0D5000223D19 /* CodeEditKit */, 6C5BE5212A3D5666002DA0FC /* WindowManagement */, 6CE952E22B29433500C29C31 /* CodeEditSourceEditor */, ); @@ -3087,7 +3084,7 @@ attributes = { BuildIndependentTargetsInParallel = 1; LastSwiftUpdateCheck = 1330; - LastUpgradeCheck = 1430; + LastUpgradeCheck = 1520; TargetAttributes = { 2BE487EB28245162003F3F64 = { CreatedOnToolsVersion = 13.3.1; @@ -3126,9 +3123,9 @@ 6C66C31129D05CC800DE9ED2 /* XCRemoteSwiftPackageReference "GRDB.swift" */, 6C21493F2A1BB9AB00748382 /* XCRemoteSwiftPackageReference "LogStream" */, 6CDEFC9429E22C2700B7C684 /* XCRemoteSwiftPackageReference "SwiftUI-Introspect" */, - 6C0F3A3A2A1D0D5000223D19 /* XCRemoteSwiftPackageReference "CodeEditKit" */, 6C5BE5202A3D5666002DA0FC /* XCRemoteSwiftPackageReference "SwiftUI-WindowManagement" */, 6CE952E12B29433500C29C31 /* XCRemoteSwiftPackageReference "CodeEditSourceEditor" */, + 30AAFCD02B7380EF007177DC /* XCLocalSwiftPackageReference "../CodeEditKit" */, ); productRefGroup = B658FB2D27DA9E0F00EA4DBD /* Products */; projectDirPath = ""; @@ -3796,6 +3793,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -3985,6 +3983,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -4240,6 +4239,7 @@ DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -4309,6 +4309,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -4576,6 +4577,13 @@ }; /* End XCConfigurationList section */ +/* Begin XCLocalSwiftPackageReference section */ + 30AAFCD02B7380EF007177DC /* XCLocalSwiftPackageReference "../CodeEditKit" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = ../CodeEditKit; + }; +/* End XCLocalSwiftPackageReference section */ + /* Begin XCRemoteSwiftPackageReference section */ 2816F592280CF50500DD548B /* XCRemoteSwiftPackageReference "CodeEditSymbols" */ = { isa = XCRemoteSwiftPackageReference; @@ -4617,14 +4625,6 @@ version = 2.3.0; }; }; - 6C0F3A3A2A1D0D5000223D19 /* XCRemoteSwiftPackageReference "CodeEditKit" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/CodeEditApp/CodeEditKit"; - requirement = { - kind = exactVersion; - version = 0.1.0; - }; - }; 6C147C4329A329350089B630 /* XCRemoteSwiftPackageReference "swift-collections" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/apple/swift-collections.git"; @@ -4704,11 +4704,6 @@ package = 58F2EB1C292FB954004A9BDE /* XCRemoteSwiftPackageReference "Sparkle" */; productName = Sparkle; }; - 6C0F3A3B2A1D0D5000223D19 /* CodeEditKit */ = { - isa = XCSwiftPackageProductDependency; - package = 6C0F3A3A2A1D0D5000223D19 /* XCRemoteSwiftPackageReference "CodeEditKit" */; - productName = CodeEditKit; - }; 6C147C4429A329350089B630 /* OrderedCollections */ = { isa = XCSwiftPackageProductDependency; package = 6C147C4329A329350089B630 /* XCRemoteSwiftPackageReference "swift-collections" */; diff --git a/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 4966272a3b..283fa6d921 100644 --- a/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -9,15 +9,6 @@ "version" : "0.6.7" } }, - { - "identity" : "codeeditkit", - "kind" : "remoteSourceControl", - "location" : "https://github.com/CodeEditApp/CodeEditKit", - "state" : { - "revision" : "9ba3343ac53eb66a213a0a525604e297d8584a45", - "version" : "0.1.0" - } - }, { "identity" : "codeeditlanguages", "kind" : "remoteSourceControl", @@ -72,24 +63,6 @@ "version" : "0.4.2" } }, - { - "identity" : "fseventswrapper", - "kind" : "remoteSourceControl", - "location" : "https://github.com/Frizlab/FSEventsWrapper", - "state" : { - "revision" : "e0c59a2ce2775e5f6642da6d19207445f10112d0", - "version" : "1.0.2" - } - }, - { - "identity" : "glob", - "kind" : "remoteSourceControl", - "location" : "https://github.com/Bouke/Glob", - "state" : { - "revision" : "deda6e163d2ff2a8d7e138e2c3326dbd71157faf", - "version" : "1.0.5" - } - }, { "identity" : "grdb.swift", "kind" : "remoteSourceControl", @@ -99,33 +72,6 @@ "version" : "5.26.1" } }, - { - "identity" : "jsonrpc", - "kind" : "remoteSourceControl", - "location" : "https://github.com/ChimeHQ/JSONRPC", - "state" : { - "revision" : "aa785ad404bdcf7ec692908b3905dd4c87e87141", - "version" : "0.7.1" - } - }, - { - "identity" : "languageclient", - "kind" : "remoteSourceControl", - "location" : "https://github.com/ChimeHQ/LanguageClient", - "state" : { - "revision" : "92beeecd0bb783da52227839ba6c55e43fc866ec", - "version" : "0.5.1" - } - }, - { - "identity" : "languageserverprotocol", - "kind" : "remoteSourceControl", - "location" : "https://github.com/ChimeHQ/LanguageServerProtocol", - "state" : { - "revision" : "cae01173f45b0518ae5533b083edd153633af984", - "version" : "0.9.2" - } - }, { "identity" : "logstream", "kind" : "remoteSourceControl", @@ -140,26 +86,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/mattmassicotte/MainOffender", "state" : { - "revision" : "343cc3797618c29b48b037b4e2beea0664e75315", - "version" : "0.1.0" - } - }, - { - "identity" : "processenv", - "kind" : "remoteSourceControl", - "location" : "https://github.com/ChimeHQ/ProcessEnv", - "state" : { - "revision" : "29487b6581bb785c372c611c943541ef4309d051", - "version" : "0.3.1" - } - }, - { - "identity" : "processservice", - "kind" : "remoteSourceControl", - "location" : "https://github.com/ChimeHQ/ProcessService", - "state" : { - "revision" : "369fb0379983d3b43c7d7ad62c4e91ee020e347c", - "version" : "0.2.6" + "revision" : "8de872d9256ff7f9913cbc5dd560568ab164be45", + "version" : "0.2.1" } }, { @@ -167,8 +95,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/ChimeHQ/Rearrange", "state" : { - "revision" : "0fb658e721c68495f6340c211cc6d4719e6b52d8", - "version" : "1.6.0" + "revision" : "5ff7f3363f7a08f77e0d761e38e6add31c2136e1", + "version" : "1.8.1" } }, { @@ -185,8 +113,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-collections.git", "state" : { - "revision" : "937e904258d22af6e447a0b72c0bc67583ef64a2", - "version" : "1.0.4" + "revision" : "d029d9d39c87bed85b1c50adee7c41795261a192", + "version" : "1.0.6" } }, { @@ -203,8 +131,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-syntax.git", "state" : { - "revision" : "6ad4ea24b01559dde0773e3d091f1b9e36175036", - "version" : "509.0.2" + "revision" : "64889f0c732f210a935a0ad7cda38f77f876262d", + "version" : "509.1.1" } }, { @@ -212,8 +140,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/lukepistrol/SwiftLintPlugin", "state" : { - "revision" : "d3ec7fb242ebe1d8e23bf17e58a1e27d43125994", - "version" : "0.2.6" + "revision" : "ea6d3ca895b49910f790e98e4b4ca658e0fe490e", + "version" : "0.54.0" } }, { @@ -239,8 +167,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/siteline/SwiftUI-Introspect", "state" : { - "revision" : "6dce3c8f5bfa8bc20120c7497da27e984a8813aa", - "version" : "0.7.0" + "revision" : "121c146fe591b1320238d054ae35c81ffa45f45a", + "version" : "0.12.0" } }, { diff --git a/CodeEdit.xcodeproj/xcshareddata/xcschemes/CodeEdit.xcscheme b/CodeEdit.xcodeproj/xcshareddata/xcschemes/CodeEdit.xcscheme index 97eb1050e7..d137f5e22c 100644 --- a/CodeEdit.xcodeproj/xcshareddata/xcschemes/CodeEdit.xcscheme +++ b/CodeEdit.xcodeproj/xcshareddata/xcschemes/CodeEdit.xcscheme @@ -1,6 +1,6 @@ Date: Wed, 7 Feb 2024 02:09:23 -0800 Subject: [PATCH 02/20] Use local packages, fix errors --- CodeEdit.xcodeproj/project.pbxproj | 36 ++++- .../xcshareddata/swiftpm/Package.resolved | 54 +++++++ CodeEdit/Features/Editor/Models/Editor.swift | 13 +- CodeEdit/Features/LSP/LSPCache.swift | 92 +++++++++++ CodeEdit/Features/LSP/LanguageServer.swift | 151 ++++++++++++++++++ 5 files changed, 338 insertions(+), 8 deletions(-) create mode 100644 CodeEdit/Features/LSP/LSPCache.swift create mode 100644 CodeEdit/Features/LSP/LanguageServer.swift diff --git a/CodeEdit.xcodeproj/project.pbxproj b/CodeEdit.xcodeproj/project.pbxproj index 0eb8ef73bc..b8a7c48c70 100644 --- a/CodeEdit.xcodeproj/project.pbxproj +++ b/CodeEdit.xcodeproj/project.pbxproj @@ -60,6 +60,9 @@ 2BE487EF28245162003F3F64 /* FinderSync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2BE487EE28245162003F3F64 /* FinderSync.swift */; }; 2BE487F428245162003F3F64 /* OpenWithCodeEdit.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 2BE487EC28245162003F3F64 /* OpenWithCodeEdit.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 3026F50F2AC006C80061227E /* InspectorAreaViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3026F50E2AC006C80061227E /* InspectorAreaViewModel.swift */; }; + 3039C8DD2B738D5A00C8B4F8 /* LanguageClient in Frameworks */ = {isa = PBXBuildFile; productRef = 3039C8DC2B738D5A00C8B4F8 /* LanguageClient */; }; + 305811812B73832B0049C9AA /* LanguageServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 305811802B73832B0049C9AA /* LanguageServer.swift */; }; + 305811832B73834F0049C9AA /* LSPCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 305811822B73834F0049C9AA /* LSPCache.swift */; }; 30E6D0012A6E505200A58B20 /* NavigatorSidebarViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30E6D0002A6E505200A58B20 /* NavigatorSidebarViewModel.swift */; }; 3E0196732A3921AC002648D8 /* codeedit_shell_integration.zsh in Resources */ = {isa = PBXBuildFile; fileRef = 3E0196722A3921AC002648D8 /* codeedit_shell_integration.zsh */; }; 3E01967A2A392B45002648D8 /* codeedit_shell_integration.bash in Resources */ = {isa = PBXBuildFile; fileRef = 3E0196792A392B45002648D8 /* codeedit_shell_integration.bash */; }; @@ -305,7 +308,6 @@ 6C2C155A29B4F4CC00EA60A5 /* Variadic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C2C155929B4F4CC00EA60A5 /* Variadic.swift */; }; 6C2C155D29B4F4E500EA60A5 /* SplitViewReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C2C155C29B4F4E500EA60A5 /* SplitViewReader.swift */; }; 6C2C156129B4F52F00EA60A5 /* SplitViewModifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C2C156029B4F52F00EA60A5 /* SplitViewModifiers.swift */; }; - 6C2C20172A4016FF0047EDF2 /* (null) in Frameworks */ = {isa = PBXBuildFile; }; 6C4104E3297C87A000F472BA /* BlurButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C4104E2297C87A000F472BA /* BlurButtonStyle.swift */; }; 6C4104E6297C884F00F472BA /* AboutDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C4104E5297C884F00F472BA /* AboutDetailView.swift */; }; 6C4104E9297C970F00F472BA /* AboutDefaultView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C4104E8297C970F00F472BA /* AboutDefaultView.swift */; }; @@ -620,6 +622,8 @@ 2BE487EE28245162003F3F64 /* FinderSync.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FinderSync.swift; sourceTree = ""; }; 2BE487F028245162003F3F64 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 3026F50E2AC006C80061227E /* InspectorAreaViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InspectorAreaViewModel.swift; sourceTree = ""; }; + 305811802B73832B0049C9AA /* LanguageServer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LanguageServer.swift; sourceTree = ""; }; + 305811822B73834F0049C9AA /* LSPCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LSPCache.swift; sourceTree = ""; }; 30E6D0002A6E505200A58B20 /* NavigatorSidebarViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigatorSidebarViewModel.swift; sourceTree = ""; }; 3E0196722A3921AC002648D8 /* codeedit_shell_integration.zsh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = codeedit_shell_integration.zsh; sourceTree = ""; }; 3E0196792A392B45002648D8 /* codeedit_shell_integration.bash */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = codeedit_shell_integration.bash; sourceTree = ""; }; @@ -1075,7 +1079,7 @@ 6CDEFC9629E22C2700B7C684 /* Introspect in Frameworks */, 2816F594280CF50500DD548B /* CodeEditSymbols in Frameworks */, 6C6BD6F829CD14D100235D17 /* CodeEditKit in Frameworks */, - 6C2C20172A4016FF0047EDF2 /* (null) in Frameworks */, + 3039C8DD2B738D5A00C8B4F8 /* LanguageClient in Frameworks */, 6C81916B29B41DD300B75C92 /* DequeModule in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1314,6 +1318,15 @@ path = ViewModels; sourceTree = ""; }; + 3058117F2B7383090049C9AA /* LSP */ = { + isa = PBXGroup; + children = ( + 305811802B73832B0049C9AA /* LanguageServer.swift */, + 305811822B73834F0049C9AA /* LSPCache.swift */, + ); + path = LSP; + sourceTree = ""; + }; 307AC4CB2ABABD9800163376 /* ViewModels */ = { isa = PBXGroup; children = ( @@ -1420,6 +1433,7 @@ 587B9E0129301D8F00AC7927 /* Git */, B6EE988E27E8877C00CDD8AB /* InspectorArea */, 58A5DF9D29339F6400D1BD5D /* Keybindings */, + 3058117F2B7383090049C9AA /* LSP */, 287776EA27E350A100D46668 /* NavigatorArea */, 5878DAA0291AE76700DD95A3 /* QuickOpen */, 58798210292D92370085B254 /* Search */, @@ -3030,6 +3044,7 @@ 6CDEFC9529E22C2700B7C684 /* Introspect */, 6C5BE5212A3D5666002DA0FC /* WindowManagement */, 6CE952E22B29433500C29C31 /* CodeEditSourceEditor */, + 3039C8DC2B738D5A00C8B4F8 /* LanguageClient */, ); productName = CodeEdit; productReference = B658FB2C27DA9E0F00EA4DBD /* CodeEdit.app */; @@ -3126,6 +3141,8 @@ 6C5BE5202A3D5666002DA0FC /* XCRemoteSwiftPackageReference "SwiftUI-WindowManagement" */, 6CE952E12B29433500C29C31 /* XCRemoteSwiftPackageReference "CodeEditSourceEditor" */, 30AAFCD02B7380EF007177DC /* XCLocalSwiftPackageReference "../CodeEditKit" */, + 30E1AAB12B73856500420274 /* XCLocalSwiftPackageReference "../LanguageClient" */, + 3039C8DF2B738D9B00C8B4F8 /* XCLocalSwiftPackageReference "../LanguageServerProtocol" */, ); productRefGroup = B658FB2D27DA9E0F00EA4DBD /* Products */; projectDirPath = ""; @@ -3464,6 +3481,7 @@ 6111920C2B08CD0B00D4459B /* SearchIndexer+InternalMethods.swift in Sources */, 6CABB1A129C5593800340467 /* OverlayView.swift in Sources */, D7211D4327E066CE008F2ED7 /* Localized+Ex.swift in Sources */, + 305811832B73834F0049C9AA /* LSPCache.swift in Sources */, 581BFB692926431000D251EC /* WelcomeActionView.swift in Sources */, 20D839AE280E0CA700B27357 /* HistoryPopoverView.swift in Sources */, B6E41C7029DD157F0088F9F4 /* AccountsSettingsView.swift in Sources */, @@ -3481,6 +3499,7 @@ 58D01C96293167DC00C5B6B4 /* Date+Formatted.swift in Sources */, B66A4E5629C918A0004573B4 /* SceneID.swift in Sources */, 6C53AAD829A6C4FD00EE9ED6 /* SplitView.swift in Sources */, + 305811812B73832B0049C9AA /* LanguageServer.swift in Sources */, B66A4E5329C91831004573B4 /* CodeEditCommands.swift in Sources */, 58822529292C280D00E83CDE /* StatusBarLineEndSelector.swift in Sources */, 5C4BB1E128212B1E00A92FB2 /* World.swift in Sources */, @@ -4578,10 +4597,18 @@ /* End XCConfigurationList section */ /* Begin XCLocalSwiftPackageReference section */ + 3039C8DF2B738D9B00C8B4F8 /* XCLocalSwiftPackageReference "../LanguageServerProtocol" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = ../LanguageServerProtocol; + }; 30AAFCD02B7380EF007177DC /* XCLocalSwiftPackageReference "../CodeEditKit" */ = { isa = XCLocalSwiftPackageReference; relativePath = ../CodeEditKit; }; + 30E1AAB12B73856500420274 /* XCLocalSwiftPackageReference "../LanguageClient" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = ../LanguageClient; + }; /* End XCLocalSwiftPackageReference section */ /* Begin XCRemoteSwiftPackageReference section */ @@ -4689,6 +4716,11 @@ package = 2816F592280CF50500DD548B /* XCRemoteSwiftPackageReference "CodeEditSymbols" */; productName = CodeEditSymbols; }; + 3039C8DC2B738D5A00C8B4F8 /* LanguageClient */ = { + isa = XCSwiftPackageProductDependency; + package = 30E1AAB12B73856500420274 /* XCLocalSwiftPackageReference "../LanguageClient" */; + productName = LanguageClient; + }; 583E529B29361BAB001AB554 /* SnapshotTesting */ = { isa = XCSwiftPackageProductDependency; package = 583E529A29361BAB001AB554 /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */; diff --git a/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 283fa6d921..1292113f8a 100644 --- a/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -63,6 +63,24 @@ "version" : "0.4.2" } }, + { + "identity" : "fseventswrapper", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Frizlab/FSEventsWrapper", + "state" : { + "revision" : "70bbea4b108221fcabfce8dbced8502831c0ae04", + "version" : "2.1.0" + } + }, + { + "identity" : "globpattern", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ChimeHQ/GlobPattern", + "state" : { + "revision" : "4ebb9e89e07cc475efa74f87dc6d21f4a9e060f8", + "version" : "0.1.1" + } + }, { "identity" : "grdb.swift", "kind" : "remoteSourceControl", @@ -72,6 +90,15 @@ "version" : "5.26.1" } }, + { + "identity" : "jsonrpc", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ChimeHQ/JSONRPC", + "state" : { + "revision" : "c6ec759d41a76ac88fe7327c41a77d9033943374", + "version" : "0.9.0" + } + }, { "identity" : "logstream", "kind" : "remoteSourceControl", @@ -90,6 +117,24 @@ "version" : "0.2.1" } }, + { + "identity" : "processenv", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ChimeHQ/ProcessEnv", + "state" : { + "revision" : "83f1ebc9dd6fb1db0bd89a3fcae00488a0f3fdd9", + "version" : "1.0.0" + } + }, + { + "identity" : "queue", + "kind" : "remoteSourceControl", + "location" : "https://github.com/mattmassicotte/Queue", + "state" : { + "revision" : "8d6f936097888f97011610ced40313655dc5948d", + "version" : "0.1.4" + } + }, { "identity" : "rearrange", "kind" : "remoteSourceControl", @@ -99,6 +144,15 @@ "version" : "1.8.1" } }, + { + "identity" : "semaphore", + "kind" : "remoteSourceControl", + "location" : "https://github.com/groue/Semaphore", + "state" : { + "revision" : "f1c4a0acabeb591068dea6cffdd39660b86dec28", + "version" : "0.0.8" + } + }, { "identity" : "sparkle", "kind" : "remoteSourceControl", diff --git a/CodeEdit/Features/Editor/Models/Editor.swift b/CodeEdit/Features/Editor/Models/Editor.swift index 2a494baa1f..609f58061f 100644 --- a/CodeEdit/Features/Editor/Models/Editor.swift +++ b/CodeEdit/Features/Editor/Models/Editor.swift @@ -169,12 +169,12 @@ final class Editor: ObservableObject, Identifiable { default: break } - - do { - try openFile(item: item) - } catch { - print(error) - } +// TODO: IS THIS NEEDED? openFile ALREADY GETS CALLED INSIDE openTab +// do { +// try openFile(item: item) +// } catch { +// print(error) +// } } /// Opens a tab in the editor. @@ -210,6 +210,7 @@ final class Editor: ObservableObject, Identifiable { let contentType = try item.file.url.resourceValues(forKeys: [.contentTypeKey]).contentType let codeFile = try CodeFileDocument( for: item.file.url, + // TODO: FILE CONTENTS ARE READ MULTIPLE TIMES withContentsOf: item.file.url, ofType: contentType?.identifier ?? "" ) diff --git a/CodeEdit/Features/LSP/LSPCache.swift b/CodeEdit/Features/LSP/LSPCache.swift new file mode 100644 index 0000000000..fac944bbca --- /dev/null +++ b/CodeEdit/Features/LSP/LSPCache.swift @@ -0,0 +1,92 @@ +// +// LSPCache.swift +// CodeEdit +// +// Created by Abe Malla on 2/7/24. +// + +import Foundation + +struct CacheKey: Hashable { + let uri: String + let requestType: String +} + +// TODO: SWITCH TO DOUBLY LINK LIST + +/// Thread safe implementation for caching LSP requests with time based expiration and cache size limits. +class LSPCache { + /// Represents a single cache entry with a generic type and an expiration date. + private struct CacheEntry { + let value: T + let expirationDate: Date + } + + /// The main cache storage mapping a `CacheKey` to a generic value. + private var cache = [CacheKey: Any]() + /// A collection of locks, one per cache key, for thread-safe access to cache entries. + /// `DispatchQueue` is used for synchronization to ensure that cache operations are thread-safe. + private var locks = [CacheKey: DispatchQueue]() + /// The maximum number of entries that the cache can hold. + private var cacheSizeLimit: Int + /// Tracks the order of cache keys for potential eviction. + private var cacheEntriesOrder: [CacheKey] = [] + /// Queue for handling the eviction of old cache entries. Separated from main cache operations to not block them. + private let evictionQueue = DispatchQueue(label: "com.CodeEdit.LSPCache.evictionQueue") + + init(cacheSizeLimit: Int = 100) { + self.cacheSizeLimit = cacheSizeLimit + } + + private func lock(for key: CacheKey) -> DispatchQueue { + if let lock = locks[key] { + return lock + } else { + let newLock = DispatchQueue(label: "com.CodeEdit.LSPCache.lock.\(key)") + locks[key] = newLock + return newLock + } + } + + func get(key: CacheKey) -> T? { + var result: T? + lock(for: key).sync { // Sync to ensure thread safe access + guard let entry = cache[key] as? CacheEntry, Date() < entry.expirationDate else { return } + result = entry.value + } + return result + } + + func set(key: CacheKey, value: T, withExpiry expiry: TimeInterval = 300) { + lock(for: key).async { + let expirationDate = Date().addingTimeInterval(expiry) + let entry = CacheEntry(value: value, expirationDate: expirationDate) + self.cache[key] = entry + } + scheduleEviction() + } + + func invalidate(key: CacheKey) { + lock(for: key).async { + self.cache.removeValue(forKey: key) + } + } + + private func scheduleEviction() { + // TODO: DECIDE ON EVICTION INTERVAL + evictionQueue.asyncAfter(deadline: .now() + 10) { + self.evictIfNeeded() + } + } + + private func evictIfNeeded() { + evictionQueue.async(flags: .barrier) { + while self.cacheEntriesOrder.count > self.cacheSizeLimit { + if let oldestKey = self.cacheEntriesOrder.first { + self.cache.removeValue(forKey: oldestKey) + self.cacheEntriesOrder.removeFirst() + } + } + } + } +} diff --git a/CodeEdit/Features/LSP/LanguageServer.swift b/CodeEdit/Features/LSP/LanguageServer.swift new file mode 100644 index 0000000000..b0cb5e2e56 --- /dev/null +++ b/CodeEdit/Features/LSP/LanguageServer.swift @@ -0,0 +1,151 @@ +// +// LanguageServer.swift +// CodeEdit +// +// Created by Abe Malla on 2/7/24. +// + +import Foundation +import JSONRPC +import LanguageClient +import LanguageServerProtocol + +struct LanguageServer { + let languageId: LanguageIdentifier + let binary: LanguageServerBinary + + // TODO: REMOVE + var trackedDocuments: [String: TextDocumentItem] = [:] + var lspCache: LSPCache = LSPCache() + + private(set) var lspInstance: InitializingServer + private(set) var rootPath: URL + + static func createServer(for languageId: LanguageIdentifier, with binary: LanguageServerBinary, rootPath: URL, workspaceFolders: [WorkspaceFolder]?) throws -> Self { + let executionParams = Process.ExecutionParameters( + path: binary.execPath, + arguments: binary.args, + environment: binary.env + ) + + var channel: DataChannel? + do { + channel = try DataChannel.localProcessChannel( + parameters: executionParams, + terminationHandler: { + print("Terminated \(languageId)") + } + ) + } catch { +// logger.error("Failed to start server for language \(languageId.rawValue)") + throw error + } + guard let channel = channel else { + throw NSError(domain: "LanguageClient", code: 1, userInfo: [NSLocalizedDescriptionKey: "Failed to start server for language \(languageId.rawValue)"]) + } + + let localServer = LanguageServerProtocol.JSONRPCServerConnection(dataChannel: channel) + let server = InitializingServer(server: localServer, initializeParamsProvider: getInitParams(projectURL: rootPath)) + return LanguageServer(languageId: languageId, binary: binary, lspInstance: server, rootPath: rootPath) + } + + private static func getInitParams(projectURL: URL) -> InitializingServer.InitializeParamsProvider { + // TODO: FILL THIS OUT PROPERLY + let provider: InitializingServer.InitializeParamsProvider = { + // Text Document Capabilities + let textDocumentCapabilities = TextDocumentClientCapabilities( + completion: CompletionClientCapabilities( + dynamicRegistration: true, + completionItem: CompletionClientCapabilities.CompletionItem( + snippetSupport: true, + commitCharactersSupport: true, + documentationFormat: [MarkupKind.plaintext], + deprecatedSupport: true, + preselectSupport: true, + tagSupport: ValueSet(valueSet: [CompletionItemTag.deprecated]), + insertReplaceSupport: true, + resolveSupport: CompletionClientCapabilities.CompletionItem.ResolveSupport( + properties: ["documentation", "details"] + ), + insertTextModeSupport: ValueSet(valueSet: [InsertTextMode.adjustIndentation]), + labelDetailsSupport: true + ), + completionItemKind: ValueSet(valueSet: [CompletionItemKind.text, CompletionItemKind.method]), + contextSupport: true, + insertTextMode: InsertTextMode.asIs, + completionList: CompletionClientCapabilities.CompletionList( + itemDefaults: ["default1", "default2"] + ) + ) + ) + + // Workspace File Operations Capabilities + let fileOperations = ClientCapabilities.Workspace.FileOperations( + dynamicRegistration: true, + didCreate: true, + willCreate: true, + didRename: true, + willRename: true, + didDelete: true, + willDelete: true + ) + + // Workspace Capabilities + // TODO: ADD inlineValue?: InlineValueWorkspaceClientCapabilities; inlayHint?: InlayHintWorkspaceClientCapabilities; diagnostics?: DiagnosticWorkspaceClientCapabilities; + let workspaceCapabilities = ClientCapabilities.Workspace( + applyEdit: true, + workspaceEdit: nil, + didChangeConfiguration: DidChangeConfigurationClientCapabilities(dynamicRegistration: true), + // TODO: NEED TO ADD https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workspace_didChangeWatchedFiles `relativePatternSupport` VARIABLE + didChangeWatchedFiles: DidChangeWatchedFilesClientCapabilities(dynamicRegistration: true), + symbol: WorkspaceSymbolClientCapabilities(dynamicRegistration: true, symbolKind: nil, tagSupport: nil, resolveSupport: []), + executeCommand: nil, + workspaceFolders: true, + configuration: true, + semanticTokens: nil, + codeLens: nil, + fileOperations: fileOperations + ) + + // All Client Capabilities + let capabilities = ClientCapabilities( + workspace: workspaceCapabilities, + textDocument: textDocumentCapabilities, + window: nil, + general: nil, + experimental: nil + ) + return InitializeParams( + processId: nil, + locale: nil, + rootPath: nil, + rootUri: projectURL.absoluteString, + initializationOptions: [], + capabilities: capabilities, + trace: nil, + workspaceFolders: nil + ) + } + return provider + } + + public func initialize() async throws { + // TODO: CATCH ERROR HERE, LOG ERROR OR SUCCESS + // InitializationResponse is not returned because it is automatically stored inside `lspInstance` + _ = try await lspInstance.initializeIfNeeded() + } + + public func shutdown() async throws { + try await lspInstance.shutdownAndExit() + } +} + +/// Represents a language server binary. +struct LanguageServerBinary { + /// The path to the language server binary. + let execPath: String + /// The arguments to pass to the language server binary. + let args: [String] + /// The environment variables to pass to the language server binary. + let env: [String: String]? +} From 8efba409d3f42d9ff5d97db1e4c7ec8ee85eb1fe Mon Sep 17 00:00:00 2001 From: Abe M Date: Wed, 14 Feb 2024 14:45:54 -0800 Subject: [PATCH 03/20] Adding LSP features --- CodeEdit.xcodeproj/project.pbxproj | 114 +++++++++- CodeEdit/Features/About/Views/AboutView.swift | 17 +- .../Documents/WorkspaceDocument.swift | 15 +- CodeEdit/Features/Editor/Models/Editor.swift | 21 +- .../Editor/Models/EditorManager.swift | 4 +- CodeEdit/Features/LSP/LSPCache.swift | 2 +- CodeEdit/Features/LSP/LSPUtil.swift | 61 +++++ .../LSP/LanguageClient+CallHierarchy.swift | 75 +++++++ .../LSP/LanguageClient+CodeLens.swift | 19 ++ .../LanguageClient+ColorPresentation.swift | 28 +++ .../LSP/LanguageClient+Completion.swift | 23 ++ .../LSP/LanguageClient+Declaration.swift | 25 +++ .../LSP/LanguageClient+Definition.swift | 32 +++ .../LSP/LanguageClient+Diagnostics.swift | 15 ++ .../LSP/LanguageClient+DocumentColor.swift | 29 +++ .../LanguageClient+DocumentHighlight.swift | 29 +++ .../LSP/LanguageClient+DocumentLink.swift | 31 +++ .../LSP/LanguageClient+DocumentSymbol.swift | 25 +++ .../LSP/LanguageClient+DocumentUtil.swift | 161 ++++++++++++++ .../LSP/LanguageClient+FoldingRange.swift | 22 ++ .../LSP/LanguageClient+Formatting.swift | 61 +++++ .../Features/LSP/LanguageClient+Hover.swift | 26 +++ .../LSP/LanguageClient+Implementation.swift | 25 +++ .../LSP/LanguageClient+InlayHint.swift | 39 ++++ .../LSP/LanguageClient+References.swift | 26 +++ .../Features/LSP/LanguageClient+Rename.swift | 40 ++++ .../LSP/LanguageClient+SelectionRange.swift | 26 +++ .../LSP/LanguageClient+SemanticTokens.swift | 44 ++++ .../LSP/LanguageClient+SignatureHelp.swift | 25 +++ .../LSP/LanguageClient+TypeDefinition.swift | 25 +++ .../Features/LSP/LanguageConfiguration.swift | 25 +++ CodeEdit/Features/LSP/LanguageServer.swift | 9 +- .../Features/LSP/LanguageServerManager.swift | 210 ++++++++++++++++++ .../ProjectNavigatorViewController.swift | 11 +- .../SourceControlNavigatorChangesList.swift | 6 +- .../WindowCommands/MainCommands.swift | 3 +- 36 files changed, 1319 insertions(+), 30 deletions(-) create mode 100644 CodeEdit/Features/LSP/LSPUtil.swift create mode 100644 CodeEdit/Features/LSP/LanguageClient+CallHierarchy.swift create mode 100644 CodeEdit/Features/LSP/LanguageClient+CodeLens.swift create mode 100644 CodeEdit/Features/LSP/LanguageClient+ColorPresentation.swift create mode 100644 CodeEdit/Features/LSP/LanguageClient+Completion.swift create mode 100644 CodeEdit/Features/LSP/LanguageClient+Declaration.swift create mode 100644 CodeEdit/Features/LSP/LanguageClient+Definition.swift create mode 100644 CodeEdit/Features/LSP/LanguageClient+Diagnostics.swift create mode 100644 CodeEdit/Features/LSP/LanguageClient+DocumentColor.swift create mode 100644 CodeEdit/Features/LSP/LanguageClient+DocumentHighlight.swift create mode 100644 CodeEdit/Features/LSP/LanguageClient+DocumentLink.swift create mode 100644 CodeEdit/Features/LSP/LanguageClient+DocumentSymbol.swift create mode 100644 CodeEdit/Features/LSP/LanguageClient+DocumentUtil.swift create mode 100644 CodeEdit/Features/LSP/LanguageClient+FoldingRange.swift create mode 100644 CodeEdit/Features/LSP/LanguageClient+Formatting.swift create mode 100644 CodeEdit/Features/LSP/LanguageClient+Hover.swift create mode 100644 CodeEdit/Features/LSP/LanguageClient+Implementation.swift create mode 100644 CodeEdit/Features/LSP/LanguageClient+InlayHint.swift create mode 100644 CodeEdit/Features/LSP/LanguageClient+References.swift create mode 100644 CodeEdit/Features/LSP/LanguageClient+Rename.swift create mode 100644 CodeEdit/Features/LSP/LanguageClient+SelectionRange.swift create mode 100644 CodeEdit/Features/LSP/LanguageClient+SemanticTokens.swift create mode 100644 CodeEdit/Features/LSP/LanguageClient+SignatureHelp.swift create mode 100644 CodeEdit/Features/LSP/LanguageClient+TypeDefinition.swift create mode 100644 CodeEdit/Features/LSP/LanguageConfiguration.swift create mode 100644 CodeEdit/Features/LSP/LanguageServerManager.swift diff --git a/CodeEdit.xcodeproj/project.pbxproj b/CodeEdit.xcodeproj/project.pbxproj index b8a7c48c70..ca7ea01246 100644 --- a/CodeEdit.xcodeproj/project.pbxproj +++ b/CodeEdit.xcodeproj/project.pbxproj @@ -59,8 +59,34 @@ 2B7AC06B282452FB0082A5B8 /* Media.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2B7AC06A282452FB0082A5B8 /* Media.xcassets */; }; 2BE487EF28245162003F3F64 /* FinderSync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2BE487EE28245162003F3F64 /* FinderSync.swift */; }; 2BE487F428245162003F3F64 /* OpenWithCodeEdit.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 2BE487EC28245162003F3F64 /* OpenWithCodeEdit.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 3007CE302B7859F500700D41 /* LanguageClient in Frameworks */ = {isa = PBXBuildFile; productRef = 3007CE2F2B7859F500700D41 /* LanguageClient */; }; 3026F50F2AC006C80061227E /* InspectorAreaViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3026F50E2AC006C80061227E /* InspectorAreaViewModel.swift */; }; - 3039C8DD2B738D5A00C8B4F8 /* LanguageClient in Frameworks */ = {isa = PBXBuildFile; productRef = 3039C8DC2B738D5A00C8B4F8 /* LanguageClient */; }; + 3039C8E12B738E9600C8B4F8 /* LanguageServerManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3039C8E02B738E9600C8B4F8 /* LanguageServerManager.swift */; }; + 3039C8E42B738EB900C8B4F8 /* LanguageClient+TypeDefinition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3039C8E32B738EB900C8B4F8 /* LanguageClient+TypeDefinition.swift */; }; + 3039C8E62B738EF600C8B4F8 /* LanguageClient+SignatureHelp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3039C8E52B738EF600C8B4F8 /* LanguageClient+SignatureHelp.swift */; }; + 3039C8E82B738F2800C8B4F8 /* LanguageClient+SemanticTokens.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3039C8E72B738F2800C8B4F8 /* LanguageClient+SemanticTokens.swift */; }; + 3039C8EA2B738F4E00C8B4F8 /* LanguageClient+SelectionRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3039C8E92B738F4E00C8B4F8 /* LanguageClient+SelectionRange.swift */; }; + 3039C8EC2B738F6600C8B4F8 /* LanguageClient+Rename.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3039C8EB2B738F6600C8B4F8 /* LanguageClient+Rename.swift */; }; + 3039C8EE2B738F9100C8B4F8 /* LanguageClient+References.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3039C8ED2B738F9100C8B4F8 /* LanguageClient+References.swift */; }; + 3039C8F02B738FAB00C8B4F8 /* LanguageClient+InlayHint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3039C8EF2B738FAB00C8B4F8 /* LanguageClient+InlayHint.swift */; }; + 3039C8F22B738FC700C8B4F8 /* LanguageClient+Implementation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3039C8F12B738FC700C8B4F8 /* LanguageClient+Implementation.swift */; }; + 3039C8F42B738FE500C8B4F8 /* LanguageClient+Hover.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3039C8F32B738FE500C8B4F8 /* LanguageClient+Hover.swift */; }; + 3039C8F62B738FF700C8B4F8 /* LanguageClient+Formatting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3039C8F52B738FF700C8B4F8 /* LanguageClient+Formatting.swift */; }; + 3039C8F82B73900A00C8B4F8 /* LanguageClient+FoldingRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3039C8F72B73900A00C8B4F8 /* LanguageClient+FoldingRange.swift */; }; + 3039C8FA2B73901E00C8B4F8 /* LanguageClient+DocumentUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3039C8F92B73901E00C8B4F8 /* LanguageClient+DocumentUtil.swift */; }; + 3039C8FC2B73904100C8B4F8 /* LanguageClient+DocumentSymbol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3039C8FB2B73904100C8B4F8 /* LanguageClient+DocumentSymbol.swift */; }; + 3039C8FE2B73905800C8B4F8 /* LanguageClient+DocumentLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3039C8FD2B73905800C8B4F8 /* LanguageClient+DocumentLink.swift */; }; + 3039C9002B73907500C8B4F8 /* LanguageClient+DocumentHighlight.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3039C8FF2B73907500C8B4F8 /* LanguageClient+DocumentHighlight.swift */; }; + 3039C9022B73908800C8B4F8 /* LanguageClient+DocumentColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3039C9012B73908800C8B4F8 /* LanguageClient+DocumentColor.swift */; }; + 3039C9042B73909B00C8B4F8 /* LanguageClient+Diagnostics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3039C9032B73909B00C8B4F8 /* LanguageClient+Diagnostics.swift */; }; + 3039C9062B7390AA00C8B4F8 /* LanguageClient+Definition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3039C9052B7390AA00C8B4F8 /* LanguageClient+Definition.swift */; }; + 3039C9082B7390C000C8B4F8 /* LanguageClient+Declaration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3039C9072B7390C000C8B4F8 /* LanguageClient+Declaration.swift */; }; + 3039C90A2B7390D200C8B4F8 /* LanguageClient+Completion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3039C9092B7390D200C8B4F8 /* LanguageClient+Completion.swift */; }; + 3039C90C2B73910300C8B4F8 /* LanguageClient+ColorPresentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3039C90B2B73910300C8B4F8 /* LanguageClient+ColorPresentation.swift */; }; + 3039C90E2B73911D00C8B4F8 /* LanguageClient+CodeLens.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3039C90D2B73911D00C8B4F8 /* LanguageClient+CodeLens.swift */; }; + 3039C9102B73912F00C8B4F8 /* LanguageClient+CallHierarchy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3039C90F2B73912F00C8B4F8 /* LanguageClient+CallHierarchy.swift */; }; + 3039C9172B7850B900C8B4F8 /* LanguageConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3039C9162B7850B900C8B4F8 /* LanguageConfiguration.swift */; }; + 3039C91A2B78588A00C8B4F8 /* LSPUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3039C9192B78588A00C8B4F8 /* LSPUtil.swift */; }; 305811812B73832B0049C9AA /* LanguageServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 305811802B73832B0049C9AA /* LanguageServer.swift */; }; 305811832B73834F0049C9AA /* LSPCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 305811822B73834F0049C9AA /* LSPCache.swift */; }; 30E6D0012A6E505200A58B20 /* NavigatorSidebarViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30E6D0002A6E505200A58B20 /* NavigatorSidebarViewModel.swift */; }; @@ -622,6 +648,32 @@ 2BE487EE28245162003F3F64 /* FinderSync.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FinderSync.swift; sourceTree = ""; }; 2BE487F028245162003F3F64 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 3026F50E2AC006C80061227E /* InspectorAreaViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InspectorAreaViewModel.swift; sourceTree = ""; }; + 3039C8E02B738E9600C8B4F8 /* LanguageServerManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LanguageServerManager.swift; sourceTree = ""; }; + 3039C8E32B738EB900C8B4F8 /* LanguageClient+TypeDefinition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LanguageClient+TypeDefinition.swift"; sourceTree = ""; }; + 3039C8E52B738EF600C8B4F8 /* LanguageClient+SignatureHelp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LanguageClient+SignatureHelp.swift"; sourceTree = ""; }; + 3039C8E72B738F2800C8B4F8 /* LanguageClient+SemanticTokens.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LanguageClient+SemanticTokens.swift"; sourceTree = ""; }; + 3039C8E92B738F4E00C8B4F8 /* LanguageClient+SelectionRange.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LanguageClient+SelectionRange.swift"; sourceTree = ""; }; + 3039C8EB2B738F6600C8B4F8 /* LanguageClient+Rename.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LanguageClient+Rename.swift"; sourceTree = ""; }; + 3039C8ED2B738F9100C8B4F8 /* LanguageClient+References.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LanguageClient+References.swift"; sourceTree = ""; }; + 3039C8EF2B738FAB00C8B4F8 /* LanguageClient+InlayHint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LanguageClient+InlayHint.swift"; sourceTree = ""; }; + 3039C8F12B738FC700C8B4F8 /* LanguageClient+Implementation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LanguageClient+Implementation.swift"; sourceTree = ""; }; + 3039C8F32B738FE500C8B4F8 /* LanguageClient+Hover.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LanguageClient+Hover.swift"; sourceTree = ""; }; + 3039C8F52B738FF700C8B4F8 /* LanguageClient+Formatting.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LanguageClient+Formatting.swift"; sourceTree = ""; }; + 3039C8F72B73900A00C8B4F8 /* LanguageClient+FoldingRange.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LanguageClient+FoldingRange.swift"; sourceTree = ""; }; + 3039C8F92B73901E00C8B4F8 /* LanguageClient+DocumentUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LanguageClient+DocumentUtil.swift"; sourceTree = ""; }; + 3039C8FB2B73904100C8B4F8 /* LanguageClient+DocumentSymbol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LanguageClient+DocumentSymbol.swift"; sourceTree = ""; }; + 3039C8FD2B73905800C8B4F8 /* LanguageClient+DocumentLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LanguageClient+DocumentLink.swift"; sourceTree = ""; }; + 3039C8FF2B73907500C8B4F8 /* LanguageClient+DocumentHighlight.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LanguageClient+DocumentHighlight.swift"; sourceTree = ""; }; + 3039C9012B73908800C8B4F8 /* LanguageClient+DocumentColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LanguageClient+DocumentColor.swift"; sourceTree = ""; }; + 3039C9032B73909B00C8B4F8 /* LanguageClient+Diagnostics.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LanguageClient+Diagnostics.swift"; sourceTree = ""; }; + 3039C9052B7390AA00C8B4F8 /* LanguageClient+Definition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LanguageClient+Definition.swift"; sourceTree = ""; }; + 3039C9072B7390C000C8B4F8 /* LanguageClient+Declaration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LanguageClient+Declaration.swift"; sourceTree = ""; }; + 3039C9092B7390D200C8B4F8 /* LanguageClient+Completion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LanguageClient+Completion.swift"; sourceTree = ""; }; + 3039C90B2B73910300C8B4F8 /* LanguageClient+ColorPresentation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LanguageClient+ColorPresentation.swift"; sourceTree = ""; }; + 3039C90D2B73911D00C8B4F8 /* LanguageClient+CodeLens.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LanguageClient+CodeLens.swift"; sourceTree = ""; }; + 3039C90F2B73912F00C8B4F8 /* LanguageClient+CallHierarchy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LanguageClient+CallHierarchy.swift"; sourceTree = ""; }; + 3039C9162B7850B900C8B4F8 /* LanguageConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LanguageConfiguration.swift; sourceTree = ""; }; + 3039C9192B78588A00C8B4F8 /* LSPUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LSPUtil.swift; sourceTree = ""; }; 305811802B73832B0049C9AA /* LanguageServer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LanguageServer.swift; sourceTree = ""; }; 305811822B73834F0049C9AA /* LSPCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LSPCache.swift; sourceTree = ""; }; 30E6D0002A6E505200A58B20 /* NavigatorSidebarViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigatorSidebarViewModel.swift; sourceTree = ""; }; @@ -1070,6 +1122,7 @@ files = ( 6C5BE5222A3D5666002DA0FC /* WindowManagement in Frameworks */, 6C66C31329D05CDC00DE9ED2 /* GRDB in Frameworks */, + 3007CE302B7859F500700D41 /* LanguageClient in Frameworks */, 58F2EB1E292FB954004A9BDE /* Sparkle in Frameworks */, 6C2149412A1BB9AB00748382 /* LogStream in Frameworks */, 6C147C4529A329350089B630 /* OrderedCollections in Frameworks */, @@ -1079,7 +1132,6 @@ 6CDEFC9629E22C2700B7C684 /* Introspect in Frameworks */, 2816F594280CF50500DD548B /* CodeEditSymbols in Frameworks */, 6C6BD6F829CD14D100235D17 /* CodeEditKit in Frameworks */, - 3039C8DD2B738D5A00C8B4F8 /* LanguageClient in Frameworks */, 6C81916B29B41DD300B75C92 /* DequeModule in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1321,8 +1373,34 @@ 3058117F2B7383090049C9AA /* LSP */ = { isa = PBXGroup; children = ( - 305811802B73832B0049C9AA /* LanguageServer.swift */, 305811822B73834F0049C9AA /* LSPCache.swift */, + 3039C9162B7850B900C8B4F8 /* LanguageConfiguration.swift */, + 305811802B73832B0049C9AA /* LanguageServer.swift */, + 3039C8E02B738E9600C8B4F8 /* LanguageServerManager.swift */, + 3039C90F2B73912F00C8B4F8 /* LanguageClient+CallHierarchy.swift */, + 3039C90D2B73911D00C8B4F8 /* LanguageClient+CodeLens.swift */, + 3039C90B2B73910300C8B4F8 /* LanguageClient+ColorPresentation.swift */, + 3039C9092B7390D200C8B4F8 /* LanguageClient+Completion.swift */, + 3039C9072B7390C000C8B4F8 /* LanguageClient+Declaration.swift */, + 3039C9052B7390AA00C8B4F8 /* LanguageClient+Definition.swift */, + 3039C9032B73909B00C8B4F8 /* LanguageClient+Diagnostics.swift */, + 3039C9012B73908800C8B4F8 /* LanguageClient+DocumentColor.swift */, + 3039C8FF2B73907500C8B4F8 /* LanguageClient+DocumentHighlight.swift */, + 3039C8FD2B73905800C8B4F8 /* LanguageClient+DocumentLink.swift */, + 3039C8FB2B73904100C8B4F8 /* LanguageClient+DocumentSymbol.swift */, + 3039C8F92B73901E00C8B4F8 /* LanguageClient+DocumentUtil.swift */, + 3039C8F72B73900A00C8B4F8 /* LanguageClient+FoldingRange.swift */, + 3039C8F52B738FF700C8B4F8 /* LanguageClient+Formatting.swift */, + 3039C8F32B738FE500C8B4F8 /* LanguageClient+Hover.swift */, + 3039C8F12B738FC700C8B4F8 /* LanguageClient+Implementation.swift */, + 3039C8EF2B738FAB00C8B4F8 /* LanguageClient+InlayHint.swift */, + 3039C8ED2B738F9100C8B4F8 /* LanguageClient+References.swift */, + 3039C8EB2B738F6600C8B4F8 /* LanguageClient+Rename.swift */, + 3039C8E92B738F4E00C8B4F8 /* LanguageClient+SelectionRange.swift */, + 3039C8E72B738F2800C8B4F8 /* LanguageClient+SemanticTokens.swift */, + 3039C8E52B738EF600C8B4F8 /* LanguageClient+SignatureHelp.swift */, + 3039C8E32B738EB900C8B4F8 /* LanguageClient+TypeDefinition.swift */, + 3039C9192B78588A00C8B4F8 /* LSPUtil.swift */, ); path = LSP; sourceTree = ""; @@ -3044,7 +3122,7 @@ 6CDEFC9529E22C2700B7C684 /* Introspect */, 6C5BE5212A3D5666002DA0FC /* WindowManagement */, 6CE952E22B29433500C29C31 /* CodeEditSourceEditor */, - 3039C8DC2B738D5A00C8B4F8 /* LanguageClient */, + 3007CE2F2B7859F500700D41 /* LanguageClient */, ); productName = CodeEdit; productReference = B658FB2C27DA9E0F00EA4DBD /* CodeEdit.app */; @@ -3305,7 +3383,9 @@ 587B9E9229301D8F00AC7927 /* BitBucketAccount.swift in Sources */, DE513F52281B672D002260B9 /* EditorTabBarAccessory.swift in Sources */, 2813F93927ECC4C300E305E4 /* NavigatorAreaView.swift in Sources */, + 3039C8F22B738FC700C8B4F8 /* LanguageClient+Implementation.swift in Sources */, 5B698A0F2B2636A700DE9392 /* SearchSettingsIgnoreGlobPatternItemView.swift in Sources */, + 3039C90C2B73910300C8B4F8 /* LanguageClient+ColorPresentation.swift in Sources */, 587B9E8A29301D8F00AC7927 /* GitHubIssue.swift in Sources */, EC0870F72A455F6400EB8692 /* ProjectNavigatorViewController+NSMenuDelegate.swift in Sources */, B60718202B0C6CE7009CDAB4 /* GitStashEntry.swift in Sources */, @@ -3314,10 +3394,12 @@ 6C82D6C629C012AD00495C54 /* NSApp+openWindow.swift in Sources */, 6C14CEB028777D3C001468FE /* FindNavigatorListViewController.swift in Sources */, 587B9E7F29301D8F00AC7927 /* GitHubUserRouter.swift in Sources */, + 3039C90E2B73911D00C8B4F8 /* LanguageClient+CodeLens.swift in Sources */, B62AEDBC2A210DBB009A9F52 /* UtilityAreaTerminalTab.swift in Sources */, B67DB0F62AFC2A7A002DC647 /* FindNavigatorToolbarBottom.swift in Sources */, 04BA7C142AE2AA7300584E1C /* GitCloneViewModel.swift in Sources */, B61A606129F188AB009B43F9 /* ExternalLink.swift in Sources */, + 3039C9102B73912F00C8B4F8 /* LanguageClient+CallHierarchy.swift in Sources */, 587B9E9729301D8F00AC7927 /* BitBucketAccount+Token.swift in Sources */, 587B9E7729301D8F00AC7927 /* String+PercentEncoding.swift in Sources */, 587B9E5B29301D8F00AC7927 /* GitCheckoutBranchView.swift in Sources */, @@ -3330,6 +3412,7 @@ 58F2EB08292FB2B0004A9BDE /* TextEditingSettings.swift in Sources */, 201169DB2837B34000F92B46 /* SourceControlNavigatorChangedFileView.swift in Sources */, 5882252E292C280D00E83CDE /* StatusBarMaximizeButton.swift in Sources */, + 3039C91A2B78588A00C8B4F8 /* LSPUtil.swift in Sources */, 6C4104E9297C970F00F472BA /* AboutDefaultView.swift in Sources */, 587B9E6F29301D8F00AC7927 /* GitLabProjectAccess.swift in Sources */, 587B9E6929301D8F00AC7927 /* GitLabEvent.swift in Sources */, @@ -3352,6 +3435,7 @@ 58F2EB03292FB2B0004A9BDE /* Documentation.docc in Sources */, 611192042B08CCED00D4459B /* SearchIndexer+ProgressiveSearch.swift in Sources */, 611192022B08CCDC00D4459B /* SearchIndexer+Search.swift in Sources */, + 3039C8E42B738EB900C8B4F8 /* LanguageClient+TypeDefinition.swift in Sources */, 04BA7C272AE2E9F100584E1C /* GitClient+Push.swift in Sources */, 2B7A583527E4BA0100D25D4E /* AppDelegate.swift in Sources */, D7012EE827E757850001E1EF /* FindNavigatorView.swift in Sources */, @@ -3366,6 +3450,7 @@ 587B9E6829301D8F00AC7927 /* GitLabAccountModel.swift in Sources */, 5878DAA7291AE76700DD95A3 /* QuickOpenViewModel.swift in Sources */, 6CFF967429BEBCC300182D6F /* FindCommands.swift in Sources */, + 3039C8F42B738FE500C8B4F8 /* LanguageClient+Hover.swift in Sources */, 587B9E6529301D8F00AC7927 /* GitLabGroupAccess.swift in Sources */, 6C91D57229B176FF0059A90D /* EditorManager.swift in Sources */, 6C82D6BC29C00CD900495C54 /* FirstResponderPropertyWrapper.swift in Sources */, @@ -3384,6 +3469,7 @@ 201169DD2837B3AC00F92B46 /* SourceControlNavigatorToolbarBottom.swift in Sources */, 587B9E8B29301D8F00AC7927 /* GitHubAccount+deleteReference.swift in Sources */, 58798237292E30B90085B254 /* FeedbackView.swift in Sources */, + 3039C9042B73909B00C8B4F8 /* LanguageClient+Diagnostics.swift in Sources */, 587B9E9829301D8F00AC7927 /* GitCommit.swift in Sources */, 6C5228B529A868BD00AC48F6 /* Environment+ContentInsets.swift in Sources */, 587B9E9429301D8F00AC7927 /* BitBucketTokenConfiguration.swift in Sources */, @@ -3392,7 +3478,9 @@ 58A5DFA329339F6400D1BD5D /* CommandManager.swift in Sources */, 58798284292ED0FB0085B254 /* TerminalEmulatorView.swift in Sources */, B6C4F2AC2B3CC4D000B2B140 /* CommitChangedFileListItemView.swift in Sources */, + 3039C8EE2B738F9100C8B4F8 /* LanguageClient+References.swift in Sources */, 6C82D6B329BFD88700495C54 /* NavigateCommands.swift in Sources */, + 3039C8E12B738E9600C8B4F8 /* LanguageServerManager.swift in Sources */, B66A4E4C29C9179B004573B4 /* CodeEditApp.swift in Sources */, 4E7F066629602E7B00BB3C12 /* CodeEditSplitViewController.swift in Sources */, 587B9E8D29301D8F00AC7927 /* GitHubAccount.swift in Sources */, @@ -3401,8 +3489,10 @@ 6C7F37FE2A3EA6FA00217B83 /* View+focusedValue.swift in Sources */, B6C4F2A12B3CA37500B2B140 /* SourceControlNavigatorHistoryView.swift in Sources */, B6C6A43029771F7100A3D28F /* EditorTabBackground.swift in Sources */, + 3039C8EA2B738F4E00C8B4F8 /* LanguageClient+SelectionRange.swift in Sources */, B60718372B170638009CDAB4 /* SourceControlNavigatorRenameBranchView.swift in Sources */, 6C578D8129CD294800DC73B2 /* ExtensionActivatorView.swift in Sources */, + 3039C90A2B7390D200C8B4F8 /* LanguageClient+Completion.swift in Sources */, B6F0517D29D9E4B100D72287 /* TerminalSettingsView.swift in Sources */, 587B9E8C29301D8F00AC7927 /* GitHubOpenness.swift in Sources */, 5894E59729FEF7740077E59C /* CEWorkspaceFile+Recursion.swift in Sources */, @@ -3423,6 +3513,7 @@ 85E4122A2A46C8CA00183F2B /* LocationsSettings.swift in Sources */, 613899B12B6E6FDC00A5CAF6 /* Collection+FuzzySearch.swift in Sources */, 581550D129FBD30400684881 /* TextTableViewCell.swift in Sources */, + 3039C8F82B73900A00C8B4F8 /* LanguageClient+FoldingRange.swift in Sources */, 587B9E6629301D8F00AC7927 /* GitLabProjectHook.swift in Sources */, 587B9E9329301D8F00AC7927 /* BitBucketOAuthConfiguration.swift in Sources */, 6C18620A298BF5A800C663EA /* RecentProjectsListView.swift in Sources */, @@ -3483,6 +3574,7 @@ D7211D4327E066CE008F2ED7 /* Localized+Ex.swift in Sources */, 305811832B73834F0049C9AA /* LSPCache.swift in Sources */, 581BFB692926431000D251EC /* WelcomeActionView.swift in Sources */, + 3039C8FC2B73904100C8B4F8 /* LanguageClient+DocumentSymbol.swift in Sources */, 20D839AE280E0CA700B27357 /* HistoryPopoverView.swift in Sources */, B6E41C7029DD157F0088F9F4 /* AccountsSettingsView.swift in Sources */, 6CFF967A29BEBD2400182D6F /* ViewCommands.swift in Sources */, @@ -3508,8 +3600,10 @@ B62AEDD42A27B29F009A9F52 /* PaneToolbar.swift in Sources */, D7E201B227E8D50000CB86D0 /* FindNavigatorForm.swift in Sources */, 287776E927E34BC700D46668 /* EditorTabBarView.swift in Sources */, + 3039C8FA2B73901E00C8B4F8 /* LanguageClient+DocumentUtil.swift in Sources */, B60BE8BD297A167600841125 /* AcknowledgementRowView.swift in Sources */, B6F0517029D9E36800D72287 /* LocationsSettingsView.swift in Sources */, + 3039C9002B73907500C8B4F8 /* LanguageClient+DocumentHighlight.swift in Sources */, B62AEDDC2A27C1B3009A9F52 /* OSLogType+Color.swift in Sources */, 587B9E6329301D8F00AC7927 /* GitLabAccount.swift in Sources */, 6C1CC99B2B1E7CBC0002349B /* FindNavigatorIndexBar.swift in Sources */, @@ -3525,6 +3619,9 @@ B6C6A42A297716A500A3D28F /* EditorTabCloseButton.swift in Sources */, B60718422B17DB93009CDAB4 /* SourceControlNavigatorRepositoryView+outlineGroupData.swift in Sources */, 58A5DF7D2931787A00D1BD5D /* ShellClient.swift in Sources */, + 3039C8E82B738F2800C8B4F8 /* LanguageClient+SemanticTokens.swift in Sources */, + 3039C8F62B738FF700C8B4F8 /* LanguageClient+Formatting.swift in Sources */, + 3039C8EC2B738F6600C8B4F8 /* LanguageClient+Rename.swift in Sources */, 5879821A292D92370085B254 /* SearchResultModel.swift in Sources */, B6F0517729D9E3AD00D72287 /* SourceControlGeneralView.swift in Sources */, 587B9E8929301D8F00AC7927 /* GitHubGist.swift in Sources */, @@ -3547,6 +3644,7 @@ 581BFB682926431000D251EC /* WelcomeView.swift in Sources */, 6CFF967829BEBCF600182D6F /* MainCommands.swift in Sources */, 587B9E7129301D8F00AC7927 /* GitURLSession.swift in Sources */, + 3039C8E62B738EF600C8B4F8 /* LanguageClient+SignatureHelp.swift in Sources */, 610C0FDA2B44438F00A01CA7 /* WorkspaceDocument+FindAndReplace.swift in Sources */, 5882252C292C280D00E83CDE /* UtilityAreaView.swift in Sources */, 2847019E27FDDF7600F87B6B /* ProjectNavigatorOutlineView.swift in Sources */, @@ -3564,6 +3662,7 @@ 286471AB27ED51FD0039369D /* ProjectNavigatorView.swift in Sources */, B6E41C7C29DE2B110088F9F4 /* AccountsSettingsProviderRow.swift in Sources */, B62AEDB52A1FE295009A9F52 /* UtilityAreaDebugView.swift in Sources */, + 3039C9062B7390AA00C8B4F8 /* LanguageClient+Definition.swift in Sources */, 6C049A372A49E2DB00D42923 /* DirectoryEventStream.swift in Sources */, 04BA7C0E2AE2A76E00584E1C /* SourceControlNavigatorChangesCommitView.swift in Sources */, 615AA21A2B0CFD480013FCCC /* LazyStringLoader.swift in Sources */, @@ -3581,6 +3680,7 @@ 58F2EB05292FB2B0004A9BDE /* Settings.swift in Sources */, 6CBD1BC62978DE53006639D5 /* Font+Caption3.swift in Sources */, 30E6D0012A6E505200A58B20 /* NavigatorSidebarViewModel.swift in Sources */, + 3039C8FE2B73905800C8B4F8 /* LanguageClient+DocumentLink.swift in Sources */, B6E41C9429DEAE260088F9F4 /* SourceControlAccount.swift in Sources */, 2806E9022979588B000040F4 /* Contributor.swift in Sources */, 58D01C98293167DC00C5B6B4 /* String+RemoveOccurrences.swift in Sources */, @@ -3624,11 +3724,13 @@ B6EA1FF829DB78DB001BF195 /* ThemeSettingThemeRow.swift in Sources */, 587B9E7629301D8F00AC7927 /* GitTime.swift in Sources */, 587B9E5D29301D8F00AC7927 /* GitLabUserRouter.swift in Sources */, + 3039C9022B73908800C8B4F8 /* LanguageClient+DocumentColor.swift in Sources */, 588847692992ABCA00996D95 /* Array+SortURLs.swift in Sources */, 58822530292C280D00E83CDE /* FilterTextField.swift in Sources */, 6C82D6B929BFE34900495C54 /* HelpCommands.swift in Sources */, 6C147C4929A32A080089B630 /* EditorLayoutView.swift in Sources */, 6C147C4129A328BF0089B630 /* EditorLayout.swift in Sources */, + 3039C8F02B738FAB00C8B4F8 /* LanguageClient+InlayHint.swift in Sources */, B6D7EA592971078500301FAC /* InspectorSection.swift in Sources */, B6AB09A32AAABFEC0003A3A6 /* EditorTabBarLeadingAccessories.swift in Sources */, B69BFDC72B0686910050D9A6 /* GitClient+Initiate.swift in Sources */, @@ -3636,6 +3738,7 @@ 85745D632A38F8D900089AAB /* String+HighlightOccurrences.swift in Sources */, B6EE989027E8879A00CDD8AB /* InspectorAreaView.swift in Sources */, 587B9DA229300ABD00AC7927 /* EffectView.swift in Sources */, + 3039C9172B7850B900C8B4F8 /* LanguageConfiguration.swift in Sources */, 6C97EBCC2978760400302F95 /* AcknowledgementsWindowController.swift in Sources */, 284DC84F2978B7B400BF2770 /* ContributorsView.swift in Sources */, B62AEDC92A2704F3009A9F52 /* UtilityAreaTabView.swift in Sources */, @@ -3696,6 +3799,7 @@ B6AB09A12AAABAAE0003A3A6 /* EditorTabs.swift in Sources */, 04C3255B2801F86400C8DA2D /* ProjectNavigatorViewController.swift in Sources */, 587B9E6029301D8F00AC7927 /* GitLabOAuthRouter.swift in Sources */, + 3039C9082B7390C000C8B4F8 /* LanguageClient+Declaration.swift in Sources */, B6AB09B32AB919CF0003A3A6 /* View+actionBar.swift in Sources */, 6C05A8AF284D0CA3007F4EAA /* WorkspaceDocument+Listeners.swift in Sources */, 588847632992A2A200996D95 /* CEWorkspaceFile.swift in Sources */, @@ -4716,7 +4820,7 @@ package = 2816F592280CF50500DD548B /* XCRemoteSwiftPackageReference "CodeEditSymbols" */; productName = CodeEditSymbols; }; - 3039C8DC2B738D5A00C8B4F8 /* LanguageClient */ = { + 3007CE2F2B7859F500700D41 /* LanguageClient */ = { isa = XCSwiftPackageProductDependency; package = 30E1AAB12B73856500420274 /* XCLocalSwiftPackageReference "../LanguageClient" */; productName = LanguageClient; diff --git a/CodeEdit/Features/About/Views/AboutView.swift b/CodeEdit/Features/About/Views/AboutView.swift index 900177edb9..7e9643a15b 100644 --- a/CodeEdit/Features/About/Views/AboutView.swift +++ b/CodeEdit/Features/About/Views/AboutView.swift @@ -44,13 +44,16 @@ public struct AboutView: View { // if anyone knows of a better way to do this feel free to refactor .background(.regularMaterial.opacity(0)) .background(EffectView(.popover, blendingMode: .behindWindow).ignoresSafeArea()) - .background { - Button("") { - dismiss() - } - .keyboardShortcut(.escape, modifiers: []) - .hidden() - } +// .background { +// Button("") { +// dismiss() +// } +// .keyboardShortcut(.escape, modifiers: []) +// .hidden() +// } + .onExitCommand(perform: { + dismiss() + }) .task { if let window = NSApp.findWindow(.about) { window.styleMask = [.closable, .fullSizeContentView, .titled, .nonactivatingPanel] diff --git a/CodeEdit/Features/Documents/WorkspaceDocument.swift b/CodeEdit/Features/Documents/WorkspaceDocument.swift index ab419b93ee..3cb3fb12f1 100644 --- a/CodeEdit/Features/Documents/WorkspaceDocument.swift +++ b/CodeEdit/Features/Documents/WorkspaceDocument.swift @@ -5,11 +5,12 @@ // Created by Pavel Kasila on 17.03.22. // -import Foundation import AppKit import SwiftUI import Combine +import Foundation import WindowManagement +import LanguageServerProtocol @objc(WorkspaceDocument) final class WorkspaceDocument: NSDocument, ObservableObject, NSToolbarDelegate { @@ -33,6 +34,7 @@ final class WorkspaceDocument: NSDocument, ObservableObject, NSToolbarDelegate { var utilityAreaModel = UtilityAreaViewModel() var searchState: SearchState? + var lspManager: LanguageServerManager? var quickOpenViewModel: QuickOpenViewModel? var commandsPaletteState: CommandPaletteViewModel? var listenerModel: WorkspaceNotificationModel = .init() @@ -115,6 +117,17 @@ final class WorkspaceDocument: NSDocument, ObservableObject, NSToolbarDelegate { workspaceURL: url, editorManager: editorManager ) + self.lspManager = LanguageServerManager() + + // TODO: ACTIVATION EVENTS HERE + Task { + try await self.lspManager?.startServer( + for: .python, + projectURL: url, + workspaceFolders: [WorkspaceFolder(uri: url.absoluteString, name: "workspace_folder_name")] + ) + } + self.workspaceFileManager = .init( folderUrl: url, ignoredFilesAndFolders: Set(ignoredFilesAndDirectory), diff --git a/CodeEdit/Features/Editor/Models/Editor.swift b/CodeEdit/Features/Editor/Models/Editor.swift index 609f58061f..c4c68967f5 100644 --- a/CodeEdit/Features/Editor/Models/Editor.swift +++ b/CodeEdit/Features/Editor/Models/Editor.swift @@ -138,17 +138,21 @@ final class Editor: ObservableObject, Identifiable { /// - file: the file to open. /// - asTemporary: indicates whether the tab should be opened as a temporary tab or a permanent tab. func openTab(file: CEWorkspaceFile, asTemporary: Bool) { + print("Attempting to open file: \(file.url)") let item = EditorInstance(file: file) // Item is already opened in a tab. guard !tabs.contains(item) || !asTemporary else { selectedTab = item history.prepend(item) + print("File already opened!") return } switch (temporaryTab, asTemporary) { case (.some(let tab), true): + print("Temporary tab 1") if let index = tabs.firstIndex(of: tab) { + print("Going inside 1") history.prepend(item) tabs.remove(tab) tabs.insert(item, at: index) @@ -157,24 +161,21 @@ final class Editor: ObservableObject, Identifiable { } case (.some(let tab), false) where tab == item: + print("2") temporaryTab = nil case (.none, true): + print("3") openTab(file: item.file) temporaryTab = item case (.none, false): + print("4") openTab(file: item.file) default: break } -// TODO: IS THIS NEEDED? openFile ALREADY GETS CALLED INSIDE openTab -// do { -// try openFile(item: item) -// } catch { -// print(error) -// } } /// Opens a tab in the editor. @@ -184,11 +185,16 @@ final class Editor: ObservableObject, Identifiable { /// - fromHistory: Indicates whether the tab has been opened from going back in history. func openTab(file: CEWorkspaceFile, at index: Int? = nil, fromHistory: Bool = false) { let item = Tab(file: file) + print("Tabs before update: \(tabs)") if let index { tabs.insert(item, at: index) } else { tabs.append(item) } + + print("Updated tabs: \(tabs)") + print("New item: \(item.file.url)") + selectedTab = item if !fromHistory { history.removeFirst(historyOffset) @@ -198,12 +204,14 @@ final class Editor: ObservableObject, Identifiable { do { try openFile(item: item) } catch { + print("openFile error") print(error) } } private func openFile(item: Tab) throws { guard item.file.fileDocument == nil else { + print("File document is nil, returning!") return } @@ -216,6 +224,7 @@ final class Editor: ObservableObject, Identifiable { ) item.file.fileDocument = codeFile CodeEditDocumentController.shared.addDocument(codeFile) + print("Successfully opened file") } func goBackInHistory() { diff --git a/CodeEdit/Features/Editor/Models/EditorManager.swift b/CodeEdit/Features/Editor/Models/EditorManager.swift index 3ce1866e20..3a398b5a0b 100644 --- a/CodeEdit/Features/Editor/Models/EditorManager.swift +++ b/CodeEdit/Features/Editor/Models/EditorManager.swift @@ -30,8 +30,6 @@ class EditorManager: ObservableObject { /// History of last-used editors. var activeEditorHistory: Deque<() -> Editor?> = [] - var fileDocuments: [CEWorkspaceFile: CodeFileDocument] = [:] - /// notify listeners whenever tab selection changes on the active editor. var tabBarTabIdSubject = PassthroughSubject() var cancellable: AnyCancellable? @@ -74,7 +72,7 @@ class EditorManager: ObservableObject { /// - editor: The editor to add the tab to. If nil, it is added to the active tab group. func openTab(item: CEWorkspaceFile, in editor: Editor? = nil) { let editor = editor ?? activeEditor - editor.openTab(file: item) + editor.openTab(file: item, asTemporary: false) } /// bind active tap group to listen to file selection changes. diff --git a/CodeEdit/Features/LSP/LSPCache.swift b/CodeEdit/Features/LSP/LSPCache.swift index fac944bbca..f01ed6d803 100644 --- a/CodeEdit/Features/LSP/LSPCache.swift +++ b/CodeEdit/Features/LSP/LSPCache.swift @@ -78,7 +78,7 @@ class LSPCache { self.evictIfNeeded() } } - + private func evictIfNeeded() { evictionQueue.async(flags: .barrier) { while self.cacheEntriesOrder.count > self.cacheSizeLimit { diff --git a/CodeEdit/Features/LSP/LSPUtil.swift b/CodeEdit/Features/LSP/LSPUtil.swift new file mode 100644 index 0000000000..828a1535a6 --- /dev/null +++ b/CodeEdit/Features/LSP/LSPUtil.swift @@ -0,0 +1,61 @@ +// +// LSPUtil.swift +// CodeEdit +// +// Created by Abe Malla on 2/10/24. +// + +import Foundation +import LanguageServerProtocol + +/// Helper function to get the edits from a completion item +/// - Parameters: +/// - startPosition: The position where the completion was requested +/// - item: The completion item +/// - Returns: An array of TextEdit objects +func getCompletionItemEdits(startPosition: Position, item: CompletionItem) -> [TextEdit] { + var edits: [TextEdit] = [] + + // If a TextEdit or InsertReplaceEdit value was provided + if let edit = item.textEdit { + switch edit { + case .optionA(let textEdit): + edits.append(textEdit) + case .optionB(let insertReplaceEdit): + edits.append( + TextEdit(range: insertReplaceEdit.insert, newText: insertReplaceEdit.newText) + ) + edits.append( + TextEdit(range: insertReplaceEdit.replace, newText: insertReplaceEdit.newText) + ) + } + } + // If the `insertText` value was provided + else if let insertText = item.insertText { + // TODO: COMPUTE EDIT BY FINDING MATCHING TEXT, ALSO CHECK FOR TRIGGER CHARACTERS + edits.append( + TextEdit( + range: LSPRange(from: startPosition, offsetCharacter: insertText.count), + newText: insertText + ) + ) + } + // Fallback to the label + else if item.label != "" { + // TODO: COMPUTE EDIT BY FINDING MATCHING TEXT, ALSO CHECK FOR TRIGGER CHARACTERS + edits.append( + TextEdit( + range: LSPRange(from: startPosition, offsetCharacter: item.label.count), + newText: item.label + ) + ) + } + + // If additional edits were provided + // An example would be to also include an 'import' statement at the top of the file + if let additionalEdits = item.additionalTextEdits { + edits.append(contentsOf: additionalEdits) + } + + return edits +} diff --git a/CodeEdit/Features/LSP/LanguageClient+CallHierarchy.swift b/CodeEdit/Features/LSP/LanguageClient+CallHierarchy.swift new file mode 100644 index 0000000000..29bbb662a3 --- /dev/null +++ b/CodeEdit/Features/LSP/LanguageClient+CallHierarchy.swift @@ -0,0 +1,75 @@ +// +// LanguageClient+CallHierarchy.swift +// CodeEdit +// +// Created by Abe Malla on 2/7/24. +// + +import Foundation +import LanguageServerProtocol + +extension LanguageServer { + func requestPrepareCallHierarchy( + document documentURI: String, _ position: Position + ) async -> CallHierarchyPrepareResponse { + // TODO: SOMEHOW NEED TO INVALIDATE THIS. CURRENTLY STORING EVERYTHING IN callHierarchyItems VARIABLE +// let prepareParams = CallHierarchyPrepareParams( +// textDocument: TextDocumentIdentifier(uri: documentURI), +// position: position, +// workDoneToken: nil +// ) +// +// do { +// guard let items = try await server.prepareCallHierarchy(params: prepareParams) else { +// return [] +// } +// callHierarchyItems[documentURI] = items +// return items +// } catch { +// // TODO: LOGGING +// print("requestPrepareCallHierarchy: Error \(error)") +// } + + return [] + } + + func requestCallHierarchyIncomingCalls( + _ callHierarchyItem: CallHierarchyItem + ) async -> CallHierarchyIncomingCallsResponse { +// let incomingParams = CallHierarchyIncomingCallsParams( +// item: callHierarchyItem, +// workDoneToken: nil +// ) +// +// do { +// guard let incomingCalls = try await server.callHierarchyIncomingCalls(params: incomingParams) else { +// return [] +// } +// return incomingCalls +// } catch { +// // TODO: LOGGING +// print("requestCallHierarchyIncomingCalls: Error \(error)") +// } + return [] + } + + func requestCallHierarchyOutgoingCalls( + _ callHierarchyItem: CallHierarchyItem + ) async -> CallHierarchyOutgoingCallsResponse { + let outgoingParams = CallHierarchyOutgoingCallsParams( + item: callHierarchyItem, + workDoneToken: nil + ) + + do { + guard let outgoingCalls = try await lspInstance.callHierarchyOutgoingCalls(outgoingParams) else { + return [] + } + return outgoingCalls + } catch { + // TODO: LOGGING + print("requestCallHierarchyOutgoingCalls: Error \(error)") + } + return [] + } +} diff --git a/CodeEdit/Features/LSP/LanguageClient+CodeLens.swift b/CodeEdit/Features/LSP/LanguageClient+CodeLens.swift new file mode 100644 index 0000000000..e289200443 --- /dev/null +++ b/CodeEdit/Features/LSP/LanguageClient+CodeLens.swift @@ -0,0 +1,19 @@ +// +// LanguageClient+CodeLens.swift +// CodeEdit +// +// Created by Abe Malla on 2/7/24. +// + +import Foundation +import LanguageServerProtocol + +extension LanguageServer { +// func requestCodeLens() async -> CodeLensResponse { +// +// } +// +// func requestCodeLensResolve() async -> CodeLensResolveResponse { +// +// } +} diff --git a/CodeEdit/Features/LSP/LanguageClient+ColorPresentation.swift b/CodeEdit/Features/LSP/LanguageClient+ColorPresentation.swift new file mode 100644 index 0000000000..22e6434633 --- /dev/null +++ b/CodeEdit/Features/LSP/LanguageClient+ColorPresentation.swift @@ -0,0 +1,28 @@ +// +// LanguageClient+ColorPresentation.swift +// CodeEdit +// +// Created by Abe Malla on 2/7/24. +// + +import Foundation +import LanguageServerProtocol + +extension LanguageServer { + func requestColorPresentation(document documentURI: String, _ color: Color, _ range: LSPRange) async -> ColorPresentationResponse { + let params = ColorPresentationParams( + workDoneToken: nil, + partialResultToken: nil, + textDocument: TextDocumentIdentifier(uri: documentURI), + color: color, + range: range + ) + do { + return try await lspInstance.colorPresentation(params) + } catch { + // TODO: LOGGING + print("requestColorPresentation: Error \(error)") + } + return [] + } +} diff --git a/CodeEdit/Features/LSP/LanguageClient+Completion.swift b/CodeEdit/Features/LSP/LanguageClient+Completion.swift new file mode 100644 index 0000000000..214ad3b054 --- /dev/null +++ b/CodeEdit/Features/LSP/LanguageClient+Completion.swift @@ -0,0 +1,23 @@ +// +// LanguageClient+Completion.swift +// CodeEdit +// +// Created by Abe Malla on 2/7/24. +// + +import Foundation +import LanguageServerProtocol + +extension LanguageServer { + func requestCompletion(document documentURI: String, position: Position) async throws -> CompletionResponse { + let cacheKey = CacheKey(uri: documentURI, requestType: "completion") + if let cachedResponse: CompletionResponse = lspCache.get(key: cacheKey) { + return cachedResponse + } + let completionParams = CompletionParams(uri: documentURI, position: position, triggerKind: .invoked, triggerCharacter: nil) + let response = try await lspInstance.completion(completionParams) + + lspCache.set(key: cacheKey, value: response) + return response + } +} diff --git a/CodeEdit/Features/LSP/LanguageClient+Declaration.swift b/CodeEdit/Features/LSP/LanguageClient+Declaration.swift new file mode 100644 index 0000000000..1fefa912aa --- /dev/null +++ b/CodeEdit/Features/LSP/LanguageClient+Declaration.swift @@ -0,0 +1,25 @@ +// +// LanguageClient+Declaration.swift +// CodeEdit +// +// Created by Abe Malla on 2/7/24. +// + +import Foundation +import LanguageServerProtocol + +extension LanguageServer { + func requestGoToDeclaration(document documentURI: String, _ position: Position) async -> DeclarationResponse { + do { + let params = TextDocumentPositionParams( + textDocument: TextDocumentIdentifier(uri: documentURI), + position: position + ) + return try await lspInstance.declaration(params) + } catch { + print("requestGoToDeclaration Error \(error)") + } + + return nil + } +} diff --git a/CodeEdit/Features/LSP/LanguageClient+Definition.swift b/CodeEdit/Features/LSP/LanguageClient+Definition.swift new file mode 100644 index 0000000000..aaf3389e10 --- /dev/null +++ b/CodeEdit/Features/LSP/LanguageClient+Definition.swift @@ -0,0 +1,32 @@ +// +// LanguageClient+Definition.swift +// CodeEdit +// +// Created by Abe Malla on 2/7/24. +// + +import Foundation +import LanguageServerProtocol + +extension LanguageServer { + func requestGoToDefinition( + for languageId: LanguageIdentifier, + document documentURI: String, + position: Position + ) async throws -> DefinitionResponse { + let cacheKey = CacheKey(uri: documentURI, requestType: "goToDefinition") + if let cachedResponse: DefinitionResponse = lspCache.get(key: cacheKey) { + return cachedResponse + } + + let textDocumentIdentifier = TextDocumentIdentifier(uri: documentURI) + let textDocumentPositionParams = TextDocumentPositionParams( + textDocument: textDocumentIdentifier, + position: position + ) + let response = try await lspInstance.definition(textDocumentPositionParams) + + lspCache.set(key: cacheKey, value: response) + return response + } +} diff --git a/CodeEdit/Features/LSP/LanguageClient+Diagnostics.swift b/CodeEdit/Features/LSP/LanguageClient+Diagnostics.swift new file mode 100644 index 0000000000..710b9eff5f --- /dev/null +++ b/CodeEdit/Features/LSP/LanguageClient+Diagnostics.swift @@ -0,0 +1,15 @@ +// +// LanguageClient+Diagnostics.swift +// CodeEdit +// +// Created by Abe Malla on 2/7/24. +// + +import Foundation +import LanguageServerProtocol + +extension LanguageServer { + func requestPullDiagnostics() async { + // TODO: IMPLEMENTATION + } +} diff --git a/CodeEdit/Features/LSP/LanguageClient+DocumentColor.swift b/CodeEdit/Features/LSP/LanguageClient+DocumentColor.swift new file mode 100644 index 0000000000..b66f4c862d --- /dev/null +++ b/CodeEdit/Features/LSP/LanguageClient+DocumentColor.swift @@ -0,0 +1,29 @@ +// +// LanguageClient+DocumentColor.swift +// CodeEdit +// +// Created by Abe Malla on 2/7/24. +// + +import Foundation +import LanguageServerProtocol + +extension LanguageServer { + /// The document color request is sent from the client to the server to list all color references found in a given text document. Along with the range, a color value in RGB is returned. + /// Clients can use the result to decorate color references in an editor. For example: + /// 1. Color boxes showing the actual color next to the reference + /// 2. Show a color picker when a color reference is edited + func requestDocumentColor(document documentURI: String) async -> DocumentColorResponse { + do { + let params = DocumentColorParams( + textDocument: TextDocumentIdentifier(uri: documentURI), + workDoneToken: nil, + partialResultToken: nil + ) + return try await lspInstance.documentColor(params) + } catch { + print("requestDocumentColor Error \(error)") + } + return [] + } +} diff --git a/CodeEdit/Features/LSP/LanguageClient+DocumentHighlight.swift b/CodeEdit/Features/LSP/LanguageClient+DocumentHighlight.swift new file mode 100644 index 0000000000..5cdc4b62e3 --- /dev/null +++ b/CodeEdit/Features/LSP/LanguageClient+DocumentHighlight.swift @@ -0,0 +1,29 @@ +// +// LanguageClient+DocumentHighlight.swift +// CodeEdit +// +// Created by Abe Malla on 2/7/24. +// + +import Foundation +import LanguageServerProtocol + +extension LanguageServer { + /// The document highlight request is sent from the client to the server to resolve document highlights for a given text document position. + /// For programming languages this usually highlights all references to the symbol scoped to this file. + func requestDocumentHighlight(document documentURI: String, _ position: Position) async -> DocumentHighlightResponse { + do { + let params = DocumentHighlightParams( + textDocument: TextDocumentIdentifier(uri: documentURI), + position: position, + workDoneToken: nil, + partialResultToken: nil + ) + return try await lspInstance.documentHighlight(params) + } catch { + print("requestDocumentHighlight Error: \(error)") + } + + return nil + } +} diff --git a/CodeEdit/Features/LSP/LanguageClient+DocumentLink.swift b/CodeEdit/Features/LSP/LanguageClient+DocumentLink.swift new file mode 100644 index 0000000000..3e3b0f42e5 --- /dev/null +++ b/CodeEdit/Features/LSP/LanguageClient+DocumentLink.swift @@ -0,0 +1,31 @@ +// +// LanguageClient+DocumentLink.swift +// CodeEdit +// +// Created by Abe Malla on 2/7/24. +// + +import Foundation +import LanguageServerProtocol + +extension LanguageServer { + func requestDocumentLink() async -> DocumentLinkResponse { + do { + // TODO: DocumentLinkParams IS MISSING `textDocument: TextDocumentIdentifier;` FIELD + } catch { + // TODO: LOGGING + print("requestDocumentLink Error: \(error)") + } + return [] + } + + func requestDocumentLinkResolve(_ documentLink: DocumentLink) async -> DocumentLink? { + do { + return try await lspInstance.documentLinkResolve(documentLink) + } catch { + // TODO: LOGGING + print("requestDocumentLinkResolve Error: \(error)") + } + return nil + } +} diff --git a/CodeEdit/Features/LSP/LanguageClient+DocumentSymbol.swift b/CodeEdit/Features/LSP/LanguageClient+DocumentSymbol.swift new file mode 100644 index 0000000000..de321352d7 --- /dev/null +++ b/CodeEdit/Features/LSP/LanguageClient+DocumentSymbol.swift @@ -0,0 +1,25 @@ +// +// LanguageClient+DocumentSymbol.swift +// CodeEdit +// +// Created by Abe Malla on 2/7/24. +// + +import Foundation +import LanguageServerProtocol + +extension LanguageServer { + func requestDocumentSymbols(for languageId: LanguageIdentifier, document documentURI: String) async throws -> DocumentSymbolResponse { +// let cacheKey = CacheKey(uri: documentURI, requestType: "documentSymbols") +// if let cachedResponse: DocumentSymbolResponse = lspCache.get(key: cacheKey) { +// return cachedResponse +// } + + let textDocumentIdentifier = TextDocumentIdentifier(uri: documentURI) + let documentSymbolParams = DocumentSymbolParams(textDocument: textDocumentIdentifier) + let response = try await lspInstance.documentSymbol(documentSymbolParams) + +// lspCache.set(key: cacheKey, value: response) + return response + } +} diff --git a/CodeEdit/Features/LSP/LanguageClient+DocumentUtil.swift b/CodeEdit/Features/LSP/LanguageClient+DocumentUtil.swift new file mode 100644 index 0000000000..164bae026a --- /dev/null +++ b/CodeEdit/Features/LSP/LanguageClient+DocumentUtil.swift @@ -0,0 +1,161 @@ +// +// LanguageClient+DocumentUtil.swift +// CodeEdit +// +// Created by Abe Malla on 2/7/24. +// + +import Foundation +import LanguageServerProtocol + +extension LanguageServer { + mutating func addDocument(_ fileURL: URL) async -> Bool { + do { + let docContent = try String(contentsOf: fileURL) + let textDocument = TextDocumentItem( + uri: fileURL.absoluteString, + languageId: .rust, + version: 0, + text: docContent + ) + return await self.addDocument(textDocument) + } catch { + // TODO: LOGGING + print("addDocument: An error occurred: \(error)") + } + + return false + } + + /// Adds a TextDocumentItem to the tracked files and notifies the language server + mutating func addDocument(_ document: TextDocumentItem) async -> Bool { + do { + // Keep track of the document + trackedDocuments[document.uri] = document + + // Send notification to server about our opened file + let params = DidOpenTextDocumentParams(textDocument: document) + try await lspInstance.textDocumentDidOpen(params) + return true + } catch { + // TODO: LOGGING + print("addDocument: An error occurred: \(error)") + } + + return false + } + + /// Stops tracking a file and notifies the language server + mutating func closeDocument(_ uri: String) async -> Bool { + guard let document = trackedDocuments.removeValue(forKey: uri) else { return false } + + do { + let params = DidCloseTextDocumentParams(textDocument: + TextDocumentIdentifier(uri: document.uri)) + try await lspInstance.textDocumentDidClose(params) + return true + } catch { + // TODO: LOGGING + print("closeDocument: An error occurred: \(error)") + } + return false + } + + /// Updates the document with the specified URI with new text and increments its version. + /// - Parameters: + /// - uri: The URI of the document to update. + /// - newText: The new text to be set for the document. + /// - Returns: `true` if the document was successfully updated, `false` + mutating func updateDocument(withUri uri: String, newText: String, range: LSPRange, rangeLength: Int) async -> Bool { + // Update the document objects values, including the version + guard let currentDocument = trackedDocuments[uri], + let nsRange = convertLSPRangeToNSRange(range, in: currentDocument.text), + let stringRange = currentDocument.text.range(from: nsRange) else { + // TODO: LOG HERE + return false + } + + // Update the document's content and increment the version. + var updatedText = currentDocument.text + updatedText.replaceSubrange(stringRange, with: newText) + let updatedVersion = currentDocument.version + 1 + let updatedDocument = TextDocumentItem(uri: currentDocument.uri, + languageId: currentDocument.languageId, + version: updatedVersion, + text: updatedText) + trackedDocuments[uri] = updatedDocument + + // Notify the server + do { + let change = TextDocumentContentChangeEvent(range: range, + rangeLength: rangeLength, + text: newText) + let params = DidChangeTextDocumentParams(textDocument: VersionedTextDocumentIdentifier(uri: uri, + version: updatedVersion), + contentChanges: [change]) + try await lspInstance.textDocumentDidChange(params) + } catch { + // TODO: LOGGING + print("updateDocument: An error occurred: \(error)") + } + return true + } +} + +fileprivate extension String { + func range(from nsRange: NSRange) -> Range? { + guard let range = Range(nsRange, in: self) else { return nil } + return range + } +} + +private func applyEditsToDocument(document: TextDocumentItem, edits: [TextEdit]) -> TextDocumentItem { + // Sort edits in reverse order to prevent offset issues + let sortedEdits = edits.sorted { $0.range.start > $1.range.start } + var updatedText = document.text + for edit in sortedEdits { + // Apply each edit to the document text + guard let nsRange = convertLSPRangeToNSRange(edit.range, in: updatedText), + let range = updatedText.range(from: nsRange) else { continue } + updatedText.replaceSubrange(range, with: edit.newText) + } + + return TextDocumentItem(uri: document.uri, languageId: document.languageId, version: document.version, text: updatedText) +} + +private func updateDocumentWithChanges(document: TextDocumentItem, changes: [TextDocumentContentChangeEvent]) -> TextDocumentItem { + var updatedText = document.text + + for change in changes { + // Apply changes with range to the document text + if let lspRange = change.range, + let nsRange = convertLSPRangeToNSRange(lspRange, in: updatedText), + let range = updatedText.range(from: nsRange) { + updatedText.replaceSubrange(range, with: change.text) + } else { + // Replace the entire document text + updatedText = change.text + } + } + + return TextDocumentItem(uri: document.uri, languageId: document.languageId, version: document.version, text: updatedText) +} + +private func convertLSPRangeToNSRange(_ range: LSPRange, in text: String) -> NSRange? { + let lines = text.split(separator: "\n", omittingEmptySubsequences: false) + + // Calculate the start index + let startLineIndex = min(range.start.line, lines.count - 1) + let startCharacterIndex = min(range.start.character, lines[startLineIndex].count) + let startIndex = lines.prefix(startLineIndex).reduce(0, { $0 + $1.count + 1 }) + startCharacterIndex + + // Calculate the end index + let endLineIndex = min(range.end.line, lines.count - 1) + let endCharacterIndex = min(range.end.character, lines[endLineIndex].count) + let endIndex = lines.prefix(endLineIndex).reduce(0, { $0 + $1.count + 1 }) + endCharacterIndex + + // Ensure the range is valid + guard startIndex <= endIndex else { return nil } + + return NSRange(location: startIndex, length: endIndex - startIndex) +} diff --git a/CodeEdit/Features/LSP/LanguageClient+FoldingRange.swift b/CodeEdit/Features/LSP/LanguageClient+FoldingRange.swift new file mode 100644 index 0000000000..1cd6e3ba7a --- /dev/null +++ b/CodeEdit/Features/LSP/LanguageClient+FoldingRange.swift @@ -0,0 +1,22 @@ +// +// LanguageClient+FoldingRange.swift +// CodeEdit +// +// Created by Abe Malla on 2/7/24. +// + +import Foundation +import LanguageServerProtocol + +extension LanguageServer { + func requestFoldingRange(document documentURI: String) async -> FoldingRangeResponse { + do { + let params = FoldingRangeParams(textDocument: TextDocumentIdentifier(uri: documentURI)) + return try await lspInstance.foldingRange(params) + } catch { + // TODO: LOGGING + print("requestFoldingRange Error: \(error)") + } + return nil + } +} diff --git a/CodeEdit/Features/LSP/LanguageClient+Formatting.swift b/CodeEdit/Features/LSP/LanguageClient+Formatting.swift new file mode 100644 index 0000000000..4233ee26c9 --- /dev/null +++ b/CodeEdit/Features/LSP/LanguageClient+Formatting.swift @@ -0,0 +1,61 @@ +// +// LanguageClient+Formatting.swift +// CodeEdit +// +// Created by Abe Malla on 2/7/24. +// + +import Foundation +import LanguageServerProtocol + +// TODO: LOGGING + +extension LanguageServer { + func requestFormatting(document documentURI: String, + withFormat formattingOptions: FormattingOptions + ) async -> FormattingResult { + do { + let params = DocumentFormattingParams(textDocument: TextDocumentIdentifier(uri: documentURI), options: formattingOptions) + return try await lspInstance.formatting(params) + } catch { + print("requestFormatting Error \(error)") + } + return [] + } + + func requestRangeFormatting(document documentURI: String, + _ range: LSPRange, + withFormat formattingOptions: FormattingOptions + ) async -> FormattingResult { + do { + let params = DocumentRangeFormattingParams( + textDocument: TextDocumentIdentifier(uri: documentURI), + range: range, + options: formattingOptions + ) + return try await lspInstance.rangeFormatting(params) + } catch { + print("requestRangeFormatting Error \(error)") + } + return [] + } + + func requestOnTypeFormatting(document documentURI: String, + _ position: Position, + character ch: String, + withFormat formattingOptions: FormattingOptions + ) async -> FormattingResult { + do { + let params = DocumentOnTypeFormattingParams( + textDocument: TextDocumentIdentifier(uri: documentURI), + position: position, + ch: ch, + options: formattingOptions + ) + return try await lspInstance.onTypeFormatting(params) + } catch { + print("requestOnTypeFormatting Error \(error)") + } + return [] + } +} diff --git a/CodeEdit/Features/LSP/LanguageClient+Hover.swift b/CodeEdit/Features/LSP/LanguageClient+Hover.swift new file mode 100644 index 0000000000..4aef5e2040 --- /dev/null +++ b/CodeEdit/Features/LSP/LanguageClient+Hover.swift @@ -0,0 +1,26 @@ +// +// LanguageClient+Hover.swift +// CodeEdit +// +// Created by Abe Malla on 2/7/24. +// + +import Foundation +import LanguageServerProtocol + +extension LanguageServer { + /// The hover request is sent from the client to the server to request hover + /// information at a given text document position. + func requestHover(document documentURI: String, _ position: Position) async -> HoverResponse { + do { + let params = TextDocumentPositionParams( + textDocument: TextDocumentIdentifier(uri: documentURI), + position: position + ) + return try await lspInstance.hover(params) + } catch { + print("requestHover Error \(error)") + } + return nil + } +} diff --git a/CodeEdit/Features/LSP/LanguageClient+Implementation.swift b/CodeEdit/Features/LSP/LanguageClient+Implementation.swift new file mode 100644 index 0000000000..22d3296e9b --- /dev/null +++ b/CodeEdit/Features/LSP/LanguageClient+Implementation.swift @@ -0,0 +1,25 @@ +// +// LanguageClient+Implementation.swift +// CodeEdit +// +// Created by Abe Malla on 2/7/24. +// + +import Foundation +import LanguageServerProtocol + +extension LanguageServer { + /// Resolve the implementation location of a symbol at a given text document position + func requestImplementation(document documentURI: String, _ position: Position) async -> ImplementationResponse { + do { + let params = TextDocumentPositionParams( + textDocument: TextDocumentIdentifier(uri: documentURI), + position: position + ) + return try await lspInstance.implementation(params) + } catch { + print("requestImplementation Error \(error)") + } + return nil + } +} diff --git a/CodeEdit/Features/LSP/LanguageClient+InlayHint.swift b/CodeEdit/Features/LSP/LanguageClient+InlayHint.swift new file mode 100644 index 0000000000..c882d34430 --- /dev/null +++ b/CodeEdit/Features/LSP/LanguageClient+InlayHint.swift @@ -0,0 +1,39 @@ +// +// LanguageClient+InlayHint.swift +// CodeEdit +// +// Created by Abe Malla on 2/7/24. +// + +import Foundation +import LanguageServerProtocol + +extension LanguageServer { + /// Compute inlay hints for a given [text document, range] tuple that may be rendered in the + /// editor in place with other text + func requestInlayHint(document documentURI: String, _ range: LSPRange) async -> InlayHintResponse { + do { + let params = InlayHintParams( + workDoneToken: nil, + textDocument: TextDocumentIdentifier(uri: documentURI), + range: range + ) + return try await lspInstance.inlayHint(params) + } catch { + print("requestInlayHint Error \(error)") + } + return nil + } + + /// The request is sent from the client to the server to resolve additional information for a given inlay hint. + /// This is usually used to compute the tooltip, location or command properties of an inlay hint’s label part + /// to avoid its unnecessary computation during the textDocument/inlayHint request. + func requestInlayHintResolve(_ inlayHint: InlayHint) async -> InlayHint? { + do { + return try await lspInstance.inlayHintResolve(inlayHint) + } catch { + print("requestInlayHint Error \(error)") + } + return nil + } +} diff --git a/CodeEdit/Features/LSP/LanguageClient+References.swift b/CodeEdit/Features/LSP/LanguageClient+References.swift new file mode 100644 index 0000000000..cce116a0d7 --- /dev/null +++ b/CodeEdit/Features/LSP/LanguageClient+References.swift @@ -0,0 +1,26 @@ +// +// LanguageClient+References.swift +// CodeEdit +// +// Created by Abe Malla on 2/7/24. +// + +import Foundation +import LanguageServerProtocol + +extension LanguageServer { + /// Resolve project-wide references for the symbol denoted by the given text document position + func requestFindReferences(document documentURI: String, _ position: Position, _ includeDeclaration: Bool = false) async -> ReferenceResponse { + do { + let params = ReferenceParams( + textDocument: TextDocumentIdentifier(uri: documentURI), + position: position, + includeDeclaration: includeDeclaration + ) + return try await lspInstance.references(params) + } catch { + print("requestInlayHint Error \(error)") + } + return nil + } +} diff --git a/CodeEdit/Features/LSP/LanguageClient+Rename.swift b/CodeEdit/Features/LSP/LanguageClient+Rename.swift new file mode 100644 index 0000000000..55ee06ea3e --- /dev/null +++ b/CodeEdit/Features/LSP/LanguageClient+Rename.swift @@ -0,0 +1,40 @@ +// +// LanguageClient+Rename.swift +// CodeEdit +// +// Created by Abe Malla on 2/7/24. +// + +import Foundation +import LanguageServerProtocol + +extension LanguageServer { + /// Setup and test the validity of a rename operation at a given location + func requestPrepareRename(document documentURI: String, _ position: Position) async -> PrepareRenameResponse { + do { + let params = TextDocumentPositionParams( + textDocument: TextDocumentIdentifier(uri: documentURI), + position: position + ) + return try await lspInstance.prepareRename(params) + } catch { + print("requestInlayHint Error \(error)") + } + return nil + } + + /// Ask the server to compute a workspace change so that the client can perform a workspace-wide rename of a symbol + func requestRename(document documentURI: String, _ position: Position, newName name: String) async -> RenameResponse { + do { + let params = RenameParams( + textDocument: TextDocumentIdentifier(uri: documentURI), + position: position, + newName: name + ) + return try await lspInstance.rename(params) + } catch { + print("requestInlayHint Error \(error)") + } + return nil + } +} diff --git a/CodeEdit/Features/LSP/LanguageClient+SelectionRange.swift b/CodeEdit/Features/LSP/LanguageClient+SelectionRange.swift new file mode 100644 index 0000000000..c0f2795a7e --- /dev/null +++ b/CodeEdit/Features/LSP/LanguageClient+SelectionRange.swift @@ -0,0 +1,26 @@ +// +// LanguageClient+SelectionRange.swift +// CodeEdit +// +// Created by Abe Malla on 2/7/24. +// + +import Foundation +import LanguageServerProtocol + +extension LanguageServer { + /// Setup and test the validity of a rename operation at a given location + func requestSelectionRange(document documentURI: String, _ positions: [Position]) async -> SelectionRangeResponse { + do { + let params = SelectionRangeParams( + workDoneToken: nil, + textDocument: TextDocumentIdentifier(uri: documentURI), + positions: positions + ) + return try await lspInstance.selectionRange(params) + } catch { + print("requestInlayHint Error \(error)") + } + return nil + } +} diff --git a/CodeEdit/Features/LSP/LanguageClient+SemanticTokens.swift b/CodeEdit/Features/LSP/LanguageClient+SemanticTokens.swift new file mode 100644 index 0000000000..6a67f1f597 --- /dev/null +++ b/CodeEdit/Features/LSP/LanguageClient+SemanticTokens.swift @@ -0,0 +1,44 @@ +// +// LanguageClient+SemanticTokens.swift +// CodeEdit +// +// Created by Abe Malla on 2/7/24. +// + +import Foundation +import LanguageServerProtocol + +extension LanguageServer { + /// Setup and test the validity of a rename operation at a given location + func requestSemanticTokensFull(document documentURI: String) async -> SemanticTokensResponse { + do { + let params = SemanticTokensParams( + textDocument: TextDocumentIdentifier(uri: documentURI) + ) + return try await lspInstance.semanticTokensFull(params) + } catch { + print("requestInlayHint Error \(error)") + } + return nil + } + + func requestSemanticTokensRange(document documentURI: String, _ range: LSPRange) async -> SemanticTokensResponse { + do { + let params = SemanticTokensRangeParams(textDocument: TextDocumentIdentifier(uri: documentURI), range: range) + return try await lspInstance.semanticTokensRange(params) + } catch { + print("requestInlayHint Error \(error)") + } + return nil + } + + func requestSemanticTokensFullDelta(document documentURI: String, _ previousResultId: String) async -> SemanticTokensDeltaResponse { + do { + let params = SemanticTokensDeltaParams(textDocument: TextDocumentIdentifier(uri: documentURI), previousResultId: previousResultId) + return try await lspInstance.semanticTokensFullDelta(params) + } catch { + print("requestInlayHint Error \(error)") + } + return nil + } +} diff --git a/CodeEdit/Features/LSP/LanguageClient+SignatureHelp.swift b/CodeEdit/Features/LSP/LanguageClient+SignatureHelp.swift new file mode 100644 index 0000000000..93dfe5629f --- /dev/null +++ b/CodeEdit/Features/LSP/LanguageClient+SignatureHelp.swift @@ -0,0 +1,25 @@ +// +// LanguageClient+SignatureHelp.swift +// CodeEdit +// +// Created by Abe Malla on 2/7/24. +// + +import Foundation +import LanguageServerProtocol + +extension LanguageServer { + /// Request signature information at a given cursor position + func requestSignatureHelp(document documentURI: String, _ position: Position) async -> SignatureHelpResponse { + do { + let params = TextDocumentPositionParams( + textDocument: TextDocumentIdentifier(uri: documentURI), + position: position + ) + return try await lspInstance.signatureHelp(params) + } catch { + print("requestInlayHint Error \(error)") + } + return nil + } +} diff --git a/CodeEdit/Features/LSP/LanguageClient+TypeDefinition.swift b/CodeEdit/Features/LSP/LanguageClient+TypeDefinition.swift new file mode 100644 index 0000000000..a6f9a90a60 --- /dev/null +++ b/CodeEdit/Features/LSP/LanguageClient+TypeDefinition.swift @@ -0,0 +1,25 @@ +// +// LanguageClient+TypeDefinition.swift +// CodeEdit +// +// Created by Abe Malla on 2/7/24. +// + +import Foundation +import LanguageServerProtocol + +extension LanguageServer { + /// Resolve the type definition location of a symbol at a given text document position + func requestTypeDefinition(document documentURI: String, _ position: Position) async -> TypeDefinitionResponse { + do { + let params = TextDocumentPositionParams( + textDocument: TextDocumentIdentifier(uri: documentURI), + position: position + ) + return try await lspInstance.typeDefinition(params) + } catch { + print("requestInlayHint Error \(error)") + } + return nil + } +} diff --git a/CodeEdit/Features/LSP/LanguageConfiguration.swift b/CodeEdit/Features/LSP/LanguageConfiguration.swift new file mode 100644 index 0000000000..86a2dbdc86 --- /dev/null +++ b/CodeEdit/Features/LSP/LanguageConfiguration.swift @@ -0,0 +1,25 @@ +// +// LanguageConfiguration.swift +// CodeEdit +// +// Created by Abe Malla on 2/7/24. +// + +import Foundation +import LanguageServerProtocol + +func loadLSPConfigurations(from configFile: URL?) -> [LanguageIdentifier: LanguageServerBinary] { + // TODO: LOAD FROM FILE + return [ + .python: LanguageServerBinary( + execPath: "/opt/homebrew/Cellar/python-lsp-server/1.10.0/libexec/bin/pylsp", + args: ["--log-file", "/Users/abe/Documents/Swift/CodeEditLSPExample/CodeEditLSPExample/LSP_Logs/python.log"], + env: ProcessInfo.processInfo.environment + ), + .rust: LanguageServerBinary( + execPath: "/Users/abe/.vscode/extensions/rust-lang.rust-analyzer-0.3.1823-darwin-arm64/server/rust-analyzer", + args: ["--verbose", "--log-file", "/Users/abe/Documents/Swift/CodeEditLSPExample/CodeEditLSPExample/LSP_Logs/rust.log"], + env: ProcessInfo.processInfo.environment // ["RUST_BACKTRACE": "full"] + ) + ] +} diff --git a/CodeEdit/Features/LSP/LanguageServer.swift b/CodeEdit/Features/LSP/LanguageServer.swift index b0cb5e2e56..f11c4def63 100644 --- a/CodeEdit/Features/LSP/LanguageServer.swift +++ b/CodeEdit/Features/LSP/LanguageServer.swift @@ -10,6 +10,8 @@ import JSONRPC import LanguageClient import LanguageServerProtocol +// TODO: ADD ACTIVATION EVENTS + struct LanguageServer { let languageId: LanguageIdentifier let binary: LanguageServerBinary @@ -50,7 +52,6 @@ struct LanguageServer { } private static func getInitParams(projectURL: URL) -> InitializingServer.InitializeParamsProvider { - // TODO: FILL THIS OUT PROPERLY let provider: InitializingServer.InitializeParamsProvider = { // Text Document Capabilities let textDocumentCapabilities = TextDocumentClientCapabilities( @@ -141,7 +142,7 @@ struct LanguageServer { } /// Represents a language server binary. -struct LanguageServerBinary { +struct LanguageServerBinary: Codable { /// The path to the language server binary. let execPath: String /// The arguments to pass to the language server binary. @@ -149,3 +150,7 @@ struct LanguageServerBinary { /// The environment variables to pass to the language server binary. let env: [String: String]? } + +enum LSPError: Error { + case binaryNotFound +} diff --git a/CodeEdit/Features/LSP/LanguageServerManager.swift b/CodeEdit/Features/LSP/LanguageServerManager.swift new file mode 100644 index 0000000000..cfc0f9d6c4 --- /dev/null +++ b/CodeEdit/Features/LSP/LanguageServerManager.swift @@ -0,0 +1,210 @@ +// +// LanguageServerManager.swift +// CodeEdit +// +// Created by Abe Malla on 2/7/24. +// + +import os.log +import JSONRPC +import Foundation +import LanguageClient +import LanguageServerProtocol + +final class LanguageServerManager: ObservableObject { + private let logger: Logger + private var languageClients: [LanguageIdentifier: LanguageServer] = [:] + private var languageConfigs: [LanguageIdentifier: LanguageServerBinary] = [:] + + init() { + self.logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "", category: "LanguageServerManager") + self.languageConfigs = loadLSPConfigurations( + from: Bundle.main.url(forResource: "lspConfigs", withExtension: "json") + ) + } + + func server(for languageId: LanguageIdentifier) -> InitializingServer? { + return languageClients[languageId]?.lspInstance + } + + func languageClient(for languageId: LanguageIdentifier) -> LanguageServer? { + return languageClients[languageId] + } + + func startServer( + for languageId: LanguageIdentifier, + projectURL: URL, + workspaceFolders: [WorkspaceFolder]? + ) async throws { + guard let serverBinary = languageConfigs[languageId] else { + logger.error("Couldn't find language sever binary for \(languageId.rawValue)") + throw LSPError.binaryNotFound + } + + let server = try LanguageServer.createServer( + for: languageId, + with: serverBinary, + rootPath: projectURL, + workspaceFolders: workspaceFolders + ) + languageClients[languageId] = server + + logger.info("Initializing \(languageId.rawValue) language server") + try await server.initialize() + logger.info("Successfully initialized \(languageId.rawValue) language server") + + // TODO: BACKGROUND THREAD TO LISTEN TO EVENTS FROM CLIENT + } + + func testListenEvents() async throws { +// guard var languageClient = self.languageClient(for: .python) else { +// print("Failed to get client") +// exit(1) +// } +// +// print("Listening for events...") +// for await event in languageClient.lspInstance.eventSequence { +// switch event { +// case let .request(id: id, request: request): +// print("Request ID: \(id)") +// +// switch request { +// case let .workspaceConfiguration(params, handler): +// print("workspaceConfiguration: \(params)") +// case let .workspaceFolders(handler): +// print("workspaceFolders: \(String(describing: handler))") +// case let .workspaceApplyEdit(params, handler): +// print("workspaceApplyEdit: \(params)") +// case let .clientRegisterCapability(params, handler): +// print("clientRegisterCapability: \(params)") +// case let .clientUnregisterCapability(params, handler): +// print("clientUnregisterCapability: \(params)") +// case let .workspaceCodeLensRefresh(handler): +// print("workspaceCodeLensRefresh: \(String(describing: handler))") +// case let .workspaceSemanticTokenRefresh(handler): +// print("workspaceSemanticTokenRefresh: \(String(describing: handler))") +// case let .windowShowMessageRequest(params, handler): +// print("windowShowMessageRequest: \(params)") +// case let .windowShowDocument(params, handler): +// print("windowShowDocument: \(params)") +// case let .windowWorkDoneProgressCreate(params, handler): +// print("windowWorkDoneProgressCreate: \(params)") +// } +// +// case let .notification(notification): +// switch notification { +// case let .windowLogMessage(params): +// print("windowLogMessage \(params.type)\n```\n\(params.message)\n```\n") +// case let .windowShowMessage(params): +// print("windowShowMessage \(params.type)\n```\n\(params.message)\n```\n") +// case let .textDocumentPublishDiagnostics(params): +// print("textDocumentPublishDiagnostics: \(params)") +// case let .telemetryEvent(params): +// print("telemetryEvent: \(params)") +// case let .protocolCancelRequest(params): +// print("protocolCancelRequest: \(params)") +// case let .protocolProgress(params): +// print("protocolProgress: \(params)") +// case let .protocolLogTrace(params): +// print("protocolLogTrace: \(params)") +// } +// +// case let .error(error): +// print("Error from EventStream: \(error)") +// } +// } + } + + func testCompletion() async throws { + do { + guard var languageClient = self.languageClient(for: .python) else { + print("Failed to get client") + throw ServerManagerError.languageClientNotFound + } + + let testFilePathStr = "/Users/abe/Documents/Python/FastestFastAPI/main.py" + let testFileURL = URL(fileURLWithPath: testFilePathStr) + + // Tell server we opened a document + _ = await languageClient.addDocument(testFileURL) + + // Completion example + let textPosition = Position(line: 32, character: 18) // Lines and characters start at 0 + let completions = try await languageClient.requestCompletion( + document: testFileURL.absoluteString, + position: textPosition + ) + switch completions { + case .optionA(let completionItems): + // Handle the case where completions is an array of CompletionItem + print("\n*******\nCompletion Items:\n*******\n") + for item in completionItems { + let textEdits = getCompletionItemEdits(startPosition: textPosition, item: item) + for edit in textEdits { + print(edit) + } + } + + case .optionB(let completionList): + // Handle the case where completions is a CompletionList + print("\n*******\nCompletion Items:\n*******\n") + for item in completionList.items { + let textEdits = getCompletionItemEdits(startPosition: textPosition, item: item) + for edit in textEdits { + print(edit) + } + } + + print(completionList.items[0]) + + case .none: + print("No completions found") + } + + // Close the document + _ = await languageClient.closeDocument(testFilePathStr) + } catch { + print(error) + } + } + + func stopServer(for languageId: LanguageIdentifier) async throws { + guard let server = self.server(for: languageId) else { + logger.error("Server not found for language \(languageId.rawValue) during stop operation") + throw ServerManagerError.serverNotFound + } + do { + try await server.shutdownAndExit() + } catch { + logger.error("Failed to stop server for language \(languageId.rawValue)") + } + languageClients.removeValue(forKey: languageId) + logger.info("Server stopped for language \(languageId.rawValue)") + + // TODO: STOP BACKGROUND THREAD FOR LISTENING TO EVENTS + } + + func restartServer(for languageId: LanguageIdentifier) async throws { +// guard let langServer = languageClients[languageId] else { +// logger.error("Server not found for language \(languageId.rawValue) during restart operation") +// throw ServerManagerError.serverNotFound +// } + // TODO: RESTART SERVER + } + + func stopAllServers() async throws { + for (languageId, server) in languageClients { + try await server.lspInstance.shutdownAndExit() + languageClients.removeValue(forKey: languageId) + } + } +} + +// MARK: - Errors + +enum ServerManagerError: Error { + case serverNotFound + case serverStartFailed + case serverStopFailed + case languageClientNotFound +} diff --git a/CodeEdit/Features/NavigatorArea/ProjectNavigator/OutlineView/ProjectNavigatorViewController.swift b/CodeEdit/Features/NavigatorArea/ProjectNavigator/OutlineView/ProjectNavigatorViewController.swift index 12ddae603a..053114aa86 100644 --- a/CodeEdit/Features/NavigatorArea/ProjectNavigator/OutlineView/ProjectNavigatorViewController.swift +++ b/CodeEdit/Features/NavigatorArea/ProjectNavigator/OutlineView/ProjectNavigatorViewController.swift @@ -111,6 +111,7 @@ final class ProjectNavigatorViewController: NSViewController { /// Expand or collapse the folder on double click @objc private func onItemDoubleClicked() { + print("Trying to open by double click") guard let item = outlineView.item(atRow: outlineView.clickedRow) as? CEWorkspaceFile else { return } if item.isFolder { @@ -274,18 +275,26 @@ extension ProjectNavigatorViewController: NSOutlineViewDelegate { } func outlineViewSelectionDidChange(_ notification: Notification) { + print("Trying to open by outlineViewSelectionDidChange") guard let outlineView = notification.object as? NSOutlineView else { + print("Cant find outline view") return } let selectedIndex = outlineView.selectedRow - guard let item = outlineView.item(atRow: selectedIndex) as? CEWorkspaceFile else { return } + guard let item = outlineView.item(atRow: selectedIndex) as? CEWorkspaceFile else { + print("Cant find item in outline view") + return + } if !item.isFolder && shouldSendSelectionUpdate { + print("Sending update in outlineViewSelectionDidChange") DispatchQueue.main.async { self.workspace?.editorManager.activeEditor.openTab(file: item, asTemporary: true) } + } else { + print("Didnt send update in outlineViewSelectionDidChange [!item.isFolder]=\(!item.isFolder) shouldSendSelectionUpdate=\(shouldSendSelectionUpdate)") } } diff --git a/CodeEdit/Features/NavigatorArea/SourceControlNavigator/Changes/Views/SourceControlNavigatorChangesList.swift b/CodeEdit/Features/NavigatorArea/SourceControlNavigator/Changes/Views/SourceControlNavigatorChangesList.swift index 387516e0cb..857dedd238 100644 --- a/CodeEdit/Features/NavigatorArea/SourceControlNavigator/Changes/Views/SourceControlNavigatorChangesList.swift +++ b/CodeEdit/Features/NavigatorArea/SourceControlNavigator/Changes/Views/SourceControlNavigatorChangesList.swift @@ -37,7 +37,7 @@ struct SourceControlNavigatorChangesList: View { Group { Button("Open in New Tab") { DispatchQueue.main.async { - workspace.editorManager.activeEditor.openTab(file: file, asTemporary: true) + workspace.editorManager.openTab(item: file) } } Button("Open in New Window") {} @@ -62,7 +62,7 @@ struct SourceControlNavigatorChangesList: View { selectedFiles.count == 1, let file = selection.first { DispatchQueue.main.async { - workspace.editorManager.activeEditor.openTab(file: file, asTemporary: false) + workspace.editorManager.openTab(item: file) } } } @@ -72,7 +72,7 @@ struct SourceControlNavigatorChangesList: View { newSelection.count == 1, let file = newSelection.first { DispatchQueue.main.async { - workspace.editorManager.activeEditor.openTab(file: file, asTemporary: true) + workspace.editorManager.openTab(item: file) } } } diff --git a/CodeEdit/Features/WindowCommands/MainCommands.swift b/CodeEdit/Features/WindowCommands/MainCommands.swift index 19ed7d78b1..984b02f3a0 100644 --- a/CodeEdit/Features/WindowCommands/MainCommands.swift +++ b/CodeEdit/Features/WindowCommands/MainCommands.swift @@ -25,7 +25,8 @@ struct MainCommands: Commands { CommandGroup(replacing: .appSettings) { Button("Settings...") { - openWindow(id: "settings") +// openWindow(id: "about") + NSApp.openWindow(.about) } .keyboardShortcut(",") } From c2ac9aed7d2d365282900f7d5f9e286990055cda Mon Sep 17 00:00:00 2001 From: Abe M Date: Sun, 2 Jun 2024 18:26:07 -0700 Subject: [PATCH 04/20] Lint errors, project item location fixes --- CodeEdit.xcodeproj/project.pbxproj | 228 +++++++++++------- .../xcshareddata/swiftpm/Package.resolved | 86 ++++++- CodeEdit/Features/About/Views/AboutView.swift | 17 +- CodeEdit/Features/Editor/Models/Editor.swift | 13 - .../LanguageClient+ColorPresentation.swift | 6 +- .../LSP/LanguageClient+Completion.swift | 9 +- .../LSP/LanguageClient+Declaration.swift | 2 +- .../LSP/LanguageClient+DocumentColor.swift | 3 +- .../LanguageClient+DocumentHighlight.swift | 10 +- .../LSP/LanguageClient+DocumentLink.swift | 2 +- .../LSP/LanguageClient+DocumentSymbol.swift | 7 +- .../LSP/LanguageClient+DocumentUtil.swift | 59 +++-- .../LSP/LanguageClient+Formatting.swift | 30 ++- .../LSP/LanguageClient+References.swift | 6 +- .../Features/LSP/LanguageClient+Rename.swift | 8 +- .../LSP/LanguageClient+SemanticTokens.swift | 14 +- .../Features/LSP/LanguageConfiguration.swift | 11 +- CodeEdit/Features/LSP/LanguageServer.swift | 31 ++- .../ProjectNavigatorViewController.swift | 10 +- 19 files changed, 373 insertions(+), 179 deletions(-) diff --git a/CodeEdit.xcodeproj/project.pbxproj b/CodeEdit.xcodeproj/project.pbxproj index 36e9c48d80..06d02a331b 100644 --- a/CodeEdit.xcodeproj/project.pbxproj +++ b/CodeEdit.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 60; + objectVersion = 55; objects = { /* Begin PBXBuildFile section */ @@ -64,9 +64,38 @@ 3000516A2BBD3A8200A98562 /* ServiceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 300051692BBD3A8200A98562 /* ServiceType.swift */; }; 3000516C2BBD3A9500A98562 /* ServiceWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3000516B2BBD3A9500A98562 /* ServiceWrapper.swift */; }; 3026F50F2AC006C80061227E /* InspectorAreaViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3026F50E2AC006C80061227E /* InspectorAreaViewModel.swift */; }; + 3083B3612C0A8C8F00C6642C /* CodeEditKit in Frameworks */ = {isa = PBXBuildFile; productRef = 6C0F3A3B2A1D0D5000223D19 /* CodeEditKit */; }; 30AB4EBB2BF718A100ED4431 /* DeveloperSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30AB4EBA2BF718A100ED4431 /* DeveloperSettings.swift */; }; 30AB4EBD2BF71CA800ED4431 /* DeveloperSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30AB4EBC2BF71CA800ED4431 /* DeveloperSettingsView.swift */; }; 30AB4EC22BF7253200ED4431 /* KeyValueTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30AB4EC12BF7253200ED4431 /* KeyValueTable.swift */; }; + 30B087FC2C0D53080063A882 /* LanguageClient+CallHierarchy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087DF2C0D53080063A882 /* LanguageClient+CallHierarchy.swift */; }; + 30B087FD2C0D53080063A882 /* LanguageClient+CodeLens.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E02C0D53080063A882 /* LanguageClient+CodeLens.swift */; }; + 30B087FE2C0D53080063A882 /* LanguageClient+ColorPresentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E12C0D53080063A882 /* LanguageClient+ColorPresentation.swift */; }; + 30B087FF2C0D53080063A882 /* LanguageClient+Completion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E22C0D53080063A882 /* LanguageClient+Completion.swift */; }; + 30B088002C0D53080063A882 /* LanguageClient+Declaration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E32C0D53080063A882 /* LanguageClient+Declaration.swift */; }; + 30B088012C0D53080063A882 /* LanguageClient+Definition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E42C0D53080063A882 /* LanguageClient+Definition.swift */; }; + 30B088022C0D53080063A882 /* LanguageClient+Diagnostics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E52C0D53080063A882 /* LanguageClient+Diagnostics.swift */; }; + 30B088032C0D53080063A882 /* LanguageClient+DocumentColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E62C0D53080063A882 /* LanguageClient+DocumentColor.swift */; }; + 30B088042C0D53080063A882 /* LanguageClient+DocumentHighlight.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E72C0D53080063A882 /* LanguageClient+DocumentHighlight.swift */; }; + 30B088052C0D53080063A882 /* LanguageClient+DocumentLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E82C0D53080063A882 /* LanguageClient+DocumentLink.swift */; }; + 30B088062C0D53080063A882 /* LanguageClient+DocumentSymbol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E92C0D53080063A882 /* LanguageClient+DocumentSymbol.swift */; }; + 30B088072C0D53080063A882 /* LanguageClient+DocumentUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087EA2C0D53080063A882 /* LanguageClient+DocumentUtil.swift */; }; + 30B088082C0D53080063A882 /* LanguageClient+FoldingRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087EB2C0D53080063A882 /* LanguageClient+FoldingRange.swift */; }; + 30B088092C0D53080063A882 /* LanguageClient+Formatting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087EC2C0D53080063A882 /* LanguageClient+Formatting.swift */; }; + 30B0880A2C0D53080063A882 /* LanguageClient+Hover.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087ED2C0D53080063A882 /* LanguageClient+Hover.swift */; }; + 30B0880B2C0D53080063A882 /* LanguageClient+Implementation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087EE2C0D53080063A882 /* LanguageClient+Implementation.swift */; }; + 30B0880C2C0D53080063A882 /* LanguageClient+InlayHint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087EF2C0D53080063A882 /* LanguageClient+InlayHint.swift */; }; + 30B0880D2C0D53080063A882 /* LanguageClient+References.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F02C0D53080063A882 /* LanguageClient+References.swift */; }; + 30B0880E2C0D53080063A882 /* LanguageClient+Rename.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F12C0D53080063A882 /* LanguageClient+Rename.swift */; }; + 30B0880F2C0D53080063A882 /* LanguageClient+SelectionRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F22C0D53080063A882 /* LanguageClient+SelectionRange.swift */; }; + 30B088102C0D53080063A882 /* LanguageClient+SemanticTokens.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F32C0D53080063A882 /* LanguageClient+SemanticTokens.swift */; }; + 30B088112C0D53080063A882 /* LanguageClient+SignatureHelp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F42C0D53080063A882 /* LanguageClient+SignatureHelp.swift */; }; + 30B088122C0D53080063A882 /* LanguageClient+TypeDefinition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F52C0D53080063A882 /* LanguageClient+TypeDefinition.swift */; }; + 30B088132C0D53080063A882 /* LanguageConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F62C0D53080063A882 /* LanguageConfiguration.swift */; }; + 30B088142C0D53080063A882 /* LanguageServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F72C0D53080063A882 /* LanguageServer.swift */; }; + 30B088152C0D53080063A882 /* LanguageServerManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F82C0D53080063A882 /* LanguageServerManager.swift */; }; + 30B088162C0D53080063A882 /* LSPCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F92C0D53080063A882 /* LSPCache.swift */; }; + 30B088172C0D53080063A882 /* LSPUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087FA2C0D53080063A882 /* LSPUtil.swift */; }; 30E6D0012A6E505200A58B20 /* NavigatorSidebarViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30E6D0002A6E505200A58B20 /* NavigatorSidebarViewModel.swift */; }; 3E0196732A3921AC002648D8 /* codeedit_shell_integration.zsh in Resources */ = {isa = PBXBuildFile; fileRef = 3E0196722A3921AC002648D8 /* codeedit_shell_integration.zsh */; }; 3E01967A2A392B45002648D8 /* codeedit_shell_integration.bash in Resources */ = {isa = PBXBuildFile; fileRef = 3E0196792A392B45002648D8 /* codeedit_shell_integration.bash */; }; @@ -637,6 +666,34 @@ 30AB4EBA2BF718A100ED4431 /* DeveloperSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperSettings.swift; sourceTree = ""; }; 30AB4EBC2BF71CA800ED4431 /* DeveloperSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperSettingsView.swift; sourceTree = ""; }; 30AB4EC12BF7253200ED4431 /* KeyValueTable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyValueTable.swift; sourceTree = ""; }; + 30B087DF2C0D53080063A882 /* LanguageClient+CallHierarchy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+CallHierarchy.swift"; sourceTree = ""; }; + 30B087E02C0D53080063A882 /* LanguageClient+CodeLens.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+CodeLens.swift"; sourceTree = ""; }; + 30B087E12C0D53080063A882 /* LanguageClient+ColorPresentation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+ColorPresentation.swift"; sourceTree = ""; }; + 30B087E22C0D53080063A882 /* LanguageClient+Completion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+Completion.swift"; sourceTree = ""; }; + 30B087E32C0D53080063A882 /* LanguageClient+Declaration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+Declaration.swift"; sourceTree = ""; }; + 30B087E42C0D53080063A882 /* LanguageClient+Definition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+Definition.swift"; sourceTree = ""; }; + 30B087E52C0D53080063A882 /* LanguageClient+Diagnostics.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+Diagnostics.swift"; sourceTree = ""; }; + 30B087E62C0D53080063A882 /* LanguageClient+DocumentColor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+DocumentColor.swift"; sourceTree = ""; }; + 30B087E72C0D53080063A882 /* LanguageClient+DocumentHighlight.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+DocumentHighlight.swift"; sourceTree = ""; }; + 30B087E82C0D53080063A882 /* LanguageClient+DocumentLink.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+DocumentLink.swift"; sourceTree = ""; }; + 30B087E92C0D53080063A882 /* LanguageClient+DocumentSymbol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+DocumentSymbol.swift"; sourceTree = ""; }; + 30B087EA2C0D53080063A882 /* LanguageClient+DocumentUtil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+DocumentUtil.swift"; sourceTree = ""; }; + 30B087EB2C0D53080063A882 /* LanguageClient+FoldingRange.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+FoldingRange.swift"; sourceTree = ""; }; + 30B087EC2C0D53080063A882 /* LanguageClient+Formatting.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+Formatting.swift"; sourceTree = ""; }; + 30B087ED2C0D53080063A882 /* LanguageClient+Hover.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+Hover.swift"; sourceTree = ""; }; + 30B087EE2C0D53080063A882 /* LanguageClient+Implementation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+Implementation.swift"; sourceTree = ""; }; + 30B087EF2C0D53080063A882 /* LanguageClient+InlayHint.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+InlayHint.swift"; sourceTree = ""; }; + 30B087F02C0D53080063A882 /* LanguageClient+References.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+References.swift"; sourceTree = ""; }; + 30B087F12C0D53080063A882 /* LanguageClient+Rename.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+Rename.swift"; sourceTree = ""; }; + 30B087F22C0D53080063A882 /* LanguageClient+SelectionRange.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+SelectionRange.swift"; sourceTree = ""; }; + 30B087F32C0D53080063A882 /* LanguageClient+SemanticTokens.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+SemanticTokens.swift"; sourceTree = ""; }; + 30B087F42C0D53080063A882 /* LanguageClient+SignatureHelp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+SignatureHelp.swift"; sourceTree = ""; }; + 30B087F52C0D53080063A882 /* LanguageClient+TypeDefinition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+TypeDefinition.swift"; sourceTree = ""; }; + 30B087F62C0D53080063A882 /* LanguageConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LanguageConfiguration.swift; sourceTree = ""; }; + 30B087F72C0D53080063A882 /* LanguageServer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LanguageServer.swift; sourceTree = ""; }; + 30B087F82C0D53080063A882 /* LanguageServerManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LanguageServerManager.swift; sourceTree = ""; }; + 30B087F92C0D53080063A882 /* LSPCache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LSPCache.swift; sourceTree = ""; }; + 30B087FA2C0D53080063A882 /* LSPUtil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LSPUtil.swift; sourceTree = ""; }; 30E6D0002A6E505200A58B20 /* NavigatorSidebarViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigatorSidebarViewModel.swift; sourceTree = ""; }; 3E0196722A3921AC002648D8 /* codeedit_shell_integration.zsh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = codeedit_shell_integration.zsh; sourceTree = ""; }; 3E0196792A392B45002648D8 /* codeedit_shell_integration.bash */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = codeedit_shell_integration.bash; sourceTree = ""; }; @@ -1086,9 +1143,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 6C0F3A3C2A1D0D5000223D19 /* CodeEditKit in Frameworks */, + 3083B3612C0A8C8F00C6642C /* CodeEditKit in Frameworks */, 6C66C31329D05CDC00DE9ED2 /* GRDB in Frameworks */, - 3007CE302B7859F500700D41 /* LanguageClient in Frameworks */, 58F2EB1E292FB954004A9BDE /* Sparkle in Frameworks */, 6CBE1D002B720565003AC32E /* CodeEditSourceEditor in Frameworks */, 6C147C4529A329350089B630 /* OrderedCollections in Frameworks */, @@ -1323,41 +1379,6 @@ path = ViewModels; sourceTree = ""; }; - 3058117F2B7383090049C9AA /* LSP */ = { - isa = PBXGroup; - children = ( - 305811822B73834F0049C9AA /* LSPCache.swift */, - 3039C9162B7850B900C8B4F8 /* LanguageConfiguration.swift */, - 305811802B73832B0049C9AA /* LanguageServer.swift */, - 3039C8E02B738E9600C8B4F8 /* LanguageServerManager.swift */, - 3039C90F2B73912F00C8B4F8 /* LanguageClient+CallHierarchy.swift */, - 3039C90D2B73911D00C8B4F8 /* LanguageClient+CodeLens.swift */, - 3039C90B2B73910300C8B4F8 /* LanguageClient+ColorPresentation.swift */, - 3039C9092B7390D200C8B4F8 /* LanguageClient+Completion.swift */, - 3039C9072B7390C000C8B4F8 /* LanguageClient+Declaration.swift */, - 3039C9052B7390AA00C8B4F8 /* LanguageClient+Definition.swift */, - 3039C9032B73909B00C8B4F8 /* LanguageClient+Diagnostics.swift */, - 3039C9012B73908800C8B4F8 /* LanguageClient+DocumentColor.swift */, - 3039C8FF2B73907500C8B4F8 /* LanguageClient+DocumentHighlight.swift */, - 3039C8FD2B73905800C8B4F8 /* LanguageClient+DocumentLink.swift */, - 3039C8FB2B73904100C8B4F8 /* LanguageClient+DocumentSymbol.swift */, - 3039C8F92B73901E00C8B4F8 /* LanguageClient+DocumentUtil.swift */, - 3039C8F72B73900A00C8B4F8 /* LanguageClient+FoldingRange.swift */, - 3039C8F52B738FF700C8B4F8 /* LanguageClient+Formatting.swift */, - 3039C8F32B738FE500C8B4F8 /* LanguageClient+Hover.swift */, - 3039C8F12B738FC700C8B4F8 /* LanguageClient+Implementation.swift */, - 3039C8EF2B738FAB00C8B4F8 /* LanguageClient+InlayHint.swift */, - 3039C8ED2B738F9100C8B4F8 /* LanguageClient+References.swift */, - 3039C8EB2B738F6600C8B4F8 /* LanguageClient+Rename.swift */, - 3039C8E92B738F4E00C8B4F8 /* LanguageClient+SelectionRange.swift */, - 3039C8E72B738F2800C8B4F8 /* LanguageClient+SemanticTokens.swift */, - 3039C8E52B738EF600C8B4F8 /* LanguageClient+SignatureHelp.swift */, - 3039C8E32B738EB900C8B4F8 /* LanguageClient+TypeDefinition.swift */, - 3039C9192B78588A00C8B4F8 /* LSPUtil.swift */, - ); - path = LSP; - sourceTree = ""; - }; 307AC4CB2ABABD9800163376 /* ViewModels */ = { isa = PBXGroup; children = ( @@ -1383,6 +1404,41 @@ path = Models; sourceTree = ""; }; + 30B087FB2C0D53080063A882 /* LSP */ = { + isa = PBXGroup; + children = ( + 30B087DF2C0D53080063A882 /* LanguageClient+CallHierarchy.swift */, + 30B087E02C0D53080063A882 /* LanguageClient+CodeLens.swift */, + 30B087E12C0D53080063A882 /* LanguageClient+ColorPresentation.swift */, + 30B087E22C0D53080063A882 /* LanguageClient+Completion.swift */, + 30B087E32C0D53080063A882 /* LanguageClient+Declaration.swift */, + 30B087E42C0D53080063A882 /* LanguageClient+Definition.swift */, + 30B087E52C0D53080063A882 /* LanguageClient+Diagnostics.swift */, + 30B087E62C0D53080063A882 /* LanguageClient+DocumentColor.swift */, + 30B087E72C0D53080063A882 /* LanguageClient+DocumentHighlight.swift */, + 30B087E82C0D53080063A882 /* LanguageClient+DocumentLink.swift */, + 30B087E92C0D53080063A882 /* LanguageClient+DocumentSymbol.swift */, + 30B087EA2C0D53080063A882 /* LanguageClient+DocumentUtil.swift */, + 30B087EB2C0D53080063A882 /* LanguageClient+FoldingRange.swift */, + 30B087EC2C0D53080063A882 /* LanguageClient+Formatting.swift */, + 30B087ED2C0D53080063A882 /* LanguageClient+Hover.swift */, + 30B087EE2C0D53080063A882 /* LanguageClient+Implementation.swift */, + 30B087EF2C0D53080063A882 /* LanguageClient+InlayHint.swift */, + 30B087F02C0D53080063A882 /* LanguageClient+References.swift */, + 30B087F12C0D53080063A882 /* LanguageClient+Rename.swift */, + 30B087F22C0D53080063A882 /* LanguageClient+SelectionRange.swift */, + 30B087F32C0D53080063A882 /* LanguageClient+SemanticTokens.swift */, + 30B087F42C0D53080063A882 /* LanguageClient+SignatureHelp.swift */, + 30B087F52C0D53080063A882 /* LanguageClient+TypeDefinition.swift */, + 30B087F62C0D53080063A882 /* LanguageConfiguration.swift */, + 30B087F72C0D53080063A882 /* LanguageServer.swift */, + 30B087F82C0D53080063A882 /* LanguageServerManager.swift */, + 30B087F92C0D53080063A882 /* LSPCache.swift */, + 30B087FA2C0D53080063A882 /* LSPUtil.swift */, + ); + path = LSP; + sourceTree = ""; + }; 3E0196712A392170002648D8 /* ShellIntegration */ = { isa = PBXGroup; children = ( @@ -1480,7 +1536,7 @@ 587B9E0129301D8F00AC7927 /* Git */, B6EE988E27E8877C00CDD8AB /* InspectorArea */, 58A5DF9D29339F6400D1BD5D /* Keybindings */, - 3058117F2B7383090049C9AA /* LSP */, + 30B087FB2C0D53080063A882 /* LSP */, 287776EA27E350A100D46668 /* NavigatorArea */, 5878DAA0291AE76700DD95A3 /* QuickOpen */, 58798210292D92370085B254 /* Search */, @@ -3221,6 +3277,8 @@ 6C0F3A3A2A1D0D5000223D19 /* XCRemoteSwiftPackageReference "CodeEditKit" */, 6CBE1CFE2B720565003AC32E /* XCRemoteSwiftPackageReference "CodeEditSourceEditor" */, 6C0617D42BDB4432008C9C42 /* XCRemoteSwiftPackageReference "LogStream" */, + 3083B3892C0BEEE300C6642C /* XCRemoteSwiftPackageReference "LanguageServerProtocol" */, + 3083B38A2C0BEEFF00C6642C /* XCRemoteSwiftPackageReference "LanguageClient" */, ); productRefGroup = B658FB2D27DA9E0F00EA4DBD /* Products */; projectDirPath = ""; @@ -3343,10 +3401,12 @@ buildActionMask = 2147483647; files = ( 58798285292ED0FB0085B254 /* TerminalEmulatorView+Coordinator.swift in Sources */, + 30B0880E2C0D53080063A882 /* LanguageClient+Rename.swift in Sources */, 587B9E7D29301D8F00AC7927 /* GitHubPullRequestRouter.swift in Sources */, B67DB0EF2AF3E381002DC647 /* PaneTextField.swift in Sources */, 5878DA842918642000DD95A3 /* ParsePackagesResolved.swift in Sources */, B628B7932B18369800F9775A /* GitClient+Validate.swift in Sources */, + 30B088142C0D53080063A882 /* LanguageServer.swift in Sources */, 5879824F292E78D80085B254 /* CodeFileView.swift in Sources */, 6C0D0C6829E861B000AE4D3F /* SettingsSidebarFix.swift in Sources */, 587B9E8429301D8F00AC7927 /* GitHubUser.swift in Sources */, @@ -3369,7 +3429,6 @@ 2813F93927ECC4C300E305E4 /* NavigatorAreaView.swift in Sources */, B664C3B02B965F6C00816B4E /* NavigationSettings.swift in Sources */, 5B698A0F2B2636A700DE9392 /* SearchSettingsIgnoreGlobPatternItemView.swift in Sources */, - 3039C90C2B73910300C8B4F8 /* LanguageClient+ColorPresentation.swift in Sources */, 587B9E8A29301D8F00AC7927 /* GitHubIssue.swift in Sources */, EC0870F72A455F6400EB8692 /* ProjectNavigatorViewController+NSMenuDelegate.swift in Sources */, B60718202B0C6CE7009CDAB4 /* GitStashEntry.swift in Sources */, @@ -3378,25 +3437,28 @@ 6C82D6C629C012AD00495C54 /* NSApp+openWindow.swift in Sources */, 6C14CEB028777D3C001468FE /* FindNavigatorListViewController.swift in Sources */, 587B9E7F29301D8F00AC7927 /* GitHubUserRouter.swift in Sources */, - 3039C90E2B73911D00C8B4F8 /* LanguageClient+CodeLens.swift in Sources */, + 30B088042C0D53080063A882 /* LanguageClient+DocumentHighlight.swift in Sources */, B62AEDBC2A210DBB009A9F52 /* UtilityAreaTerminalTab.swift in Sources */, B67DB0F62AFC2A7A002DC647 /* FindNavigatorToolbarBottom.swift in Sources */, 04BA7C142AE2AA7300584E1C /* GitCloneViewModel.swift in Sources */, B61A606129F188AB009B43F9 /* ExternalLink.swift in Sources */, - 3039C9102B73912F00C8B4F8 /* LanguageClient+CallHierarchy.swift in Sources */, 587B9E9729301D8F00AC7927 /* BitBucketAccount+Token.swift in Sources */, 587B9E7729301D8F00AC7927 /* String+PercentEncoding.swift in Sources */, 587B9E5B29301D8F00AC7927 /* GitCheckoutBranchView.swift in Sources */, 2813F93827ECC4AA00E305E4 /* FindNavigatorResultList.swift in Sources */, + 30B088152C0D53080063A882 /* LanguageServerManager.swift in Sources */, 613899B92B6E704500A5CAF6 /* String+Normalise.swift in Sources */, + 30B088002C0D53080063A882 /* LanguageClient+Declaration.swift in Sources */, 04BA7C192AE2D7C600584E1C /* GitClient+Branches.swift in Sources */, 587B9E8829301D8F00AC7927 /* GitHubFiles.swift in Sources */, 77A01E232BB423A800F0EA38 /* CEWorkspaceSettingsPage.swift in Sources */, 587B9DA729300ABD00AC7927 /* HelpButton.swift in Sources */, + 30B088172C0D53080063A882 /* LSPUtil.swift in Sources */, 6C5B63DE29C76213005454BA /* WindowCodeFileView.swift in Sources */, 58F2EB08292FB2B0004A9BDE /* TextEditingSettings.swift in Sources */, 201169DB2837B34000F92B46 /* SourceControlNavigatorChangedFileView.swift in Sources */, 5882252E292C280D00E83CDE /* UtilityAreaMaximizeButton.swift in Sources */, + 30B0880D2C0D53080063A882 /* LanguageClient+References.swift in Sources */, 77A01E2E2BB4261200F0EA38 /* CEWorkspaceSettings.swift in Sources */, 6C4104E9297C970F00F472BA /* AboutDefaultView.swift in Sources */, 587B9E6F29301D8F00AC7927 /* GitLabProjectAccess.swift in Sources */, @@ -3417,10 +3479,10 @@ B6C4F2A62B3CABD200B2B140 /* HistoryInspectorItemView.swift in Sources */, B65B10FE2B08B07D002852CF /* SourceControlNavigatorChangesList.swift in Sources */, 58F2EB03292FB2B0004A9BDE /* Documentation.docc in Sources */, + 30B087FE2C0D53080063A882 /* LanguageClient+ColorPresentation.swift in Sources */, 66F2C8C42BEAA939004674F7 /* PDFFileView.swift in Sources */, 611192042B08CCED00D4459B /* SearchIndexer+ProgressiveSearch.swift in Sources */, 611192022B08CCDC00D4459B /* SearchIndexer+Search.swift in Sources */, - 3039C8E42B738EB900C8B4F8 /* LanguageClient+TypeDefinition.swift in Sources */, 04BA7C272AE2E9F100584E1C /* GitClient+Push.swift in Sources */, B664C3B32B96634F00816B4E /* NavigationSettingsView.swift in Sources */, 2B7A583527E4BA0100D25D4E /* AppDelegate.swift in Sources */, @@ -3431,13 +3493,13 @@ 041FC6AD2AE437CE00C1F65A /* SourceControlNavigatorNewBranchView.swift in Sources */, 77A01E432BBC3A2800F0EA38 /* CETask.swift in Sources */, 6C48D8F72972E5F300D6D205 /* WindowObserver.swift in Sources */, + 30B087FD2C0D53080063A882 /* LanguageClient+CodeLens.swift in Sources */, 6CED16E42A3E660D000EC962 /* String+Lines.swift in Sources */, 587B9E6B29301D8F00AC7927 /* GitLabAvatarURL.swift in Sources */, 58798233292E30B90085B254 /* FeedbackToolbar.swift in Sources */, 587B9E6829301D8F00AC7927 /* GitLabAccountModel.swift in Sources */, 5878DAA7291AE76700DD95A3 /* QuickOpenViewModel.swift in Sources */, 6CFF967429BEBCC300182D6F /* FindCommands.swift in Sources */, - 3039C8F42B738FE500C8B4F8 /* LanguageClient+Hover.swift in Sources */, 587B9E6529301D8F00AC7927 /* GitLabGroupAccess.swift in Sources */, 6C91D57229B176FF0059A90D /* EditorManager.swift in Sources */, 6C82D6BC29C00CD900495C54 /* FirstResponderPropertyWrapper.swift in Sources */, @@ -3458,7 +3520,6 @@ 201169DD2837B3AC00F92B46 /* SourceControlNavigatorToolbarBottom.swift in Sources */, 587B9E8B29301D8F00AC7927 /* GitHubAccount+deleteReference.swift in Sources */, 58798237292E30B90085B254 /* FeedbackView.swift in Sources */, - 3039C9042B73909B00C8B4F8 /* LanguageClient+Diagnostics.swift in Sources */, 587B9E9829301D8F00AC7927 /* GitCommit.swift in Sources */, 6C5228B529A868BD00AC48F6 /* Environment+ContentInsets.swift in Sources */, 587B9E9429301D8F00AC7927 /* BitBucketTokenConfiguration.swift in Sources */, @@ -3467,12 +3528,11 @@ 58A5DFA329339F6400D1BD5D /* CommandManager.swift in Sources */, 58798284292ED0FB0085B254 /* TerminalEmulatorView.swift in Sources */, B6C4F2AC2B3CC4D000B2B140 /* CommitChangedFileListItemView.swift in Sources */, - 3039C8EE2B738F9100C8B4F8 /* LanguageClient+References.swift in Sources */, 6C82D6B329BFD88700495C54 /* NavigateCommands.swift in Sources */, - 3039C8E12B738E9600C8B4F8 /* LanguageServerManager.swift in Sources */, B66A4E4C29C9179B004573B4 /* CodeEditApp.swift in Sources */, 661EF7B82BEE215300C3E577 /* ImageFileView.swift in Sources */, 4E7F066629602E7B00BB3C12 /* CodeEditSplitViewController.swift in Sources */, + 30B088022C0D53080063A882 /* LanguageClient+Diagnostics.swift in Sources */, 587B9E8D29301D8F00AC7927 /* GitHubAccount.swift in Sources */, 201169E72837B5CA00F92B46 /* SourceControlManager.swift in Sources */, 58822528292C280D00E83CDE /* StatusBarEncodingSelector.swift in Sources */, @@ -3480,17 +3540,18 @@ 6C7F37FE2A3EA6FA00217B83 /* View+focusedValue.swift in Sources */, B6C4F2A12B3CA37500B2B140 /* SourceControlNavigatorHistoryView.swift in Sources */, 6CBE1CFB2B71DAA6003AC32E /* Loopable.swift in Sources */, + 30B088092C0D53080063A882 /* LanguageClient+Formatting.swift in Sources */, + 30B088102C0D53080063A882 /* LanguageClient+SemanticTokens.swift in Sources */, B6C6A43029771F7100A3D28F /* EditorTabBackground.swift in Sources */, - 3039C8EA2B738F4E00C8B4F8 /* LanguageClient+SelectionRange.swift in Sources */, B60718372B170638009CDAB4 /* SourceControlNavigatorRenameBranchView.swift in Sources */, 6C578D8129CD294800DC73B2 /* ExtensionActivatorView.swift in Sources */, - 3039C90A2B7390D200C8B4F8 /* LanguageClient+Completion.swift in Sources */, B6F0517D29D9E4B100D72287 /* TerminalSettingsView.swift in Sources */, 587B9E8C29301D8F00AC7927 /* GitHubOpenness.swift in Sources */, 5894E59729FEF7740077E59C /* CEWorkspaceFile+Recursion.swift in Sources */, 9D36E1BF2B5E7D7500443C41 /* GitBranchesGroup.swift in Sources */, 587B9E8229301D8F00AC7927 /* GitHubPreviewHeader.swift in Sources */, 611191FC2B08CCB800D4459B /* SearchIndexer+AsyncController.swift in Sources */, + 30B088112C0D53080063A882 /* LanguageClient+SignatureHelp.swift in Sources */, 6C578D8929CD36E400DC73B2 /* Commands+ForEach.swift in Sources */, 611192082B08CCFD00D4459B /* SearchIndexer+Terms.swift in Sources */, 28B8F884280FFE4600596236 /* NSTableView+Background.swift in Sources */, @@ -3504,8 +3565,8 @@ 85E4122A2A46C8CA00183F2B /* LocationsSettings.swift in Sources */, 613899B12B6E6FDC00A5CAF6 /* Collection+FuzzySearch.swift in Sources */, 581550D129FBD30400684881 /* TextTableViewCell.swift in Sources */, - 3039C8F82B73900A00C8B4F8 /* LanguageClient+FoldingRange.swift in Sources */, 587B9E6629301D8F00AC7927 /* GitLabProjectHook.swift in Sources */, + 30B088032C0D53080063A882 /* LanguageClient+DocumentColor.swift in Sources */, 587B9E9329301D8F00AC7927 /* BitBucketOAuthConfiguration.swift in Sources */, 6C18620A298BF5A800C663EA /* RecentProjectsListView.swift in Sources */, 58F2EB0A292FB2B0004A9BDE /* SettingsData.swift in Sources */, @@ -3528,6 +3589,7 @@ 5882252B292C280D00E83CDE /* StatusBarCursorPositionLabel.swift in Sources */, 5882252D292C280D00E83CDE /* UtilityAreaSplitTerminalButton.swift in Sources */, 58798238292E30B90085B254 /* FeedbackWindowController.swift in Sources */, + 30B088132C0D53080063A882 /* LanguageConfiguration.swift in Sources */, 587B9E6C29301D8F00AC7927 /* GitLabNamespace.swift in Sources */, 30AB4EC22BF7253200ED4431 /* KeyValueTable.swift in Sources */, 6C48D8F22972DAFC00D6D205 /* Env+IsFullscreen.swift in Sources */, @@ -3566,11 +3628,11 @@ 6111920C2B08CD0B00D4459B /* SearchIndexer+InternalMethods.swift in Sources */, 6CABB1A129C5593800340467 /* SearchPanelView.swift in Sources */, D7211D4327E066CE008F2ED7 /* Localized+Ex.swift in Sources */, - 305811832B73834F0049C9AA /* LSPCache.swift in Sources */, 581BFB692926431000D251EC /* WelcomeActionView.swift in Sources */, 669BC4082BED306400D1197C /* AnyFileView.swift in Sources */, 20D839AE280E0CA700B27357 /* HistoryPopoverView.swift in Sources */, B6E41C7029DD157F0088F9F4 /* AccountsSettingsView.swift in Sources */, + 30B088122C0D53080063A882 /* LanguageClient+TypeDefinition.swift in Sources */, 6CFF967A29BEBD2400182D6F /* ViewCommands.swift in Sources */, 850C631229D6B03400E1444C /* SettingsPage.swift in Sources */, 587B9E6729301D8F00AC7927 /* GitLabEventData.swift in Sources */, @@ -3595,10 +3657,8 @@ B62AEDD42A27B29F009A9F52 /* PaneToolbar.swift in Sources */, D7E201B227E8D50000CB86D0 /* FindNavigatorForm.swift in Sources */, 287776E927E34BC700D46668 /* EditorTabBarView.swift in Sources */, - 3039C8FA2B73901E00C8B4F8 /* LanguageClient+DocumentUtil.swift in Sources */, B60BE8BD297A167600841125 /* AcknowledgementRowView.swift in Sources */, B6F0517029D9E36800D72287 /* LocationsSettingsView.swift in Sources */, - 3039C9002B73907500C8B4F8 /* LanguageClient+DocumentHighlight.swift in Sources */, B62AEDDC2A27C1B3009A9F52 /* OSLogType+Color.swift in Sources */, 587B9E6329301D8F00AC7927 /* GitLabAccount.swift in Sources */, 6C1CC99B2B1E7CBC0002349B /* FindNavigatorIndexBar.swift in Sources */, @@ -3615,9 +3675,6 @@ B6C6A42A297716A500A3D28F /* EditorTabCloseButton.swift in Sources */, B60718422B17DB93009CDAB4 /* SourceControlNavigatorRepositoryView+outlineGroupData.swift in Sources */, 58A5DF7D2931787A00D1BD5D /* ShellClient.swift in Sources */, - 3039C8E82B738F2800C8B4F8 /* LanguageClient+SemanticTokens.swift in Sources */, - 3039C8F62B738FF700C8B4F8 /* LanguageClient+Formatting.swift in Sources */, - 3039C8EC2B738F6600C8B4F8 /* LanguageClient+Rename.swift in Sources */, 5879821A292D92370085B254 /* SearchResultModel.swift in Sources */, B6F0517729D9E3AD00D72287 /* SourceControlGeneralView.swift in Sources */, 587B9E8929301D8F00AC7927 /* GitHubGist.swift in Sources */, @@ -3640,9 +3697,9 @@ 581BFB682926431000D251EC /* WelcomeView.swift in Sources */, 6CFF967829BEBCF600182D6F /* MainCommands.swift in Sources */, 587B9E7129301D8F00AC7927 /* GitURLSession.swift in Sources */, - 3039C8E62B738EF600C8B4F8 /* LanguageClient+SignatureHelp.swift in Sources */, 610C0FDA2B44438F00A01CA7 /* WorkspaceDocument+FindAndReplace.swift in Sources */, 5882252C292C280D00E83CDE /* UtilityAreaView.swift in Sources */, + 30B088072C0D53080063A882 /* LanguageClient+DocumentUtil.swift in Sources */, 2847019E27FDDF7600F87B6B /* ProjectNavigatorOutlineView.swift in Sources */, B607184C2B17E037009CDAB4 /* SourceControlStashChangesView.swift in Sources */, 6C14CEB32877A68F001468FE /* FindNavigatorMatchListCell.swift in Sources */, @@ -3658,13 +3715,15 @@ 286471AB27ED51FD0039369D /* ProjectNavigatorView.swift in Sources */, B6E41C7C29DE2B110088F9F4 /* AccountsSettingsProviderRow.swift in Sources */, B62AEDB52A1FE295009A9F52 /* UtilityAreaDebugView.swift in Sources */, - 3039C9062B7390AA00C8B4F8 /* LanguageClient+Definition.swift in Sources */, + 30B0880B2C0D53080063A882 /* LanguageClient+Implementation.swift in Sources */, 6C049A372A49E2DB00D42923 /* DirectoryEventStream.swift in Sources */, + 30B088062C0D53080063A882 /* LanguageClient+DocumentSymbol.swift in Sources */, 04BA7C0E2AE2A76E00584E1C /* SourceControlNavigatorChangesCommitView.swift in Sources */, 615AA21A2B0CFD480013FCCC /* LazyStringLoader.swift in Sources */, 6CAAF68A29BC9C2300A1F48A /* (null) in Sources */, 30AB4EBD2BF71CA800ED4431 /* DeveloperSettingsView.swift in Sources */, 6C6BD6EF29CD12E900235D17 /* ExtensionManagerWindow.swift in Sources */, + 30B087FF2C0D53080063A882 /* LanguageClient+Completion.swift in Sources */, 6CFF967629BEBCD900182D6F /* FileCommands.swift in Sources */, B60718462B17DC15009CDAB4 /* RepoOutlineGroupItem.swift in Sources */, 613899B32B6E6FEE00A5CAF6 /* FuzzySearchable.swift in Sources */, @@ -3677,7 +3736,6 @@ 58F2EB05292FB2B0004A9BDE /* Settings.swift in Sources */, 6CBD1BC62978DE53006639D5 /* Font+Caption3.swift in Sources */, 30E6D0012A6E505200A58B20 /* NavigatorSidebarViewModel.swift in Sources */, - 3039C8FE2B73905800C8B4F8 /* LanguageClient+DocumentLink.swift in Sources */, B6E41C9429DEAE260088F9F4 /* SourceControlAccount.swift in Sources */, 2806E9022979588B000040F4 /* Contributor.swift in Sources */, 58D01C98293167DC00C5B6B4 /* String+RemoveOccurrences.swift in Sources */, @@ -3689,6 +3747,7 @@ 6CA1AE952B46950000378EAB /* EditorInstance.swift in Sources */, 30AB4EBB2BF718A100ED4431 /* DeveloperSettings.swift in Sources */, B6C4F2A92B3CB00100B2B140 /* CommitDetailsHeaderView.swift in Sources */, + 30B088012C0D53080063A882 /* LanguageClient+Definition.swift in Sources */, B6EA1FFB29DB78F6001BF195 /* ThemeSettingsThemeDetails.swift in Sources */, 587B9E7029301D8F00AC7927 /* GitLabUser.swift in Sources */, 04660F6A27E51E5C00477777 /* CodeEditWindowController.swift in Sources */, @@ -3697,6 +3756,7 @@ 587B9E6129301D8F00AC7927 /* GitLabOAuthConfiguration.swift in Sources */, 587B9E6229301D8F00AC7927 /* GitLabConfiguration.swift in Sources */, 61A53A7E2B4449870093BF8A /* WorkspaceDocument+Find.swift in Sources */, + 30B0880A2C0D53080063A882 /* LanguageClient+Hover.swift in Sources */, 6CABB19E29C5591D00340467 /* NSTableViewWrapper.swift in Sources */, 5879821B292D92370085B254 /* SearchResultMatchModel.swift in Sources */, 04BA7C1E2AE2D8A000584E1C /* GitClient+Clone.swift in Sources */, @@ -3728,13 +3788,11 @@ B6EA1FF829DB78DB001BF195 /* ThemeSettingThemeRow.swift in Sources */, 587B9E7629301D8F00AC7927 /* GitTime.swift in Sources */, 587B9E5D29301D8F00AC7927 /* GitLabUserRouter.swift in Sources */, - 3039C9022B73908800C8B4F8 /* LanguageClient+DocumentColor.swift in Sources */, 588847692992ABCA00996D95 /* Array+SortURLs.swift in Sources */, 58822530292C280D00E83CDE /* UtilityAreaFilterTextField.swift in Sources */, 6C82D6B929BFE34900495C54 /* HelpCommands.swift in Sources */, 6C147C4929A32A080089B630 /* EditorLayoutView.swift in Sources */, 6C147C4129A328BF0089B630 /* EditorLayout.swift in Sources */, - 3039C8F02B738FAB00C8B4F8 /* LanguageClient+InlayHint.swift in Sources */, B6D7EA592971078500301FAC /* InspectorSection.swift in Sources */, B6AB09A32AAABFEC0003A3A6 /* EditorTabBarLeadingAccessories.swift in Sources */, B69BFDC72B0686910050D9A6 /* GitClient+Initiate.swift in Sources */, @@ -3742,13 +3800,14 @@ 85745D632A38F8D900089AAB /* String+HighlightOccurrences.swift in Sources */, B6EE989027E8879A00CDD8AB /* InspectorAreaView.swift in Sources */, 587B9DA229300ABD00AC7927 /* EffectView.swift in Sources */, - 3039C9172B7850B900C8B4F8 /* LanguageConfiguration.swift in Sources */, 6C97EBCC2978760400302F95 /* AcknowledgementsWindowController.swift in Sources */, 284DC84F2978B7B400BF2770 /* ContributorsView.swift in Sources */, B62AEDC92A2704F3009A9F52 /* UtilityAreaTabView.swift in Sources */, + 30B088052C0D53080063A882 /* LanguageClient+DocumentLink.swift in Sources */, 58798250292E78D80085B254 /* CodeFileDocument.swift in Sources */, 5878DAA5291AE76700DD95A3 /* QuickOpenView.swift in Sources */, 201169D72837B2E300F92B46 /* SourceControlNavigatorView.swift in Sources */, + 30B088162C0D53080063A882 /* LSPCache.swift in Sources */, B6F0517929D9E3C900D72287 /* SourceControlGitView.swift in Sources */, 587B9E8329301D8F00AC7927 /* GitHubPullRequest.swift in Sources */, 5878DA82291863F900DD95A3 /* AcknowledgementsView.swift in Sources */, @@ -3756,6 +3815,8 @@ 58D01C9A293167DC00C5B6B4 /* CodeEditKeychain.swift in Sources */, B62AEDAA2A1FCBE5009A9F52 /* AreaTabBar.swift in Sources */, 20D839AB280DEB2900B27357 /* NoSelectionInspectorView.swift in Sources */, + 30B0880F2C0D53080063A882 /* LanguageClient+SelectionRange.swift in Sources */, + 30B0880C2C0D53080063A882 /* LanguageClient+InlayHint.swift in Sources */, 587B9E5A29301D8F00AC7927 /* GitCloneView.swift in Sources */, B65B10F52B081A0C002852CF /* SourceControlAddRemoteView.swift in Sources */, 58D01C99293167DC00C5B6B4 /* String+MD5.swift in Sources */, @@ -3778,6 +3839,7 @@ 587B9E9629301D8F00AC7927 /* BitBucketRepositories.swift in Sources */, 5878DAA6291AE76700DD95A3 /* QuickOpenPreviewView.swift in Sources */, 58798286292ED0FB0085B254 /* SwiftTerm+Color+Init.swift in Sources */, + 30B087FC2C0D53080063A882 /* LanguageClient+CallHierarchy.swift in Sources */, 6CFF967C29BEBD5200182D6F /* WindowCommands.swift in Sources */, 587B9E7229301D8F00AC7927 /* GitJSONPostRouter.swift in Sources */, 5878DAB0291D627C00DD95A3 /* EditorPathBarMenu.swift in Sources */, @@ -3806,10 +3868,10 @@ B6AB09A12AAABAAE0003A3A6 /* EditorTabs.swift in Sources */, 04C3255B2801F86400C8DA2D /* ProjectNavigatorViewController.swift in Sources */, 587B9E6029301D8F00AC7927 /* GitLabOAuthRouter.swift in Sources */, - 3039C9082B7390C000C8B4F8 /* LanguageClient+Declaration.swift in Sources */, B6AB09B32AB919CF0003A3A6 /* View+actionBar.swift in Sources */, 6C05A8AF284D0CA3007F4EAA /* WorkspaceDocument+Listeners.swift in Sources */, 588847632992A2A200996D95 /* CEWorkspaceFile.swift in Sources */, + 30B088082C0D53080063A882 /* LanguageClient+FoldingRange.swift in Sources */, 6C2C155D29B4F4E500EA60A5 /* SplitViewReader.swift in Sources */, B65B10EF2B07C454002852CF /* GitClient+Remote.swift in Sources */, 58AFAA2F2933C69E00482B53 /* EditorItemID.swift in Sources */, @@ -4908,21 +4970,6 @@ }; /* End XCConfigurationList section */ -/* Begin XCLocalSwiftPackageReference section */ - 3039C8DF2B738D9B00C8B4F8 /* XCLocalSwiftPackageReference "../LanguageServerProtocol" */ = { - isa = XCLocalSwiftPackageReference; - relativePath = ../LanguageServerProtocol; - }; - 30AAFCD02B7380EF007177DC /* XCLocalSwiftPackageReference "../CodeEditKit" */ = { - isa = XCLocalSwiftPackageReference; - relativePath = ../CodeEditKit; - }; - 30E1AAB12B73856500420274 /* XCLocalSwiftPackageReference "../LanguageClient" */ = { - isa = XCLocalSwiftPackageReference; - relativePath = ../LanguageClient; - }; -/* End XCLocalSwiftPackageReference section */ - /* Begin XCRemoteSwiftPackageReference section */ 2816F592280CF50500DD548B /* XCRemoteSwiftPackageReference "CodeEditSymbols" */ = { isa = XCRemoteSwiftPackageReference; @@ -4940,6 +4987,22 @@ minimumVersion = 0.2.2; }; }; + 3083B3892C0BEEE300C6642C /* XCRemoteSwiftPackageReference "LanguageServerProtocol" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/ChimeHQ/LanguageServerProtocol"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 0.13.2; + }; + }; + 3083B38A2C0BEEFF00C6642C /* XCRemoteSwiftPackageReference "LanguageClient" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/ChimeHQ/LanguageClient"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 0.8.0; + }; + }; 583E529A29361BAB001AB554 /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/pointfreeco/swift-snapshot-testing.git"; @@ -5008,8 +5071,8 @@ isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/CodeEditApp/CodeEditSourceEditor"; requirement = { - kind = upToNextMajorVersion; - minimumVersion = 0.7.2; + kind = exactVersion; + version = 0.7.2; }; }; 6CDEFC9429E22C2700B7C684 /* XCRemoteSwiftPackageReference "SwiftUI-Introspect" */ = { @@ -5028,11 +5091,6 @@ package = 2816F592280CF50500DD548B /* XCRemoteSwiftPackageReference "CodeEditSymbols" */; productName = CodeEditSymbols; }; - 3007CE2F2B7859F500700D41 /* LanguageClient */ = { - isa = XCSwiftPackageProductDependency; - package = 30E1AAB12B73856500420274 /* XCLocalSwiftPackageReference "../LanguageClient" */; - productName = LanguageClient; - }; 583E529B29361BAB001AB554 /* SnapshotTesting */ = { isa = XCSwiftPackageProductDependency; package = 583E529A29361BAB001AB554 /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */; diff --git a/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index ce4215548a..26f820371c 100644 --- a/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "3f6921a5ec30d1ecb6d6b205cf27a816c318246bb00f0ea367b997cc66527d32", + "originHash" : "9c699d730017e749c2b945e8435c6edd8169fe23742cc8fd8a58078ae48764ac", "pins" : [ { "identity" : "anycodable", @@ -31,7 +31,7 @@ { "identity" : "codeeditsourceeditor", "kind" : "remoteSourceControl", - "location" : "https://github.com/CodeEditApp/CodeEditSourceEditor", + "location" : "https://github.com/CodeEditApp/CodeEditSourceEditor.git", "state" : { "revision" : "7360f00bf7ec8e93b4833357bd254bef7e5c943d", "version" : "0.7.2" @@ -51,8 +51,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/CodeEditApp/CodeEditTextView.git", "state" : { - "revision" : "86b980464bcb67693e2053283c7a99bdc6f358bc", - "version" : "0.7.3" + "revision" : "80911be6bcdae5e35ef5ed351adf6dda9b57e555", + "version" : "0.7.4" } }, { @@ -73,6 +73,24 @@ "version" : "0.4.2" } }, + { + "identity" : "fseventswrapper", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Frizlab/FSEventsWrapper", + "state" : { + "revision" : "70bbea4b108221fcabfce8dbced8502831c0ae04", + "version" : "2.1.0" + } + }, + { + "identity" : "globpattern", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ChimeHQ/GlobPattern", + "state" : { + "revision" : "4ebb9e89e07cc475efa74f87dc6d21f4a9e060f8", + "version" : "0.1.1" + } + }, { "identity" : "grdb.swift", "kind" : "remoteSourceControl", @@ -82,10 +100,37 @@ "version" : "5.26.1" } }, + { + "identity" : "jsonrpc", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ChimeHQ/JSONRPC", + "state" : { + "revision" : "c6ec759d41a76ac88fe7327c41a77d9033943374", + "version" : "0.9.0" + } + }, + { + "identity" : "languageclient", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ChimeHQ/LanguageClient", + "state" : { + "revision" : "f8fdeaed850fbc3e542cd038e952758887f6be5d", + "version" : "0.8.0" + } + }, + { + "identity" : "languageserverprotocol", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ChimeHQ/LanguageServerProtocol", + "state" : { + "revision" : "ac76fccf0e981c8e30c5ee4de1b15adc1decd697", + "version" : "0.13.2" + } + }, { "identity" : "logstream", "kind" : "remoteSourceControl", - "location" : "https://github.com/CodeEditApp/LogStream", + "location" : "https://github.com/Wouter01/LogStream", "state" : { "revision" : "6f83694b2675dcf3b1cea0a52546ff4469c18282", "version" : "1.3.0" @@ -100,6 +145,24 @@ "version" : "0.2.1" } }, + { + "identity" : "processenv", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ChimeHQ/ProcessEnv", + "state" : { + "revision" : "83f1ebc9dd6fb1db0bd89a3fcae00488a0f3fdd9", + "version" : "1.0.0" + } + }, + { + "identity" : "queue", + "kind" : "remoteSourceControl", + "location" : "https://github.com/mattmassicotte/Queue", + "state" : { + "revision" : "8d6f936097888f97011610ced40313655dc5948d", + "version" : "0.1.4" + } + }, { "identity" : "rearrange", "kind" : "remoteSourceControl", @@ -109,6 +172,15 @@ "version" : "1.8.1" } }, + { + "identity" : "semaphore", + "kind" : "remoteSourceControl", + "location" : "https://github.com/groue/Semaphore", + "state" : { + "revision" : "f1c4a0acabeb591068dea6cffdd39660b86dec28", + "version" : "0.0.8" + } + }, { "identity" : "sparkle", "kind" : "remoteSourceControl", @@ -150,8 +222,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/lukepistrol/SwiftLintPlugin", "state" : { - "revision" : "ea6d3ca895b49910f790e98e4b4ca658e0fe490e", - "version" : "0.54.0" + "revision" : "a0f7b12c7be228592d924f29f654ebbd924ac9c5", + "version" : "0.55.1" } }, { diff --git a/CodeEdit/Features/About/Views/AboutView.swift b/CodeEdit/Features/About/Views/AboutView.swift index 7e9643a15b..900177edb9 100644 --- a/CodeEdit/Features/About/Views/AboutView.swift +++ b/CodeEdit/Features/About/Views/AboutView.swift @@ -44,16 +44,13 @@ public struct AboutView: View { // if anyone knows of a better way to do this feel free to refactor .background(.regularMaterial.opacity(0)) .background(EffectView(.popover, blendingMode: .behindWindow).ignoresSafeArea()) -// .background { -// Button("") { -// dismiss() -// } -// .keyboardShortcut(.escape, modifiers: []) -// .hidden() -// } - .onExitCommand(perform: { - dismiss() - }) + .background { + Button("") { + dismiss() + } + .keyboardShortcut(.escape, modifiers: []) + .hidden() + } .task { if let window = NSApp.findWindow(.about) { window.styleMask = [.closable, .fullSizeContentView, .titled, .nonactivatingPanel] diff --git a/CodeEdit/Features/Editor/Models/Editor.swift b/CodeEdit/Features/Editor/Models/Editor.swift index 6f009fb670..805ec7816d 100644 --- a/CodeEdit/Features/Editor/Models/Editor.swift +++ b/CodeEdit/Features/Editor/Models/Editor.swift @@ -144,19 +144,16 @@ final class Editor: ObservableObject, Identifiable { /// - file: the file to open. /// - asTemporary: indicates whether the tab should be opened as a temporary tab or a permanent tab. func openTab(file: CEWorkspaceFile, asTemporary: Bool) { - print("Attempting to open file: \(file.url)") let item = EditorInstance(file: file) // Item is already opened in a tab. guard !tabs.contains(item) || !asTemporary else { selectedTab = item history.prepend(item) - print("File already opened!") return } switch (temporaryTab, asTemporary) { case (.some(let tab), true): - print("Temporary tab 1") if let index = tabs.firstIndex(of: tab) { history.removeFirst(historyOffset) history.prepend(item) @@ -168,16 +165,13 @@ final class Editor: ObservableObject, Identifiable { } case (.some(let tab), false) where tab == item: - print("2") temporaryTab = nil case (.none, true): - print("3") openTab(file: item.file) temporaryTab = item case (.none, false): - print("4") openTab(file: item.file) default: @@ -192,7 +186,6 @@ final class Editor: ObservableObject, Identifiable { /// - fromHistory: Indicates whether the tab has been opened from going back in history. func openTab(file: CEWorkspaceFile, at index: Int? = nil, fromHistory: Bool = false) { let item = Tab(file: file) - print("Tabs before update: \(tabs)") if let index { tabs.insert(item, at: index) } else { @@ -203,9 +196,6 @@ final class Editor: ObservableObject, Identifiable { } } - print("Updated tabs: \(tabs)") - print("New item: \(item.file.url)") - selectedTab = item if !fromHistory { history.removeFirst(historyOffset) @@ -215,14 +205,12 @@ final class Editor: ObservableObject, Identifiable { do { try openFile(item: item) } catch { - print("openFile error") print(error) } } private func openFile(item: Tab) throws { guard item.file.fileDocument == nil else { - print("File document is nil, returning!") return } @@ -235,7 +223,6 @@ final class Editor: ObservableObject, Identifiable { ) item.file.fileDocument = codeFile CodeEditDocumentController.shared.addDocument(codeFile) - print("Successfully opened file") } func goBackInHistory() { diff --git a/CodeEdit/Features/LSP/LanguageClient+ColorPresentation.swift b/CodeEdit/Features/LSP/LanguageClient+ColorPresentation.swift index 22e6434633..4c5ebdf0ad 100644 --- a/CodeEdit/Features/LSP/LanguageClient+ColorPresentation.swift +++ b/CodeEdit/Features/LSP/LanguageClient+ColorPresentation.swift @@ -9,7 +9,11 @@ import Foundation import LanguageServerProtocol extension LanguageServer { - func requestColorPresentation(document documentURI: String, _ color: Color, _ range: LSPRange) async -> ColorPresentationResponse { + func requestColorPresentation( + document documentURI: String, + _ color: Color, + _ range: LSPRange + ) async -> ColorPresentationResponse { let params = ColorPresentationParams( workDoneToken: nil, partialResultToken: nil, diff --git a/CodeEdit/Features/LSP/LanguageClient+Completion.swift b/CodeEdit/Features/LSP/LanguageClient+Completion.swift index 214ad3b054..041e069d4a 100644 --- a/CodeEdit/Features/LSP/LanguageClient+Completion.swift +++ b/CodeEdit/Features/LSP/LanguageClient+Completion.swift @@ -14,9 +14,14 @@ extension LanguageServer { if let cachedResponse: CompletionResponse = lspCache.get(key: cacheKey) { return cachedResponse } - let completionParams = CompletionParams(uri: documentURI, position: position, triggerKind: .invoked, triggerCharacter: nil) + let completionParams = CompletionParams( + uri: documentURI, + position: position, + triggerKind: .invoked, + triggerCharacter: nil + ) let response = try await lspInstance.completion(completionParams) - + lspCache.set(key: cacheKey, value: response) return response } diff --git a/CodeEdit/Features/LSP/LanguageClient+Declaration.swift b/CodeEdit/Features/LSP/LanguageClient+Declaration.swift index 1fefa912aa..41374f6bce 100644 --- a/CodeEdit/Features/LSP/LanguageClient+Declaration.swift +++ b/CodeEdit/Features/LSP/LanguageClient+Declaration.swift @@ -19,7 +19,7 @@ extension LanguageServer { } catch { print("requestGoToDeclaration Error \(error)") } - + return nil } } diff --git a/CodeEdit/Features/LSP/LanguageClient+DocumentColor.swift b/CodeEdit/Features/LSP/LanguageClient+DocumentColor.swift index b66f4c862d..4599d327d5 100644 --- a/CodeEdit/Features/LSP/LanguageClient+DocumentColor.swift +++ b/CodeEdit/Features/LSP/LanguageClient+DocumentColor.swift @@ -9,7 +9,8 @@ import Foundation import LanguageServerProtocol extension LanguageServer { - /// The document color request is sent from the client to the server to list all color references found in a given text document. Along with the range, a color value in RGB is returned. + /// The document color request is sent from the client to the server to list all color + /// references found in a given text document. Along with the range, a color value in RGB is returned. /// Clients can use the result to decorate color references in an editor. For example: /// 1. Color boxes showing the actual color next to the reference /// 2. Show a color picker when a color reference is edited diff --git a/CodeEdit/Features/LSP/LanguageClient+DocumentHighlight.swift b/CodeEdit/Features/LSP/LanguageClient+DocumentHighlight.swift index 5cdc4b62e3..95668aa2b8 100644 --- a/CodeEdit/Features/LSP/LanguageClient+DocumentHighlight.swift +++ b/CodeEdit/Features/LSP/LanguageClient+DocumentHighlight.swift @@ -9,9 +9,13 @@ import Foundation import LanguageServerProtocol extension LanguageServer { - /// The document highlight request is sent from the client to the server to resolve document highlights for a given text document position. - /// For programming languages this usually highlights all references to the symbol scoped to this file. - func requestDocumentHighlight(document documentURI: String, _ position: Position) async -> DocumentHighlightResponse { + /// The document highlight request is sent from the client to the server to resolve document + /// highlights for a given text document position. For programming languages this usually + /// highlights all references to the symbol scoped to this file. + func requestDocumentHighlight( + document documentURI: String, + _ position: Position + ) async -> DocumentHighlightResponse { do { let params = DocumentHighlightParams( textDocument: TextDocumentIdentifier(uri: documentURI), diff --git a/CodeEdit/Features/LSP/LanguageClient+DocumentLink.swift b/CodeEdit/Features/LSP/LanguageClient+DocumentLink.swift index 3e3b0f42e5..355d35e764 100644 --- a/CodeEdit/Features/LSP/LanguageClient+DocumentLink.swift +++ b/CodeEdit/Features/LSP/LanguageClient+DocumentLink.swift @@ -18,7 +18,7 @@ extension LanguageServer { } return [] } - + func requestDocumentLinkResolve(_ documentLink: DocumentLink) async -> DocumentLink? { do { return try await lspInstance.documentLinkResolve(documentLink) diff --git a/CodeEdit/Features/LSP/LanguageClient+DocumentSymbol.swift b/CodeEdit/Features/LSP/LanguageClient+DocumentSymbol.swift index de321352d7..af1d676bc8 100644 --- a/CodeEdit/Features/LSP/LanguageClient+DocumentSymbol.swift +++ b/CodeEdit/Features/LSP/LanguageClient+DocumentSymbol.swift @@ -9,12 +9,15 @@ import Foundation import LanguageServerProtocol extension LanguageServer { - func requestDocumentSymbols(for languageId: LanguageIdentifier, document documentURI: String) async throws -> DocumentSymbolResponse { + func requestDocumentSymbols( + for languageId: LanguageIdentifier, + document documentURI: String + ) async throws -> DocumentSymbolResponse { // let cacheKey = CacheKey(uri: documentURI, requestType: "documentSymbols") // if let cachedResponse: DocumentSymbolResponse = lspCache.get(key: cacheKey) { // return cachedResponse // } - + let textDocumentIdentifier = TextDocumentIdentifier(uri: documentURI) let documentSymbolParams = DocumentSymbolParams(textDocument: textDocumentIdentifier) let response = try await lspInstance.documentSymbol(documentSymbolParams) diff --git a/CodeEdit/Features/LSP/LanguageClient+DocumentUtil.swift b/CodeEdit/Features/LSP/LanguageClient+DocumentUtil.swift index 164bae026a..6926f2aea8 100644 --- a/CodeEdit/Features/LSP/LanguageClient+DocumentUtil.swift +++ b/CodeEdit/Features/LSP/LanguageClient+DocumentUtil.swift @@ -23,10 +23,10 @@ extension LanguageServer { // TODO: LOGGING print("addDocument: An error occurred: \(error)") } - + return false } - + /// Adds a TextDocumentItem to the tracked files and notifies the language server mutating func addDocument(_ document: TextDocumentItem) async -> Bool { do { @@ -41,14 +41,14 @@ extension LanguageServer { // TODO: LOGGING print("addDocument: An error occurred: \(error)") } - + return false } /// Stops tracking a file and notifies the language server mutating func closeDocument(_ uri: String) async -> Bool { guard let document = trackedDocuments.removeValue(forKey: uri) else { return false } - + do { let params = DidCloseTextDocumentParams(textDocument: TextDocumentIdentifier(uri: document.uri)) @@ -66,7 +66,12 @@ extension LanguageServer { /// - uri: The URI of the document to update. /// - newText: The new text to be set for the document. /// - Returns: `true` if the document was successfully updated, `false` - mutating func updateDocument(withUri uri: String, newText: String, range: LSPRange, rangeLength: Int) async -> Bool { + mutating func updateDocument( + withUri uri: String, + newText: String, + range: LSPRange, + rangeLength: Int + ) async -> Bool { // Update the document objects values, including the version guard let currentDocument = trackedDocuments[uri], let nsRange = convertLSPRangeToNSRange(range, in: currentDocument.text), @@ -79,20 +84,25 @@ extension LanguageServer { var updatedText = currentDocument.text updatedText.replaceSubrange(stringRange, with: newText) let updatedVersion = currentDocument.version + 1 - let updatedDocument = TextDocumentItem(uri: currentDocument.uri, - languageId: currentDocument.languageId, - version: updatedVersion, - text: updatedText) + let updatedDocument = TextDocumentItem( + uri: currentDocument.uri, + languageId: currentDocument.languageId, + version: updatedVersion, + text: updatedText + ) trackedDocuments[uri] = updatedDocument // Notify the server do { - let change = TextDocumentContentChangeEvent(range: range, - rangeLength: rangeLength, - text: newText) - let params = DidChangeTextDocumentParams(textDocument: VersionedTextDocumentIdentifier(uri: uri, - version: updatedVersion), - contentChanges: [change]) + let change = TextDocumentContentChangeEvent( + range: range, + rangeLength: rangeLength, + text: newText + ) + let params = DidChangeTextDocumentParams( + textDocument: VersionedTextDocumentIdentifier(uri: uri, version: updatedVersion), + contentChanges: [change] + ) try await lspInstance.textDocumentDidChange(params) } catch { // TODO: LOGGING @@ -120,10 +130,18 @@ private func applyEditsToDocument(document: TextDocumentItem, edits: [TextEdit]) updatedText.replaceSubrange(range, with: edit.newText) } - return TextDocumentItem(uri: document.uri, languageId: document.languageId, version: document.version, text: updatedText) + return TextDocumentItem( + uri: document.uri, + languageId: document.languageId, + version: document.version, + text: updatedText + ) } -private func updateDocumentWithChanges(document: TextDocumentItem, changes: [TextDocumentContentChangeEvent]) -> TextDocumentItem { +private func updateDocumentWithChanges( + document: TextDocumentItem, + changes: [TextDocumentContentChangeEvent] +) -> TextDocumentItem { var updatedText = document.text for change in changes { @@ -138,7 +156,12 @@ private func updateDocumentWithChanges(document: TextDocumentItem, changes: [Tex } } - return TextDocumentItem(uri: document.uri, languageId: document.languageId, version: document.version, text: updatedText) + return TextDocumentItem( + uri: document.uri, + languageId: document.languageId, + version: document.version, + text: updatedText + ) } private func convertLSPRangeToNSRange(_ range: LSPRange, in text: String) -> NSRange? { diff --git a/CodeEdit/Features/LSP/LanguageClient+Formatting.swift b/CodeEdit/Features/LSP/LanguageClient+Formatting.swift index 4233ee26c9..2d9725e480 100644 --- a/CodeEdit/Features/LSP/LanguageClient+Formatting.swift +++ b/CodeEdit/Features/LSP/LanguageClient+Formatting.swift @@ -11,21 +11,26 @@ import LanguageServerProtocol // TODO: LOGGING extension LanguageServer { - func requestFormatting(document documentURI: String, - withFormat formattingOptions: FormattingOptions + func requestFormatting( + document documentURI: String, + withFormat formattingOptions: FormattingOptions ) async -> FormattingResult { do { - let params = DocumentFormattingParams(textDocument: TextDocumentIdentifier(uri: documentURI), options: formattingOptions) + let params = DocumentFormattingParams( + textDocument: TextDocumentIdentifier(uri: documentURI), + options: formattingOptions + ) return try await lspInstance.formatting(params) } catch { print("requestFormatting Error \(error)") } return [] } - - func requestRangeFormatting(document documentURI: String, - _ range: LSPRange, - withFormat formattingOptions: FormattingOptions + + func requestRangeFormatting( + document documentURI: String, + _ range: LSPRange, + withFormat formattingOptions: FormattingOptions ) async -> FormattingResult { do { let params = DocumentRangeFormattingParams( @@ -39,11 +44,12 @@ extension LanguageServer { } return [] } - - func requestOnTypeFormatting(document documentURI: String, - _ position: Position, - character ch: String, - withFormat formattingOptions: FormattingOptions + + func requestOnTypeFormatting( + document documentURI: String, + _ position: Position, + character ch: String, + withFormat formattingOptions: FormattingOptions ) async -> FormattingResult { do { let params = DocumentOnTypeFormattingParams( diff --git a/CodeEdit/Features/LSP/LanguageClient+References.swift b/CodeEdit/Features/LSP/LanguageClient+References.swift index cce116a0d7..47aaab063b 100644 --- a/CodeEdit/Features/LSP/LanguageClient+References.swift +++ b/CodeEdit/Features/LSP/LanguageClient+References.swift @@ -10,7 +10,11 @@ import LanguageServerProtocol extension LanguageServer { /// Resolve project-wide references for the symbol denoted by the given text document position - func requestFindReferences(document documentURI: String, _ position: Position, _ includeDeclaration: Bool = false) async -> ReferenceResponse { + func requestFindReferences( + document documentURI: String, + _ position: Position, + _ includeDeclaration: Bool = false + ) async -> ReferenceResponse { do { let params = ReferenceParams( textDocument: TextDocumentIdentifier(uri: documentURI), diff --git a/CodeEdit/Features/LSP/LanguageClient+Rename.swift b/CodeEdit/Features/LSP/LanguageClient+Rename.swift index 55ee06ea3e..fd588b5cb2 100644 --- a/CodeEdit/Features/LSP/LanguageClient+Rename.swift +++ b/CodeEdit/Features/LSP/LanguageClient+Rename.swift @@ -22,9 +22,13 @@ extension LanguageServer { } return nil } - + /// Ask the server to compute a workspace change so that the client can perform a workspace-wide rename of a symbol - func requestRename(document documentURI: String, _ position: Position, newName name: String) async -> RenameResponse { + func requestRename( + document documentURI: String, + _ position: Position, + newName name: String + ) async -> RenameResponse { do { let params = RenameParams( textDocument: TextDocumentIdentifier(uri: documentURI), diff --git a/CodeEdit/Features/LSP/LanguageClient+SemanticTokens.swift b/CodeEdit/Features/LSP/LanguageClient+SemanticTokens.swift index 6a67f1f597..4918699474 100644 --- a/CodeEdit/Features/LSP/LanguageClient+SemanticTokens.swift +++ b/CodeEdit/Features/LSP/LanguageClient+SemanticTokens.swift @@ -21,7 +21,7 @@ extension LanguageServer { } return nil } - + func requestSemanticTokensRange(document documentURI: String, _ range: LSPRange) async -> SemanticTokensResponse { do { let params = SemanticTokensRangeParams(textDocument: TextDocumentIdentifier(uri: documentURI), range: range) @@ -31,10 +31,16 @@ extension LanguageServer { } return nil } - - func requestSemanticTokensFullDelta(document documentURI: String, _ previousResultId: String) async -> SemanticTokensDeltaResponse { + + func requestSemanticTokensFullDelta( + document documentURI: String, + _ previousResultId: String + ) async -> SemanticTokensDeltaResponse { do { - let params = SemanticTokensDeltaParams(textDocument: TextDocumentIdentifier(uri: documentURI), previousResultId: previousResultId) + let params = SemanticTokensDeltaParams( + textDocument: TextDocumentIdentifier(uri: documentURI), + previousResultId: previousResultId + ) return try await lspInstance.semanticTokensFullDelta(params) } catch { print("requestInlayHint Error \(error)") diff --git a/CodeEdit/Features/LSP/LanguageConfiguration.swift b/CodeEdit/Features/LSP/LanguageConfiguration.swift index 86a2dbdc86..fd9f8a3d96 100644 --- a/CodeEdit/Features/LSP/LanguageConfiguration.swift +++ b/CodeEdit/Features/LSP/LanguageConfiguration.swift @@ -13,12 +13,19 @@ func loadLSPConfigurations(from configFile: URL?) -> [LanguageIdentifier: Langua return [ .python: LanguageServerBinary( execPath: "/opt/homebrew/Cellar/python-lsp-server/1.10.0/libexec/bin/pylsp", - args: ["--log-file", "/Users/abe/Documents/Swift/CodeEditLSPExample/CodeEditLSPExample/LSP_Logs/python.log"], + args: [ + "--log-file", + "/Users/abe/Documents/Swift/CodeEditLSPExample/CodeEditLSPExample/LSP_Logs/python.log" + ], env: ProcessInfo.processInfo.environment ), .rust: LanguageServerBinary( execPath: "/Users/abe/.vscode/extensions/rust-lang.rust-analyzer-0.3.1823-darwin-arm64/server/rust-analyzer", - args: ["--verbose", "--log-file", "/Users/abe/Documents/Swift/CodeEditLSPExample/CodeEditLSPExample/LSP_Logs/rust.log"], + args: [ + "--verbose", + "--log-file", + "/Users/abe/Documents/Swift/CodeEditLSPExample/CodeEditLSPExample/LSP_Logs/rust.log" + ], env: ProcessInfo.processInfo.environment // ["RUST_BACKTRACE": "full"] ) ] diff --git a/CodeEdit/Features/LSP/LanguageServer.swift b/CodeEdit/Features/LSP/LanguageServer.swift index f11c4def63..f71cd3a416 100644 --- a/CodeEdit/Features/LSP/LanguageServer.swift +++ b/CodeEdit/Features/LSP/LanguageServer.swift @@ -23,7 +23,12 @@ struct LanguageServer { private(set) var lspInstance: InitializingServer private(set) var rootPath: URL - static func createServer(for languageId: LanguageIdentifier, with binary: LanguageServerBinary, rootPath: URL, workspaceFolders: [WorkspaceFolder]?) throws -> Self { + static func createServer( + for languageId: LanguageIdentifier, + with binary: LanguageServerBinary, + rootPath: URL, + workspaceFolders: [WorkspaceFolder]? + ) throws -> Self { let executionParams = Process.ExecutionParameters( path: binary.execPath, arguments: binary.args, @@ -43,14 +48,22 @@ struct LanguageServer { throw error } guard let channel = channel else { - throw NSError(domain: "LanguageClient", code: 1, userInfo: [NSLocalizedDescriptionKey: "Failed to start server for language \(languageId.rawValue)"]) + throw NSError( + domain: "LanguageClient", + code: 1, + userInfo: [NSLocalizedDescriptionKey: "Failed to start server for language \(languageId.rawValue)"] + ) } let localServer = LanguageServerProtocol.JSONRPCServerConnection(dataChannel: channel) - let server = InitializingServer(server: localServer, initializeParamsProvider: getInitParams(projectURL: rootPath)) + let server = InitializingServer( + server: localServer, + initializeParamsProvider: getInitParams(projectURL: rootPath) + ) return LanguageServer(languageId: languageId, binary: binary, lspInstance: server, rootPath: rootPath) } + // swiftlint:disable function_body_length line_length private static func getInitParams(projectURL: URL) -> InitializingServer.InitializeParamsProvider { let provider: InitializingServer.InitializeParamsProvider = { // Text Document Capabilities @@ -92,14 +105,19 @@ struct LanguageServer { ) // Workspace Capabilities - // TODO: ADD inlineValue?: InlineValueWorkspaceClientCapabilities; inlayHint?: InlayHintWorkspaceClientCapabilities; diagnostics?: DiagnosticWorkspaceClientCapabilities; + // TODO: ADD inlineValue?: InlineValueWorkspaceClientCapabilities;inlayHint?: InlayHintWorkspaceClientCapabilities; diagnostics?: DiagnosticWorkspaceClientCapabilities; let workspaceCapabilities = ClientCapabilities.Workspace( applyEdit: true, workspaceEdit: nil, didChangeConfiguration: DidChangeConfigurationClientCapabilities(dynamicRegistration: true), // TODO: NEED TO ADD https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workspace_didChangeWatchedFiles `relativePatternSupport` VARIABLE didChangeWatchedFiles: DidChangeWatchedFilesClientCapabilities(dynamicRegistration: true), - symbol: WorkspaceSymbolClientCapabilities(dynamicRegistration: true, symbolKind: nil, tagSupport: nil, resolveSupport: []), + symbol: WorkspaceSymbolClientCapabilities( + dynamicRegistration: true, + symbolKind: nil, + tagSupport: nil, + resolveSupport: [] + ), executeCommand: nil, workspaceFolders: true, configuration: true, @@ -128,14 +146,17 @@ struct LanguageServer { ) } return provider + // swiftlint:enable function_body_length line_length } + /// Initializes the language server if it hasn't been initialized already. public func initialize() async throws { // TODO: CATCH ERROR HERE, LOG ERROR OR SUCCESS // InitializationResponse is not returned because it is automatically stored inside `lspInstance` _ = try await lspInstance.initializeIfNeeded() } + /// Shuts down the language server and exits it. public func shutdown() async throws { try await lspInstance.shutdownAndExit() } diff --git a/CodeEdit/Features/NavigatorArea/ProjectNavigator/OutlineView/ProjectNavigatorViewController.swift b/CodeEdit/Features/NavigatorArea/ProjectNavigator/OutlineView/ProjectNavigatorViewController.swift index a3af839200..b89aaaf360 100644 --- a/CodeEdit/Features/NavigatorArea/ProjectNavigator/OutlineView/ProjectNavigatorViewController.swift +++ b/CodeEdit/Features/NavigatorArea/ProjectNavigator/OutlineView/ProjectNavigatorViewController.swift @@ -276,26 +276,18 @@ extension ProjectNavigatorViewController: NSOutlineViewDelegate { } func outlineViewSelectionDidChange(_ notification: Notification) { - print("Trying to open by outlineViewSelectionDidChange") guard let outlineView = notification.object as? NSOutlineView else { - print("Cant find outline view") return } let selectedIndex = outlineView.selectedRow - guard let item = outlineView.item(atRow: selectedIndex) as? CEWorkspaceFile else { - print("Cant find item in outline view") - return - } + guard let item = outlineView.item(atRow: selectedIndex) as? CEWorkspaceFile else { return } if !item.isFolder && shouldSendSelectionUpdate { - print("Sending update in outlineViewSelectionDidChange") DispatchQueue.main.async { self.workspace?.editorManager.activeEditor.openTab(file: item, asTemporary: true) } - } else { - print("Didnt send update in outlineViewSelectionDidChange [!item.isFolder]=\(!item.isFolder) shouldSendSelectionUpdate=\(shouldSendSelectionUpdate)") } } From cf354172d301c1cbf9de59adefccc34013d0f2f1 Mon Sep 17 00:00:00 2001 From: Abe M Date: Sun, 2 Jun 2024 18:32:05 -0700 Subject: [PATCH 05/20] Lint fix --- CodeEdit/Features/LSP/LanguageClient+Formatting.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CodeEdit/Features/LSP/LanguageClient+Formatting.swift b/CodeEdit/Features/LSP/LanguageClient+Formatting.swift index 2d9725e480..c4ced5c0f8 100644 --- a/CodeEdit/Features/LSP/LanguageClient+Formatting.swift +++ b/CodeEdit/Features/LSP/LanguageClient+Formatting.swift @@ -47,15 +47,15 @@ extension LanguageServer { func requestOnTypeFormatting( document documentURI: String, - _ position: Position, - character ch: String, - withFormat formattingOptions: FormattingOptions + _ position: Position, + character char: String, + withFormat formattingOptions: FormattingOptions ) async -> FormattingResult { do { let params = DocumentOnTypeFormattingParams( textDocument: TextDocumentIdentifier(uri: documentURI), position: position, - ch: ch, + ch: char, options: formattingOptions ) return try await lspInstance.onTypeFormatting(params) From 89a75ed3bc1ed176846ab0a8f4207bfd98aa33d1 Mon Sep 17 00:00:00 2001 From: Abe M Date: Sun, 2 Jun 2024 18:34:17 -0700 Subject: [PATCH 06/20] Lint fix --- CodeEdit/Features/LSP/LanguageConfiguration.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CodeEdit/Features/LSP/LanguageConfiguration.swift b/CodeEdit/Features/LSP/LanguageConfiguration.swift index fd9f8a3d96..00151895b4 100644 --- a/CodeEdit/Features/LSP/LanguageConfiguration.swift +++ b/CodeEdit/Features/LSP/LanguageConfiguration.swift @@ -9,6 +9,8 @@ import Foundation import LanguageServerProtocol func loadLSPConfigurations(from configFile: URL?) -> [LanguageIdentifier: LanguageServerBinary] { + // TEMP: This is in a variable to avoid lint error + let rustPath = "/Users/abe/.vscode/extensions/rust-lang.rust-analyzer-0.3.1823-darwin-arm64/server/rust-analyzer" // TODO: LOAD FROM FILE return [ .python: LanguageServerBinary( @@ -20,7 +22,7 @@ func loadLSPConfigurations(from configFile: URL?) -> [LanguageIdentifier: Langua env: ProcessInfo.processInfo.environment ), .rust: LanguageServerBinary( - execPath: "/Users/abe/.vscode/extensions/rust-lang.rust-analyzer-0.3.1823-darwin-arm64/server/rust-analyzer", + execPath: rustPath, args: [ "--verbose", "--log-file", From 4f65928128226d0e10c5a2d0580460d7cbc0e010 Mon Sep 17 00:00:00 2001 From: Abe M Date: Thu, 6 Jun 2024 18:43:22 -0700 Subject: [PATCH 07/20] New cache, more documentation, fixes, setup LSP service --- .swiftlint.yml | 1 + CodeEdit.xcodeproj/project.pbxproj | 58 ++++---- .../xcshareddata/swiftpm/Package.resolved | 11 +- CodeEdit/AppDelegate.swift | 9 +- .../Documents/WorkspaceDocument.swift | 2 +- CodeEdit/Features/LSP/LSPCache.swift | 96 +++++------- CodeEdit/Features/LSP/LSPEventHandler.swift | 87 +++++++++++ ...geServerManager.swift => LSPService.swift} | 140 +++++++++--------- .../LanguageClient+CallHierarchy.swift | 9 +- .../LanguageClient+CodeLens.swift | 0 .../LanguageClient+ColorPresentation.swift | 0 .../LanguageClient+Completion.swift | 6 +- .../LanguageClient+Declaration.swift | 0 .../LanguageClient+Definition.swift | 0 .../LanguageClient+Diagnostics.swift | 0 .../LanguageClient+DocumentColor.swift | 0 .../LanguageClient+DocumentHighlight.swift | 0 .../LanguageClient+DocumentLink.swift | 0 .../LanguageClient+DocumentSymbol.swift | 10 +- .../LanguageClient+DocumentUtil.swift | 12 +- .../LanguageClient+FoldingRange.swift | 0 .../LanguageClient+Formatting.swift | 0 .../LanguageClient+Hover.swift | 0 .../LanguageClient+Implementation.swift | 0 .../LanguageClient+InlayHint.swift | 0 .../LanguageClient+References.swift | 0 .../LanguageClient+Rename.swift | 1 - .../LanguageClient+SelectionRange.swift | 0 .../LanguageClient+SemanticTokens.swift | 0 .../LanguageClient+SignatureHelp.swift | 0 .../LanguageClient+TypeDefinition.swift | 0 CodeEdit/Features/LSP/LanguageServer.swift | 30 ++-- .../ProjectNavigatorViewController.swift | 1 - 33 files changed, 254 insertions(+), 219 deletions(-) create mode 100644 CodeEdit/Features/LSP/LSPEventHandler.swift rename CodeEdit/Features/LSP/{LanguageServerManager.swift => LSPService.swift} (53%) rename CodeEdit/Features/LSP/{ => LanguageClient}/LanguageClient+CallHierarchy.swift (87%) rename CodeEdit/Features/LSP/{ => LanguageClient}/LanguageClient+CodeLens.swift (100%) rename CodeEdit/Features/LSP/{ => LanguageClient}/LanguageClient+ColorPresentation.swift (100%) rename CodeEdit/Features/LSP/{ => LanguageClient}/LanguageClient+Completion.swift (84%) rename CodeEdit/Features/LSP/{ => LanguageClient}/LanguageClient+Declaration.swift (100%) rename CodeEdit/Features/LSP/{ => LanguageClient}/LanguageClient+Definition.swift (100%) rename CodeEdit/Features/LSP/{ => LanguageClient}/LanguageClient+Diagnostics.swift (100%) rename CodeEdit/Features/LSP/{ => LanguageClient}/LanguageClient+DocumentColor.swift (100%) rename CodeEdit/Features/LSP/{ => LanguageClient}/LanguageClient+DocumentHighlight.swift (100%) rename CodeEdit/Features/LSP/{ => LanguageClient}/LanguageClient+DocumentLink.swift (100%) rename CodeEdit/Features/LSP/{ => LanguageClient}/LanguageClient+DocumentSymbol.swift (57%) rename CodeEdit/Features/LSP/{ => LanguageClient}/LanguageClient+DocumentUtil.swift (94%) rename CodeEdit/Features/LSP/{ => LanguageClient}/LanguageClient+FoldingRange.swift (100%) rename CodeEdit/Features/LSP/{ => LanguageClient}/LanguageClient+Formatting.swift (100%) rename CodeEdit/Features/LSP/{ => LanguageClient}/LanguageClient+Hover.swift (100%) rename CodeEdit/Features/LSP/{ => LanguageClient}/LanguageClient+Implementation.swift (100%) rename CodeEdit/Features/LSP/{ => LanguageClient}/LanguageClient+InlayHint.swift (100%) rename CodeEdit/Features/LSP/{ => LanguageClient}/LanguageClient+References.swift (100%) rename CodeEdit/Features/LSP/{ => LanguageClient}/LanguageClient+Rename.swift (98%) rename CodeEdit/Features/LSP/{ => LanguageClient}/LanguageClient+SelectionRange.swift (100%) rename CodeEdit/Features/LSP/{ => LanguageClient}/LanguageClient+SemanticTokens.swift (100%) rename CodeEdit/Features/LSP/{ => LanguageClient}/LanguageClient+SignatureHelp.swift (100%) rename CodeEdit/Features/LSP/{ => LanguageClient}/LanguageClient+TypeDefinition.swift (100%) diff --git a/.swiftlint.yml b/.swiftlint.yml index 22f7378f67..882417f7d5 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -8,6 +8,7 @@ type_name: - ID identifier_name: + allowed_symbols: ["$", "_"] excluded: - id - vc diff --git a/CodeEdit.xcodeproj/project.pbxproj b/CodeEdit.xcodeproj/project.pbxproj index 1b5b238232..512beb56b3 100644 --- a/CodeEdit.xcodeproj/project.pbxproj +++ b/CodeEdit.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 55; + objectVersion = 60; objects = { /* Begin PBXBuildFile section */ @@ -64,7 +64,6 @@ 3000516A2BBD3A8200A98562 /* ServiceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 300051692BBD3A8200A98562 /* ServiceType.swift */; }; 3000516C2BBD3A9500A98562 /* ServiceWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3000516B2BBD3A9500A98562 /* ServiceWrapper.swift */; }; 3026F50F2AC006C80061227E /* InspectorAreaViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3026F50E2AC006C80061227E /* InspectorAreaViewModel.swift */; }; - 3083B3612C0A8C8F00C6642C /* CodeEditKit in Frameworks */ = {isa = PBXBuildFile; productRef = 6C0F3A3B2A1D0D5000223D19 /* CodeEditKit */; }; 30AB4EBB2BF718A100ED4431 /* DeveloperSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30AB4EBA2BF718A100ED4431 /* DeveloperSettings.swift */; }; 30AB4EBD2BF71CA800ED4431 /* DeveloperSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30AB4EBC2BF71CA800ED4431 /* DeveloperSettingsView.swift */; }; 30AB4EC22BF7253200ED4431 /* KeyValueTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30AB4EC12BF7253200ED4431 /* KeyValueTable.swift */; }; @@ -93,9 +92,10 @@ 30B088122C0D53080063A882 /* LanguageClient+TypeDefinition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F52C0D53080063A882 /* LanguageClient+TypeDefinition.swift */; }; 30B088132C0D53080063A882 /* LanguageConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F62C0D53080063A882 /* LanguageConfiguration.swift */; }; 30B088142C0D53080063A882 /* LanguageServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F72C0D53080063A882 /* LanguageServer.swift */; }; - 30B088152C0D53080063A882 /* LanguageServerManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F82C0D53080063A882 /* LanguageServerManager.swift */; }; + 30B088152C0D53080063A882 /* LSPService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F82C0D53080063A882 /* LSPService.swift */; }; 30B088162C0D53080063A882 /* LSPCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F92C0D53080063A882 /* LSPCache.swift */; }; 30B088172C0D53080063A882 /* LSPUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087FA2C0D53080063A882 /* LSPUtil.swift */; }; + 30CB648D2C12680F00CC8A9E /* LSPEventHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30CB648C2C12680F00CC8A9E /* LSPEventHandler.swift */; }; 30E6D0012A6E505200A58B20 /* NavigatorSidebarViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30E6D0002A6E505200A58B20 /* NavigatorSidebarViewModel.swift */; }; 3E0196732A3921AC002648D8 /* codeedit_shell_integration.zsh in Resources */ = {isa = PBXBuildFile; fileRef = 3E0196722A3921AC002648D8 /* codeedit_shell_integration.zsh */; }; 3E01967A2A392B45002648D8 /* codeedit_shell_integration.bash in Resources */ = {isa = PBXBuildFile; fileRef = 3E0196792A392B45002648D8 /* codeedit_shell_integration.bash */; }; @@ -693,9 +693,10 @@ 30B087F52C0D53080063A882 /* LanguageClient+TypeDefinition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+TypeDefinition.swift"; sourceTree = ""; }; 30B087F62C0D53080063A882 /* LanguageConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LanguageConfiguration.swift; sourceTree = ""; }; 30B087F72C0D53080063A882 /* LanguageServer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LanguageServer.swift; sourceTree = ""; }; - 30B087F82C0D53080063A882 /* LanguageServerManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LanguageServerManager.swift; sourceTree = ""; }; + 30B087F82C0D53080063A882 /* LSPService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LSPService.swift; sourceTree = ""; }; 30B087F92C0D53080063A882 /* LSPCache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LSPCache.swift; sourceTree = ""; }; 30B087FA2C0D53080063A882 /* LSPUtil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LSPUtil.swift; sourceTree = ""; }; + 30CB648C2C12680F00CC8A9E /* LSPEventHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LSPEventHandler.swift; sourceTree = ""; }; 30E6D0002A6E505200A58B20 /* NavigatorSidebarViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigatorSidebarViewModel.swift; sourceTree = ""; }; 3E0196722A3921AC002648D8 /* codeedit_shell_integration.zsh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = codeedit_shell_integration.zsh; sourceTree = ""; }; 3E0196792A392B45002648D8 /* codeedit_shell_integration.bash */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = codeedit_shell_integration.bash; sourceTree = ""; }; @@ -1147,7 +1148,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 3083B3612C0A8C8F00C6642C /* CodeEditKit in Frameworks */, 6C66C31329D05CDC00DE9ED2 /* GRDB in Frameworks */, 58F2EB1E292FB954004A9BDE /* Sparkle in Frameworks */, 6CBE1D002B720565003AC32E /* CodeEditSourceEditor in Frameworks */, @@ -1410,6 +1410,20 @@ sourceTree = ""; }; 30B087FB2C0D53080063A882 /* LSP */ = { + isa = PBXGroup; + children = ( + 30B0881E2C12626B0063A882 /* LanguageClient */, + 30B087F72C0D53080063A882 /* LanguageServer.swift */, + 30B087F62C0D53080063A882 /* LanguageConfiguration.swift */, + 30B087F82C0D53080063A882 /* LSPService.swift */, + 30B087F92C0D53080063A882 /* LSPCache.swift */, + 30B087FA2C0D53080063A882 /* LSPUtil.swift */, + 30CB648C2C12680F00CC8A9E /* LSPEventHandler.swift */, + ); + path = LSP; + sourceTree = ""; + }; + 30B0881E2C12626B0063A882 /* LanguageClient */ = { isa = PBXGroup; children = ( 30B087DF2C0D53080063A882 /* LanguageClient+CallHierarchy.swift */, @@ -1435,13 +1449,8 @@ 30B087F32C0D53080063A882 /* LanguageClient+SemanticTokens.swift */, 30B087F42C0D53080063A882 /* LanguageClient+SignatureHelp.swift */, 30B087F52C0D53080063A882 /* LanguageClient+TypeDefinition.swift */, - 30B087F62C0D53080063A882 /* LanguageConfiguration.swift */, - 30B087F72C0D53080063A882 /* LanguageServer.swift */, - 30B087F82C0D53080063A882 /* LanguageServerManager.swift */, - 30B087F92C0D53080063A882 /* LSPCache.swift */, - 30B087FA2C0D53080063A882 /* LSPUtil.swift */, ); - path = LSP; + path = LanguageClient; sourceTree = ""; }; 3E0196712A392170002648D8 /* ShellIntegration */ = { @@ -3193,7 +3202,6 @@ 6C6BD6F729CD14D100235D17 /* CodeEditKit */, 6C66C31229D05CDC00DE9ED2 /* GRDB */, 6CDEFC9529E22C2700B7C684 /* Introspect */, - 6C0F3A3B2A1D0D5000223D19 /* CodeEditKit */, 6CB4463F2B6DFF3A00539ED0 /* CodeEditSourceEditor */, 6CBE1CFF2B720565003AC32E /* CodeEditSourceEditor */, 6C0617D52BDB4432008C9C42 /* LogStream */, @@ -3289,11 +3297,11 @@ 6C6BD6F229CD142C00235D17 /* XCRemoteSwiftPackageReference "collectionconcurrencykit" */, 6C66C31129D05CC800DE9ED2 /* XCRemoteSwiftPackageReference "GRDB.swift" */, 6CDEFC9429E22C2700B7C684 /* XCRemoteSwiftPackageReference "SwiftUI-Introspect" */, - 6C0F3A3A2A1D0D5000223D19 /* XCRemoteSwiftPackageReference "CodeEditKit" */, 6CBE1CFE2B720565003AC32E /* XCRemoteSwiftPackageReference "CodeEditSourceEditor" */, 6C0617D42BDB4432008C9C42 /* XCRemoteSwiftPackageReference "LogStream" */, 3083B3892C0BEEE300C6642C /* XCRemoteSwiftPackageReference "LanguageServerProtocol" */, 3083B38A2C0BEEFF00C6642C /* XCRemoteSwiftPackageReference "LanguageClient" */, + 30B0881D2C1261F80063A882 /* XCLocalSwiftPackageReference "../CodeEditKit" */, ); productRefGroup = B658FB2D27DA9E0F00EA4DBD /* Products */; projectDirPath = ""; @@ -3461,7 +3469,7 @@ 587B9E7729301D8F00AC7927 /* String+PercentEncoding.swift in Sources */, 587B9E5B29301D8F00AC7927 /* GitCheckoutBranchView.swift in Sources */, 2813F93827ECC4AA00E305E4 /* FindNavigatorResultList.swift in Sources */, - 30B088152C0D53080063A882 /* LanguageServerManager.swift in Sources */, + 30B088152C0D53080063A882 /* LSPService.swift in Sources */, 613899B92B6E704500A5CAF6 /* String+Normalise.swift in Sources */, 30B088002C0D53080063A882 /* LanguageClient+Declaration.swift in Sources */, 04BA7C192AE2D7C600584E1C /* GitClient+Branches.swift in Sources */, @@ -3532,6 +3540,7 @@ 6C2C156129B4F52F00EA60A5 /* SplitViewModifiers.swift in Sources */, 61A53A812B4449F00093BF8A /* WorkspaceDocument+Index.swift in Sources */, 66AF6CE22BF17CC300D83C9D /* StatusBarViewModel.swift in Sources */, + 30CB648D2C12680F00CC8A9E /* LSPEventHandler.swift in Sources */, 201169DD2837B3AC00F92B46 /* SourceControlNavigatorToolbarBottom.swift in Sources */, 587B9E8B29301D8F00AC7927 /* GitHubAccount+deleteReference.swift in Sources */, 58798237292E30B90085B254 /* FeedbackView.swift in Sources */, @@ -4743,6 +4752,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = CodeEdit/CodeEdit.entitlements; CODE_SIGN_IDENTITY = "-"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; DEAD_CODE_STRIPPING = YES; @@ -4987,6 +4997,13 @@ }; /* End XCConfigurationList section */ +/* Begin XCLocalSwiftPackageReference section */ + 30B0881D2C1261F80063A882 /* XCLocalSwiftPackageReference "../CodeEditKit" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = ../CodeEditKit; + }; +/* End XCLocalSwiftPackageReference section */ + /* Begin XCRemoteSwiftPackageReference section */ 2816F592280CF50500DD548B /* XCRemoteSwiftPackageReference "CodeEditSymbols" */ = { isa = XCRemoteSwiftPackageReference; @@ -5052,14 +5069,6 @@ minimumVersion = 1.3.0; }; }; - 6C0F3A3A2A1D0D5000223D19 /* XCRemoteSwiftPackageReference "CodeEditKit" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/CodeEditApp/CodeEditKit"; - requirement = { - kind = exactVersion; - version = 0.1.1; - }; - }; 6C147C4329A329350089B630 /* XCRemoteSwiftPackageReference "swift-collections" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/apple/swift-collections.git"; @@ -5128,11 +5137,6 @@ package = 6C0617D42BDB4432008C9C42 /* XCRemoteSwiftPackageReference "LogStream" */; productName = LogStream; }; - 6C0F3A3B2A1D0D5000223D19 /* CodeEditKit */ = { - isa = XCSwiftPackageProductDependency; - package = 6C0F3A3A2A1D0D5000223D19 /* XCRemoteSwiftPackageReference "CodeEditKit" */; - productName = CodeEditKit; - }; 6C147C4429A329350089B630 /* OrderedCollections */ = { isa = XCSwiftPackageProductDependency; package = 6C147C4329A329350089B630 /* XCRemoteSwiftPackageReference "swift-collections" */; diff --git a/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index b3ce990a2c..9cb51d677a 100644 --- a/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "9c699d730017e749c2b945e8435c6edd8169fe23742cc8fd8a58078ae48764ac", + "originHash" : "2fa7c60efc338d0f03199598f0092f98e50b91e5117f3b0f4ed3dbb35f45b701", "pins" : [ { "identity" : "anycodable", @@ -10,15 +10,6 @@ "version" : "0.6.7" } }, - { - "identity" : "codeeditkit", - "kind" : "remoteSourceControl", - "location" : "https://github.com/CodeEditApp/CodeEditKit", - "state" : { - "revision" : "bf76c0240589a38b504a703363ab85fcedfbc732", - "version" : "0.1.1" - } - }, { "identity" : "codeeditlanguages", "kind" : "remoteSourceControl", diff --git a/CodeEdit/AppDelegate.swift b/CodeEdit/AppDelegate.swift index eebf250e73..750b39293e 100644 --- a/CodeEdit/AppDelegate.swift +++ b/CodeEdit/AppDelegate.swift @@ -6,8 +6,8 @@ // import SwiftUI -import CodeEditSourceEditor import CodeEditSymbols +import CodeEditSourceEditor final class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject { private let updater = SoftwareUpdater() @@ -234,10 +234,9 @@ final class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject { /// Setup all the services into a ServiceContainer for the application to use. private func setupServiceContainer() { - // Example for how services will be instantiated -// ServiceContainer.register( -// PasteboardService() -// ) + ServiceContainer.register( + LSPService() + ) } extension AppDelegate { diff --git a/CodeEdit/Features/Documents/WorkspaceDocument.swift b/CodeEdit/Features/Documents/WorkspaceDocument.swift index 4d8bce3ce2..beba679b8f 100644 --- a/CodeEdit/Features/Documents/WorkspaceDocument.swift +++ b/CodeEdit/Features/Documents/WorkspaceDocument.swift @@ -115,7 +115,7 @@ final class WorkspaceDocument: NSDocument, ObservableObject, NSToolbarDelegate { ) self.lspManager = LanguageServerManager() - // TODO: ACTIVATION EVENTS HERE + // TODO: ACTIVATION EVENTS HERE, WHEN EXTENSIONS ARE AVAILABLE Task { try await self.lspManager?.startServer( for: .python, diff --git a/CodeEdit/Features/LSP/LSPCache.swift b/CodeEdit/Features/LSP/LSPCache.swift index f01ed6d803..9c88c778ea 100644 --- a/CodeEdit/Features/LSP/LSPCache.swift +++ b/CodeEdit/Features/LSP/LSPCache.swift @@ -7,86 +7,56 @@ import Foundation -struct CacheKey: Hashable { +struct CacheKey: Hashable { let uri: String let requestType: String -} - -// TODO: SWITCH TO DOUBLY LINK LIST + let extraData: ExtraData? -/// Thread safe implementation for caching LSP requests with time based expiration and cache size limits. -class LSPCache { - /// Represents a single cache entry with a generic type and an expiration date. - private struct CacheEntry { - let value: T - let expirationDate: Date + init(uri: String, requestType: String, extraData: ExtraData? = nil) { + self.uri = uri + self.requestType = requestType + self.extraData = extraData } +} - /// The main cache storage mapping a `CacheKey` to a generic value. - private var cache = [CacheKey: Any]() - /// A collection of locks, one per cache key, for thread-safe access to cache entries. - /// `DispatchQueue` is used for synchronization to ensure that cache operations are thread-safe. - private var locks = [CacheKey: DispatchQueue]() - /// The maximum number of entries that the cache can hold. - private var cacheSizeLimit: Int - /// Tracks the order of cache keys for potential eviction. - private var cacheEntriesOrder: [CacheKey] = [] - /// Queue for handling the eviction of old cache entries. Separated from main cache operations to not block them. - private let evictionQueue = DispatchQueue(label: "com.CodeEdit.LSPCache.evictionQueue") - - init(cacheSizeLimit: Int = 100) { - self.cacheSizeLimit = cacheSizeLimit - } +final class LSPCache { + /// Represents a single cache entry with a generic type. + final class CacheEntry: NSObject { + let value: T - private func lock(for key: CacheKey) -> DispatchQueue { - if let lock = locks[key] { - return lock - } else { - let newLock = DispatchQueue(label: "com.CodeEdit.LSPCache.lock.\(key)") - locks[key] = newLock - return newLock + init(_ value: T) { + self.value = value } } - func get(key: CacheKey) -> T? { - var result: T? - lock(for: key).sync { // Sync to ensure thread safe access - guard let entry = cache[key] as? CacheEntry, Date() < entry.expirationDate else { return } - result = entry.value - } - return result - } + private var cache = NSCache>() - func set(key: CacheKey, value: T, withExpiry expiry: TimeInterval = 300) { - lock(for: key).async { - let expirationDate = Date().addingTimeInterval(expiry) - let entry = CacheEntry(value: value, expirationDate: expirationDate) - self.cache[key] = entry + func get(key: CacheKey) -> T? { + let cacheKey = key.description as NSString + guard let entry = cache.object(forKey: cacheKey) as? CacheEntry else { + return nil } - scheduleEviction() + return entry.value } - func invalidate(key: CacheKey) { - lock(for: key).async { - self.cache.removeValue(forKey: key) - } + func set(key: CacheKey, value: T) { + let entry = CacheEntry(value) + let cacheKey = key.description as NSString + cache.setObject(entry, forKey: cacheKey) } - private func scheduleEviction() { - // TODO: DECIDE ON EVICTION INTERVAL - evictionQueue.asyncAfter(deadline: .now() + 10) { - self.evictIfNeeded() - } + func invalidate(key: CacheKey) { + let cacheKey = key.description as NSString + cache.removeObject(forKey: cacheKey) } +} - private func evictIfNeeded() { - evictionQueue.async(flags: .barrier) { - while self.cacheEntriesOrder.count > self.cacheSizeLimit { - if let oldestKey = self.cacheEntriesOrder.first { - self.cache.removeValue(forKey: oldestKey) - self.cacheEntriesOrder.removeFirst() - } - } +private extension CacheKey: CustomStringConvertible { + var description: String { + if let extraData = extraData { + return "\(uri)-\(requestType)-\(extraData)" + } else { + return "\(uri)-\(requestType)" } } } diff --git a/CodeEdit/Features/LSP/LSPEventHandler.swift b/CodeEdit/Features/LSP/LSPEventHandler.swift new file mode 100644 index 0000000000..c55c070e50 --- /dev/null +++ b/CodeEdit/Features/LSP/LSPEventHandler.swift @@ -0,0 +1,87 @@ +// +// LSPEventHandler.swift +// CodeEdit +// +// Created by Abe Malla on 6/1/24. +// + +extension LSPService { + + private func startListeningToEvents(for languageId: LanguageIdentifier) { + guard let languageClient = languageClients[languageId] else { + logger.error("Language client not found for \(languageId.rawValue)") + return + } + + // Create a new Task to listen to the events + let task = Task { + for await event in languageClient.lspInstance.eventSequence { + handleEvent(event, for: languageId) + } + } + eventListeningTasks[languageId] = task + } + + private func stopListeningToEvents(for languageId: LanguageIdentifier) { + if let task = eventListeningTasks[languageId] { + task.cancel() + eventListeningTasks.removeValue(forKey: languageId) + } + } + + private func handleEvent(_ event: LSPEvent, for languageId: LanguageIdentifier) { + switch event { + case let .request(id, request): + print("Request ID: \(id) for \(languageId.rawValue)") + handleRequest(request) + case let .notification(notification): + handleNotification(notification) + case let .error(error): + print("Error from EventStream for \(languageId.rawValue): \(error)") + } + } + + private func handleRequest(_ request: LSPRequest) { + switch request { + case let .workspaceConfiguration(params, handler): + print("workspaceConfiguration: \(params)") + case let .workspaceFolders(handler): + print("workspaceFolders: \(String(describing: handler))") + case let .workspaceApplyEdit(params, handler): + print("workspaceApplyEdit: \(params)") + case let .clientRegisterCapability(params, handler): + print("clientRegisterCapability: \(params)") + case let .clientUnregisterCapability(params, handler): + print("clientUnregisterCapability: \(params)") + case let .workspaceCodeLensRefresh(handler): + print("workspaceCodeLensRefresh: \(String(describing: handler))") + case let .workspaceSemanticTokenRefresh(handler): + print("workspaceSemanticTokenRefresh: \(String(describing: handler))") + case let .windowShowMessageRequest(params, handler): + print("windowShowMessageRequest: \(params)") + case let .windowShowDocument(params, handler): + print("windowShowDocument: \(params)") + case let .windowWorkDoneProgressCreate(params, handler): + print("windowWorkDoneProgressCreate: \(params)") + } + } + + private func handleNotification(_ notification: LSPNotification) { + switch notification { + case let .windowLogMessage(params): + print("windowLogMessage \(params.type)\n```\n\(params.message)\n```\n") + case let .windowShowMessage(params): + print("windowShowMessage \(params.type)\n```\n\(params.message)\n```\n") + case let .textDocumentPublishDiagnostics(params): + print("textDocumentPublishDiagnostics: \(params)") + case let .telemetryEvent(params): + print("telemetryEvent: \(params)") + case let .protocolCancelRequest(params): + print("protocolCancelRequest: \(params)") + case let .protocolProgress(params): + print("protocolProgress: \(params)") + case let .protocolLogTrace(params): + print("protocolLogTrace: \(params)") + } + } +} diff --git a/CodeEdit/Features/LSP/LanguageServerManager.swift b/CodeEdit/Features/LSP/LSPService.swift similarity index 53% rename from CodeEdit/Features/LSP/LanguageServerManager.swift rename to CodeEdit/Features/LSP/LSPService.swift index cfc0f9d6c4..c0f017c27e 100644 --- a/CodeEdit/Features/LSP/LanguageServerManager.swift +++ b/CodeEdit/Features/LSP/LSPService.swift @@ -1,5 +1,5 @@ // -// LanguageServerManager.swift +// LSPService.swift // CodeEdit // // Created by Abe Malla on 2/7/24. @@ -11,26 +11,63 @@ import Foundation import LanguageClient import LanguageServerProtocol -final class LanguageServerManager: ObservableObject { +/** + `LSPService` is a service class responsible for managing the lifecycle and event handling + of Language Server Protocol (LSP) clients within the CodeEdit application. It handles the initialization, + communication, and termination of language servers, ensuring that code assistance features + such as code completion, diagnostics, and more are available for various programming languages. + + This class uses Swift's concurrency model to manage background tasks and event streams + efficiently. Each language server runs in its own asynchronous task, listening for events and + handling them as they occur. The `LSPService` class also provides functionality to start + and stop individual language servers, as well as to stop all running servers. + + ## Usage: + To use `LSPService`, create an instance of the class, configure it with the necessary language + server binaries, and invoke the start or stop methods as needed. This class is designed to be + used within a macOS native code editor environment, leveraging the Swift concurrency model for + efficient background processing. + + ## Example: + ```swift + @Service var lspService + + try await lspService.startServer( + for: .python, + projectURL: projectURL, + workspaceFolders: workspaceFolders + ) + try await lspService.stopServer(for: .python) + ``` +*/ +final class LSPService: ObservableObject { + private let logger: Logger + /// Holds the active language clients private var languageClients: [LanguageIdentifier: LanguageServer] = [:] + /// Holds the language server configurations for all the installed language servers private var languageConfigs: [LanguageIdentifier: LanguageServerBinary] = [:] + /// Holds all the event listeners for each active language client + private var eventListeningTasks: [LanguageIdentifier: Task] = [:] init() { - self.logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "", category: "LanguageServerManager") + self.logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "", category: "LSPService") self.languageConfigs = loadLSPConfigurations( from: Bundle.main.url(forResource: "lspConfigs", withExtension: "json") ) } + /// Gets the language server for the specified language func server(for languageId: LanguageIdentifier) -> InitializingServer? { return languageClients[languageId]?.lspInstance } + /// Gets the language client for the specified language func languageClient(for languageId: LanguageIdentifier) -> LanguageServer? { return languageClients[languageId] } + /// Given a language, will attempt to start the language server func startServer( for languageId: LanguageIdentifier, projectURL: URL, @@ -53,68 +90,29 @@ final class LanguageServerManager: ObservableObject { try await server.initialize() logger.info("Successfully initialized \(languageId.rawValue) language server") - // TODO: BACKGROUND THREAD TO LISTEN TO EVENTS FROM CLIENT + startListeningToEvents(for: languageId) } - func testListenEvents() async throws { -// guard var languageClient = self.languageClient(for: .python) else { -// print("Failed to get client") -// exit(1) -// } -// -// print("Listening for events...") -// for await event in languageClient.lspInstance.eventSequence { -// switch event { -// case let .request(id: id, request: request): -// print("Request ID: \(id)") -// -// switch request { -// case let .workspaceConfiguration(params, handler): -// print("workspaceConfiguration: \(params)") -// case let .workspaceFolders(handler): -// print("workspaceFolders: \(String(describing: handler))") -// case let .workspaceApplyEdit(params, handler): -// print("workspaceApplyEdit: \(params)") -// case let .clientRegisterCapability(params, handler): -// print("clientRegisterCapability: \(params)") -// case let .clientUnregisterCapability(params, handler): -// print("clientUnregisterCapability: \(params)") -// case let .workspaceCodeLensRefresh(handler): -// print("workspaceCodeLensRefresh: \(String(describing: handler))") -// case let .workspaceSemanticTokenRefresh(handler): -// print("workspaceSemanticTokenRefresh: \(String(describing: handler))") -// case let .windowShowMessageRequest(params, handler): -// print("windowShowMessageRequest: \(params)") -// case let .windowShowDocument(params, handler): -// print("windowShowDocument: \(params)") -// case let .windowWorkDoneProgressCreate(params, handler): -// print("windowWorkDoneProgressCreate: \(params)") -// } -// -// case let .notification(notification): -// switch notification { -// case let .windowLogMessage(params): -// print("windowLogMessage \(params.type)\n```\n\(params.message)\n```\n") -// case let .windowShowMessage(params): -// print("windowShowMessage \(params.type)\n```\n\(params.message)\n```\n") -// case let .textDocumentPublishDiagnostics(params): -// print("textDocumentPublishDiagnostics: \(params)") -// case let .telemetryEvent(params): -// print("telemetryEvent: \(params)") -// case let .protocolCancelRequest(params): -// print("protocolCancelRequest: \(params)") -// case let .protocolProgress(params): -// print("protocolProgress: \(params)") -// case let .protocolLogTrace(params): -// print("protocolLogTrace: \(params)") -// } -// -// case let .error(error): -// print("Error from EventStream: \(error)") -// } -// } + /// Notify the proper language server that we opened a document. + func documentWasOpened(for languageId: LanguageIdentifier, file fileURL: URL) async throws -> bool { + guard var languageClient = self.languageClient(for: .python) else { + logger.error("Failed to get \(languageId.rawValue) client") + throw ServerManagerError.languageClientNotFound + } + return await languageClient.addDocument(fileURL) } + /// Notify the proper language server that we closed a document so we can stop tracking the file. + func documentWasClosed(for languageId: LanguageIdentifier, file fileURL: URL) async throws { + guard var languageClient = self.languageClient(for: .python) else { + logger.error("Failed to get \(languageId.rawValue) client") + throw ServerManagerError.languageClientNotFound + } + return await languageClient.closeDocument(fileURL) + } + + /// NOTE: This function is intended to be removed when the frontend is being developed. + /// For now this is just for reference of a working example. func testCompletion() async throws { do { guard var languageClient = self.languageClient(for: .python) else { @@ -122,7 +120,7 @@ final class LanguageServerManager: ObservableObject { throw ServerManagerError.languageClientNotFound } - let testFilePathStr = "/Users/abe/Documents/Python/FastestFastAPI/main.py" + let testFilePathStr = "" let testFileURL = URL(fileURLWithPath: testFilePathStr) // Tell server we opened a document @@ -168,6 +166,8 @@ final class LanguageServerManager: ObservableObject { } } + /// Attempts to stop a running language server. Throws an error if the server is not found + /// or if the language server throws an error while trying to shutdown. func stopServer(for languageId: LanguageIdentifier) async throws { guard let server = self.server(for: languageId) else { logger.error("Server not found for language \(languageId.rawValue) during stop operation") @@ -181,21 +181,13 @@ final class LanguageServerManager: ObservableObject { languageClients.removeValue(forKey: languageId) logger.info("Server stopped for language \(languageId.rawValue)") - // TODO: STOP BACKGROUND THREAD FOR LISTENING TO EVENTS - } - - func restartServer(for languageId: LanguageIdentifier) async throws { -// guard let langServer = languageClients[languageId] else { -// logger.error("Server not found for language \(languageId.rawValue) during restart operation") -// throw ServerManagerError.serverNotFound -// } - // TODO: RESTART SERVER + stopListeningToEvents(for: languageId) } + /// Goes through all active langauge servers and attempts to shut them down. func stopAllServers() async throws { - for (languageId, server) in languageClients { - try await server.lspInstance.shutdownAndExit() - languageClients.removeValue(forKey: languageId) + for languageId in languageClients.keys { + try await stopServer(for: languageId) } } } diff --git a/CodeEdit/Features/LSP/LanguageClient+CallHierarchy.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+CallHierarchy.swift similarity index 87% rename from CodeEdit/Features/LSP/LanguageClient+CallHierarchy.swift rename to CodeEdit/Features/LSP/LanguageClient/LanguageClient+CallHierarchy.swift index 29bbb662a3..f87820d57e 100644 --- a/CodeEdit/Features/LSP/LanguageClient+CallHierarchy.swift +++ b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+CallHierarchy.swift @@ -26,8 +26,7 @@ extension LanguageServer { // callHierarchyItems[documentURI] = items // return items // } catch { -// // TODO: LOGGING -// print("requestPrepareCallHierarchy: Error \(error)") +// logger.error("requestPrepareCallHierarchy: Error \(error)") // } return [] @@ -47,8 +46,7 @@ extension LanguageServer { // } // return incomingCalls // } catch { -// // TODO: LOGGING -// print("requestCallHierarchyIncomingCalls: Error \(error)") +// logger.error("requestCallHierarchyIncomingCalls: Error \(error)") // } return [] } @@ -67,8 +65,7 @@ extension LanguageServer { } return outgoingCalls } catch { - // TODO: LOGGING - print("requestCallHierarchyOutgoingCalls: Error \(error)") + logger.error("requestCallHierarchyOutgoingCalls: Error \(error)") } return [] } diff --git a/CodeEdit/Features/LSP/LanguageClient+CodeLens.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+CodeLens.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageClient+CodeLens.swift rename to CodeEdit/Features/LSP/LanguageClient/LanguageClient+CodeLens.swift diff --git a/CodeEdit/Features/LSP/LanguageClient+ColorPresentation.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+ColorPresentation.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageClient+ColorPresentation.swift rename to CodeEdit/Features/LSP/LanguageClient/LanguageClient+ColorPresentation.swift diff --git a/CodeEdit/Features/LSP/LanguageClient+Completion.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Completion.swift similarity index 84% rename from CodeEdit/Features/LSP/LanguageClient+Completion.swift rename to CodeEdit/Features/LSP/LanguageClient/LanguageClient+Completion.swift index 041e069d4a..0b0730afb1 100644 --- a/CodeEdit/Features/LSP/LanguageClient+Completion.swift +++ b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Completion.swift @@ -10,7 +10,11 @@ import LanguageServerProtocol extension LanguageServer { func requestCompletion(document documentURI: String, position: Position) async throws -> CompletionResponse { - let cacheKey = CacheKey(uri: documentURI, requestType: "completion") + let cacheKey = CacheKey( + uri: documentURI, + requestType: "completion", + extraData: position + ) if let cachedResponse: CompletionResponse = lspCache.get(key: cacheKey) { return cachedResponse } diff --git a/CodeEdit/Features/LSP/LanguageClient+Declaration.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Declaration.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageClient+Declaration.swift rename to CodeEdit/Features/LSP/LanguageClient/LanguageClient+Declaration.swift diff --git a/CodeEdit/Features/LSP/LanguageClient+Definition.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Definition.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageClient+Definition.swift rename to CodeEdit/Features/LSP/LanguageClient/LanguageClient+Definition.swift diff --git a/CodeEdit/Features/LSP/LanguageClient+Diagnostics.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Diagnostics.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageClient+Diagnostics.swift rename to CodeEdit/Features/LSP/LanguageClient/LanguageClient+Diagnostics.swift diff --git a/CodeEdit/Features/LSP/LanguageClient+DocumentColor.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentColor.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageClient+DocumentColor.swift rename to CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentColor.swift diff --git a/CodeEdit/Features/LSP/LanguageClient+DocumentHighlight.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentHighlight.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageClient+DocumentHighlight.swift rename to CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentHighlight.swift diff --git a/CodeEdit/Features/LSP/LanguageClient+DocumentLink.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentLink.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageClient+DocumentLink.swift rename to CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentLink.swift diff --git a/CodeEdit/Features/LSP/LanguageClient+DocumentSymbol.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentSymbol.swift similarity index 57% rename from CodeEdit/Features/LSP/LanguageClient+DocumentSymbol.swift rename to CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentSymbol.swift index af1d676bc8..1a66968a7e 100644 --- a/CodeEdit/Features/LSP/LanguageClient+DocumentSymbol.swift +++ b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentSymbol.swift @@ -13,16 +13,8 @@ extension LanguageServer { for languageId: LanguageIdentifier, document documentURI: String ) async throws -> DocumentSymbolResponse { -// let cacheKey = CacheKey(uri: documentURI, requestType: "documentSymbols") -// if let cachedResponse: DocumentSymbolResponse = lspCache.get(key: cacheKey) { -// return cachedResponse -// } - let textDocumentIdentifier = TextDocumentIdentifier(uri: documentURI) let documentSymbolParams = DocumentSymbolParams(textDocument: textDocumentIdentifier) - let response = try await lspInstance.documentSymbol(documentSymbolParams) - -// lspCache.set(key: cacheKey, value: response) - return response + return try await lspInstance.documentSymbol(documentSymbolParams) } } diff --git a/CodeEdit/Features/LSP/LanguageClient+DocumentUtil.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentUtil.swift similarity index 94% rename from CodeEdit/Features/LSP/LanguageClient+DocumentUtil.swift rename to CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentUtil.swift index 6926f2aea8..5a0e12245c 100644 --- a/CodeEdit/Features/LSP/LanguageClient+DocumentUtil.swift +++ b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentUtil.swift @@ -20,8 +20,7 @@ extension LanguageServer { ) return await self.addDocument(textDocument) } catch { - // TODO: LOGGING - print("addDocument: An error occurred: \(error)") + logger.error("addDocument: An error occurred: \(error)") } return false @@ -38,8 +37,7 @@ extension LanguageServer { try await lspInstance.textDocumentDidOpen(params) return true } catch { - // TODO: LOGGING - print("addDocument: An error occurred: \(error)") + logger.error("addDocument: An error occurred: \(error)") } return false @@ -55,8 +53,7 @@ extension LanguageServer { try await lspInstance.textDocumentDidClose(params) return true } catch { - // TODO: LOGGING - print("closeDocument: An error occurred: \(error)") + logger.error("closeDocument: An error occurred: \(error)") } return false } @@ -105,8 +102,7 @@ extension LanguageServer { ) try await lspInstance.textDocumentDidChange(params) } catch { - // TODO: LOGGING - print("updateDocument: An error occurred: \(error)") + logger.error("updateDocument: An error occurred: \(error)") } return true } diff --git a/CodeEdit/Features/LSP/LanguageClient+FoldingRange.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+FoldingRange.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageClient+FoldingRange.swift rename to CodeEdit/Features/LSP/LanguageClient/LanguageClient+FoldingRange.swift diff --git a/CodeEdit/Features/LSP/LanguageClient+Formatting.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Formatting.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageClient+Formatting.swift rename to CodeEdit/Features/LSP/LanguageClient/LanguageClient+Formatting.swift diff --git a/CodeEdit/Features/LSP/LanguageClient+Hover.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Hover.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageClient+Hover.swift rename to CodeEdit/Features/LSP/LanguageClient/LanguageClient+Hover.swift diff --git a/CodeEdit/Features/LSP/LanguageClient+Implementation.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Implementation.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageClient+Implementation.swift rename to CodeEdit/Features/LSP/LanguageClient/LanguageClient+Implementation.swift diff --git a/CodeEdit/Features/LSP/LanguageClient+InlayHint.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+InlayHint.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageClient+InlayHint.swift rename to CodeEdit/Features/LSP/LanguageClient/LanguageClient+InlayHint.swift diff --git a/CodeEdit/Features/LSP/LanguageClient+References.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+References.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageClient+References.swift rename to CodeEdit/Features/LSP/LanguageClient/LanguageClient+References.swift diff --git a/CodeEdit/Features/LSP/LanguageClient+Rename.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Rename.swift similarity index 98% rename from CodeEdit/Features/LSP/LanguageClient+Rename.swift rename to CodeEdit/Features/LSP/LanguageClient/LanguageClient+Rename.swift index fd588b5cb2..314135a223 100644 --- a/CodeEdit/Features/LSP/LanguageClient+Rename.swift +++ b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Rename.swift @@ -5,7 +5,6 @@ // Created by Abe Malla on 2/7/24. // -import Foundation import LanguageServerProtocol extension LanguageServer { diff --git a/CodeEdit/Features/LSP/LanguageClient+SelectionRange.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+SelectionRange.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageClient+SelectionRange.swift rename to CodeEdit/Features/LSP/LanguageClient/LanguageClient+SelectionRange.swift diff --git a/CodeEdit/Features/LSP/LanguageClient+SemanticTokens.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+SemanticTokens.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageClient+SemanticTokens.swift rename to CodeEdit/Features/LSP/LanguageClient/LanguageClient+SemanticTokens.swift diff --git a/CodeEdit/Features/LSP/LanguageClient+SignatureHelp.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+SignatureHelp.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageClient+SignatureHelp.swift rename to CodeEdit/Features/LSP/LanguageClient/LanguageClient+SignatureHelp.swift diff --git a/CodeEdit/Features/LSP/LanguageClient+TypeDefinition.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+TypeDefinition.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageClient+TypeDefinition.swift rename to CodeEdit/Features/LSP/LanguageClient/LanguageClient+TypeDefinition.swift diff --git a/CodeEdit/Features/LSP/LanguageServer.swift b/CodeEdit/Features/LSP/LanguageServer.swift index f71cd3a416..1cce93d0dc 100644 --- a/CodeEdit/Features/LSP/LanguageServer.swift +++ b/CodeEdit/Features/LSP/LanguageServer.swift @@ -5,22 +5,25 @@ // Created by Abe Malla on 2/7/24. // -import Foundation import JSONRPC +import Foundation import LanguageClient import LanguageServerProtocol -// TODO: ADD ACTIVATION EVENTS - struct LanguageServer { + /// Identifies which language the server belongs to let languageId: LanguageIdentifier + /// Holds information about the language server binary let binary: LanguageServerBinary + /// A cache to hold responses from the server, to minimize duplicate server requests + let lspCache = LSPCache() - // TODO: REMOVE + // TODO: REMOVE WHEN NEW DOCUMENT TRACKER IS IMPLEMENTED. IS PART OF NEW FILE SOLUTION. var trackedDocuments: [String: TextDocumentItem] = [:] - var lspCache: LSPCache = LSPCache() + /// An instance of a language server, that may or may not be initialized private(set) var lspInstance: InitializingServer + /// The path to the root of the project private(set) var rootPath: URL static func createServer( @@ -44,7 +47,6 @@ struct LanguageServer { } ) } catch { -// logger.error("Failed to start server for language \(languageId.rawValue)") throw error } guard let channel = channel else { @@ -63,7 +65,7 @@ struct LanguageServer { return LanguageServer(languageId: languageId, binary: binary, lspInstance: server, rootPath: rootPath) } - // swiftlint:disable function_body_length line_length + // swiftlint:disable function_body_length private static func getInitParams(projectURL: URL) -> InitializingServer.InitializeParamsProvider { let provider: InitializingServer.InitializeParamsProvider = { // Text Document Capabilities @@ -105,12 +107,10 @@ struct LanguageServer { ) // Workspace Capabilities - // TODO: ADD inlineValue?: InlineValueWorkspaceClientCapabilities;inlayHint?: InlayHintWorkspaceClientCapabilities; diagnostics?: DiagnosticWorkspaceClientCapabilities; let workspaceCapabilities = ClientCapabilities.Workspace( applyEdit: true, workspaceEdit: nil, didChangeConfiguration: DidChangeConfigurationClientCapabilities(dynamicRegistration: true), - // TODO: NEED TO ADD https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workspace_didChangeWatchedFiles `relativePatternSupport` VARIABLE didChangeWatchedFiles: DidChangeWatchedFilesClientCapabilities(dynamicRegistration: true), symbol: WorkspaceSymbolClientCapabilities( dynamicRegistration: true, @@ -146,14 +146,18 @@ struct LanguageServer { ) } return provider - // swiftlint:enable function_body_length line_length + // swiftlint:enable function_body_length } /// Initializes the language server if it hasn't been initialized already. public func initialize() async throws { - // TODO: CATCH ERROR HERE, LOG ERROR OR SUCCESS - // InitializationResponse is not returned because it is automatically stored inside `lspInstance` - _ = try await lspInstance.initializeIfNeeded() + do { + _ = try await lspInstance.initializeIfNeeded() + logger.info("Language server for \(languageId.rawValue) initialized successfully") + } catch { + logger.error("Failed to initialize \(languageId.rawValue) LSP instance: \(error.localizedDescription)") + throw error + } } /// Shuts down the language server and exits it. diff --git a/CodeEdit/Features/NavigatorArea/ProjectNavigator/OutlineView/ProjectNavigatorViewController.swift b/CodeEdit/Features/NavigatorArea/ProjectNavigator/OutlineView/ProjectNavigatorViewController.swift index b89aaaf360..ef12c300c6 100644 --- a/CodeEdit/Features/NavigatorArea/ProjectNavigator/OutlineView/ProjectNavigatorViewController.swift +++ b/CodeEdit/Features/NavigatorArea/ProjectNavigator/OutlineView/ProjectNavigatorViewController.swift @@ -112,7 +112,6 @@ final class ProjectNavigatorViewController: NSViewController { /// Expand or collapse the folder on double click @objc private func onItemDoubleClicked() { - print("Trying to open by double click") guard let item = outlineView.item(atRow: outlineView.clickedRow) as? CEWorkspaceFile else { return } if item.isFolder { From 50c01fef283eaa51d6bac517208af3283ed20f33 Mon Sep 17 00:00:00 2001 From: Abe M Date: Thu, 6 Jun 2024 18:44:49 -0700 Subject: [PATCH 08/20] Lint fix --- CodeEdit/Features/SplitView/Views/Variadic.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/CodeEdit/Features/SplitView/Views/Variadic.swift b/CodeEdit/Features/SplitView/Views/Variadic.swift index 0253b4f9e1..b5ab5aecbe 100644 --- a/CodeEdit/Features/SplitView/Views/Variadic.swift +++ b/CodeEdit/Features/SplitView/Views/Variadic.swift @@ -8,7 +8,6 @@ import SwiftUI struct Helper: _VariadicView_UnaryViewRoot { - // swiftlint:disable:next identifier_name var _body: (_VariadicView.Children) -> Result func body(children: _VariadicView.Children) -> some View { From f8abec225adb8596d918b515c95e9e7440e1df88 Mon Sep 17 00:00:00 2001 From: Abe M Date: Thu, 13 Jun 2024 03:52:57 -0700 Subject: [PATCH 09/20] Fix errors, missing calls --- CodeEdit.xcodeproj/project.pbxproj | 36 +++++---- .../Documents/WorkspaceDocument.swift | 13 +--- CodeEdit/Features/LSP/LSPCache.swift | 74 +++++++++++++++---- CodeEdit/Features/LSP/LSPEventHandler.swift | 17 +++-- CodeEdit/Features/LSP/LSPService.swift | 43 ++++++----- CodeEdit/Features/LSP/LSPUtil.swift | 8 +- .../LanguageClient+CallHierarchy.swift | 58 +++++++-------- .../LanguageClient+CodeLens.swift | 19 ----- .../LanguageClient+Completion.swift | 2 +- .../LanguageClient+Definition.swift | 8 +- .../LanguageClient+Diagnostics.swift | 19 ++++- .../LanguageClient+DocumentHighlight.swift | 1 - .../LanguageClient+DocumentLink.swift | 18 ++--- .../LanguageClient+DocumentUtil.swift | 8 +- .../Features/LSP/LanguageConfiguration.swift | 34 --------- CodeEdit/Features/LSP/LanguageServer.swift | 18 ++++- 16 files changed, 203 insertions(+), 173 deletions(-) delete mode 100644 CodeEdit/Features/LSP/LanguageClient/LanguageClient+CodeLens.swift delete mode 100644 CodeEdit/Features/LSP/LanguageConfiguration.swift diff --git a/CodeEdit.xcodeproj/project.pbxproj b/CodeEdit.xcodeproj/project.pbxproj index 512beb56b3..f845635919 100644 --- a/CodeEdit.xcodeproj/project.pbxproj +++ b/CodeEdit.xcodeproj/project.pbxproj @@ -68,7 +68,6 @@ 30AB4EBD2BF71CA800ED4431 /* DeveloperSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30AB4EBC2BF71CA800ED4431 /* DeveloperSettingsView.swift */; }; 30AB4EC22BF7253200ED4431 /* KeyValueTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30AB4EC12BF7253200ED4431 /* KeyValueTable.swift */; }; 30B087FC2C0D53080063A882 /* LanguageClient+CallHierarchy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087DF2C0D53080063A882 /* LanguageClient+CallHierarchy.swift */; }; - 30B087FD2C0D53080063A882 /* LanguageClient+CodeLens.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E02C0D53080063A882 /* LanguageClient+CodeLens.swift */; }; 30B087FE2C0D53080063A882 /* LanguageClient+ColorPresentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E12C0D53080063A882 /* LanguageClient+ColorPresentation.swift */; }; 30B087FF2C0D53080063A882 /* LanguageClient+Completion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E22C0D53080063A882 /* LanguageClient+Completion.swift */; }; 30B088002C0D53080063A882 /* LanguageClient+Declaration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E32C0D53080063A882 /* LanguageClient+Declaration.swift */; }; @@ -90,12 +89,13 @@ 30B088102C0D53080063A882 /* LanguageClient+SemanticTokens.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F32C0D53080063A882 /* LanguageClient+SemanticTokens.swift */; }; 30B088112C0D53080063A882 /* LanguageClient+SignatureHelp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F42C0D53080063A882 /* LanguageClient+SignatureHelp.swift */; }; 30B088122C0D53080063A882 /* LanguageClient+TypeDefinition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F52C0D53080063A882 /* LanguageClient+TypeDefinition.swift */; }; - 30B088132C0D53080063A882 /* LanguageConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F62C0D53080063A882 /* LanguageConfiguration.swift */; }; 30B088142C0D53080063A882 /* LanguageServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F72C0D53080063A882 /* LanguageServer.swift */; }; 30B088152C0D53080063A882 /* LSPService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F82C0D53080063A882 /* LSPService.swift */; }; 30B088162C0D53080063A882 /* LSPCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F92C0D53080063A882 /* LSPCache.swift */; }; 30B088172C0D53080063A882 /* LSPUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087FA2C0D53080063A882 /* LSPUtil.swift */; }; 30CB648D2C12680F00CC8A9E /* LSPEventHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30CB648C2C12680F00CC8A9E /* LSPEventHandler.swift */; }; + 30CB64912C16CA8100CC8A9E /* LanguageServerProtocol in Frameworks */ = {isa = PBXBuildFile; productRef = 30CB64902C16CA8100CC8A9E /* LanguageServerProtocol */; }; + 30CB64942C16CA9100CC8A9E /* LanguageClient in Frameworks */ = {isa = PBXBuildFile; productRef = 30CB64932C16CA9100CC8A9E /* LanguageClient */; }; 30E6D0012A6E505200A58B20 /* NavigatorSidebarViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30E6D0002A6E505200A58B20 /* NavigatorSidebarViewModel.swift */; }; 3E0196732A3921AC002648D8 /* codeedit_shell_integration.zsh in Resources */ = {isa = PBXBuildFile; fileRef = 3E0196722A3921AC002648D8 /* codeedit_shell_integration.zsh */; }; 3E01967A2A392B45002648D8 /* codeedit_shell_integration.bash in Resources */ = {isa = PBXBuildFile; fileRef = 3E0196792A392B45002648D8 /* codeedit_shell_integration.bash */; }; @@ -669,7 +669,6 @@ 30AB4EBC2BF71CA800ED4431 /* DeveloperSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperSettingsView.swift; sourceTree = ""; }; 30AB4EC12BF7253200ED4431 /* KeyValueTable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyValueTable.swift; sourceTree = ""; }; 30B087DF2C0D53080063A882 /* LanguageClient+CallHierarchy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+CallHierarchy.swift"; sourceTree = ""; }; - 30B087E02C0D53080063A882 /* LanguageClient+CodeLens.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+CodeLens.swift"; sourceTree = ""; }; 30B087E12C0D53080063A882 /* LanguageClient+ColorPresentation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+ColorPresentation.swift"; sourceTree = ""; }; 30B087E22C0D53080063A882 /* LanguageClient+Completion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+Completion.swift"; sourceTree = ""; }; 30B087E32C0D53080063A882 /* LanguageClient+Declaration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+Declaration.swift"; sourceTree = ""; }; @@ -691,7 +690,6 @@ 30B087F32C0D53080063A882 /* LanguageClient+SemanticTokens.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+SemanticTokens.swift"; sourceTree = ""; }; 30B087F42C0D53080063A882 /* LanguageClient+SignatureHelp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+SignatureHelp.swift"; sourceTree = ""; }; 30B087F52C0D53080063A882 /* LanguageClient+TypeDefinition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+TypeDefinition.swift"; sourceTree = ""; }; - 30B087F62C0D53080063A882 /* LanguageConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LanguageConfiguration.swift; sourceTree = ""; }; 30B087F72C0D53080063A882 /* LanguageServer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LanguageServer.swift; sourceTree = ""; }; 30B087F82C0D53080063A882 /* LSPService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LSPService.swift; sourceTree = ""; }; 30B087F92C0D53080063A882 /* LSPCache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LSPCache.swift; sourceTree = ""; }; @@ -1153,11 +1151,13 @@ 6CBE1D002B720565003AC32E /* CodeEditSourceEditor in Frameworks */, 6C147C4529A329350089B630 /* OrderedCollections in Frameworks */, 6C0617D62BDB4432008C9C42 /* LogStream in Frameworks */, + 30CB64912C16CA8100CC8A9E /* LanguageServerProtocol in Frameworks */, 6C6BD6F429CD142C00235D17 /* CollectionConcurrencyKit in Frameworks */, 6CB446402B6DFF3A00539ED0 /* CodeEditSourceEditor in Frameworks */, 5879828A292ED15F0085B254 /* SwiftTerm in Frameworks */, 6CDEFC9629E22C2700B7C684 /* Introspect in Frameworks */, 2816F594280CF50500DD548B /* CodeEditSymbols in Frameworks */, + 30CB64942C16CA9100CC8A9E /* LanguageClient in Frameworks */, 6C6BD6F829CD14D100235D17 /* CodeEditKit in Frameworks */, 6C81916B29B41DD300B75C92 /* DequeModule in Frameworks */, ); @@ -1414,7 +1414,6 @@ children = ( 30B0881E2C12626B0063A882 /* LanguageClient */, 30B087F72C0D53080063A882 /* LanguageServer.swift */, - 30B087F62C0D53080063A882 /* LanguageConfiguration.swift */, 30B087F82C0D53080063A882 /* LSPService.swift */, 30B087F92C0D53080063A882 /* LSPCache.swift */, 30B087FA2C0D53080063A882 /* LSPUtil.swift */, @@ -1427,7 +1426,6 @@ isa = PBXGroup; children = ( 30B087DF2C0D53080063A882 /* LanguageClient+CallHierarchy.swift */, - 30B087E02C0D53080063A882 /* LanguageClient+CodeLens.swift */, 30B087E12C0D53080063A882 /* LanguageClient+ColorPresentation.swift */, 30B087E22C0D53080063A882 /* LanguageClient+Completion.swift */, 30B087E32C0D53080063A882 /* LanguageClient+Declaration.swift */, @@ -3205,6 +3203,8 @@ 6CB4463F2B6DFF3A00539ED0 /* CodeEditSourceEditor */, 6CBE1CFF2B720565003AC32E /* CodeEditSourceEditor */, 6C0617D52BDB4432008C9C42 /* LogStream */, + 30CB64902C16CA8100CC8A9E /* LanguageServerProtocol */, + 30CB64932C16CA9100CC8A9E /* LanguageClient */, ); productName = CodeEdit; productReference = B658FB2C27DA9E0F00EA4DBD /* CodeEdit.app */; @@ -3299,9 +3299,9 @@ 6CDEFC9429E22C2700B7C684 /* XCRemoteSwiftPackageReference "SwiftUI-Introspect" */, 6CBE1CFE2B720565003AC32E /* XCRemoteSwiftPackageReference "CodeEditSourceEditor" */, 6C0617D42BDB4432008C9C42 /* XCRemoteSwiftPackageReference "LogStream" */, - 3083B3892C0BEEE300C6642C /* XCRemoteSwiftPackageReference "LanguageServerProtocol" */, - 3083B38A2C0BEEFF00C6642C /* XCRemoteSwiftPackageReference "LanguageClient" */, - 30B0881D2C1261F80063A882 /* XCLocalSwiftPackageReference "../CodeEditKit" */, + 30CB648F2C16CA8100CC8A9E /* XCRemoteSwiftPackageReference "LanguageServerProtocol" */, + 30CB64922C16CA9100CC8A9E /* XCRemoteSwiftPackageReference "LanguageClient" */, + 30CB64952C16CAA200CC8A9E /* XCLocalSwiftPackageReference "../CodeEditKit" */, ); productRefGroup = B658FB2D27DA9E0F00EA4DBD /* Products */; projectDirPath = ""; @@ -3516,7 +3516,6 @@ 041FC6AD2AE437CE00C1F65A /* SourceControlNavigatorNewBranchView.swift in Sources */, 77A01E432BBC3A2800F0EA38 /* CETask.swift in Sources */, 6C48D8F72972E5F300D6D205 /* WindowObserver.swift in Sources */, - 30B087FD2C0D53080063A882 /* LanguageClient+CodeLens.swift in Sources */, 6CED16E42A3E660D000EC962 /* String+Lines.swift in Sources */, 587B9E6B29301D8F00AC7927 /* GitLabAvatarURL.swift in Sources */, 58798233292E30B90085B254 /* FeedbackToolbar.swift in Sources */, @@ -3613,7 +3612,6 @@ 5882252B292C280D00E83CDE /* StatusBarCursorPositionLabel.swift in Sources */, 5882252D292C280D00E83CDE /* UtilityAreaSplitTerminalButton.swift in Sources */, 58798238292E30B90085B254 /* FeedbackWindowController.swift in Sources */, - 30B088132C0D53080063A882 /* LanguageConfiguration.swift in Sources */, 587B9E6C29301D8F00AC7927 /* GitLabNamespace.swift in Sources */, 30AB4EC22BF7253200ED4431 /* KeyValueTable.swift in Sources */, 6C48D8F22972DAFC00D6D205 /* Env+IsFullscreen.swift in Sources */, @@ -4998,7 +4996,7 @@ /* End XCConfigurationList section */ /* Begin XCLocalSwiftPackageReference section */ - 30B0881D2C1261F80063A882 /* XCLocalSwiftPackageReference "../CodeEditKit" */ = { + 30CB64952C16CAA200CC8A9E /* XCLocalSwiftPackageReference "../CodeEditKit" */ = { isa = XCLocalSwiftPackageReference; relativePath = ../CodeEditKit; }; @@ -5021,7 +5019,7 @@ minimumVersion = 0.2.2; }; }; - 3083B3892C0BEEE300C6642C /* XCRemoteSwiftPackageReference "LanguageServerProtocol" */ = { + 30CB648F2C16CA8100CC8A9E /* XCRemoteSwiftPackageReference "LanguageServerProtocol" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/ChimeHQ/LanguageServerProtocol"; requirement = { @@ -5029,7 +5027,7 @@ minimumVersion = 0.13.2; }; }; - 3083B38A2C0BEEFF00C6642C /* XCRemoteSwiftPackageReference "LanguageClient" */ = { + 30CB64922C16CA9100CC8A9E /* XCRemoteSwiftPackageReference "LanguageClient" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/ChimeHQ/LanguageClient"; requirement = { @@ -5117,6 +5115,16 @@ package = 2816F592280CF50500DD548B /* XCRemoteSwiftPackageReference "CodeEditSymbols" */; productName = CodeEditSymbols; }; + 30CB64902C16CA8100CC8A9E /* LanguageServerProtocol */ = { + isa = XCSwiftPackageProductDependency; + package = 30CB648F2C16CA8100CC8A9E /* XCRemoteSwiftPackageReference "LanguageServerProtocol" */; + productName = LanguageServerProtocol; + }; + 30CB64932C16CA9100CC8A9E /* LanguageClient */ = { + isa = XCSwiftPackageProductDependency; + package = 30CB64922C16CA9100CC8A9E /* XCRemoteSwiftPackageReference "LanguageClient" */; + productName = LanguageClient; + }; 583E529B29361BAB001AB554 /* SnapshotTesting */ = { isa = XCSwiftPackageProductDependency; package = 583E529A29361BAB001AB554 /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */; diff --git a/CodeEdit/Features/Documents/WorkspaceDocument.swift b/CodeEdit/Features/Documents/WorkspaceDocument.swift index beba679b8f..d60988afbd 100644 --- a/CodeEdit/Features/Documents/WorkspaceDocument.swift +++ b/CodeEdit/Features/Documents/WorkspaceDocument.swift @@ -9,7 +9,7 @@ import AppKit import SwiftUI import Combine import Foundation -import WindowManagement +//import WindowManagement import LanguageServerProtocol @objc(WorkspaceDocument) @@ -35,7 +35,6 @@ final class WorkspaceDocument: NSDocument, ObservableObject, NSToolbarDelegate { var statusBarViewModel = StatusBarViewModel() var utilityAreaModel = UtilityAreaViewModel() var searchState: SearchState? - var lspManager: LanguageServerManager? var quickOpenViewModel: QuickOpenViewModel? var commandsPaletteState: QuickActionsViewModel? var listenerModel: WorkspaceNotificationModel = .init() @@ -113,16 +112,6 @@ final class WorkspaceDocument: NSDocument, ObservableObject, NSToolbarDelegate { workspaceURL: url, editorManager: editorManager ) - self.lspManager = LanguageServerManager() - - // TODO: ACTIVATION EVENTS HERE, WHEN EXTENSIONS ARE AVAILABLE - Task { - try await self.lspManager?.startServer( - for: .python, - projectURL: url, - workspaceFolders: [WorkspaceFolder(uri: url.absoluteString, name: "workspace_folder_name")] - ) - } self.workspaceFileManager = .init( folderUrl: url, diff --git a/CodeEdit/Features/LSP/LSPCache.swift b/CodeEdit/Features/LSP/LSPCache.swift index 9c88c778ea..c45d78d105 100644 --- a/CodeEdit/Features/LSP/LSPCache.swift +++ b/CodeEdit/Features/LSP/LSPCache.swift @@ -7,51 +7,97 @@ import Foundation -struct CacheKey: Hashable { +struct AnyHashableData: Hashable { + private let value: Any + private let hashValueFunc: () -> Int + private let equalsFunc: (Any) -> Bool + + init(_ value: T) { + self.value = value + self.hashValueFunc = { value.hashValue } + self.equalsFunc = { ($0 as? T) == value } + } + + static func == (lhs: AnyHashableData, rhs: AnyHashableData) -> Bool { + return lhs.equalsFunc(rhs.value) + } + + func hash(into hasher: inout Hasher) { + hasher.combine(hashValueFunc()) + } + + var description: String { + return String(describing: value) + } +} + +struct NoExtraData: Hashable { } + +struct CacheKey: Hashable { let uri: String let requestType: String - let extraData: ExtraData? + let extraData: AnyHashableData? - init(uri: String, requestType: String, extraData: ExtraData? = nil) { + init(uri: String, requestType: String, extraData: ExtraData? = nil) { self.uri = uri self.requestType = requestType - self.extraData = extraData + self.extraData = extraData.map(AnyHashableData.init) + } + + static func == (lhs: CacheKey, rhs: CacheKey) -> Bool { + return lhs.uri == rhs.uri && + lhs.requestType == rhs.requestType && + lhs.extraData == rhs.extraData + } + + func hash(into hasher: inout Hasher) { + hasher.combine(uri) + hasher.combine(requestType) + if let extraData = extraData { + hasher.combine(extraData) + } } } final class LSPCache { /// Represents a single cache entry with a generic type. - final class CacheEntry: NSObject { - let value: T + final class CacheEntry: NSObject { + let value: Any + let type: Any.Type - init(_ value: T) { + init(_ value: T) { self.value = value + self.type = T.self + } + + func getValue(as type: T.Type) -> T? { + return value as? T } } - private var cache = NSCache>() + private var cache = NSCache() - func get(key: CacheKey) -> T? { + func get(key: CacheKey, as type: T.Type) -> T? { let cacheKey = key.description as NSString - guard let entry = cache.object(forKey: cacheKey) as? CacheEntry else { + guard let entry = cache.object(forKey: cacheKey) else { return nil } - return entry.value + return entry.getValue(as: type) } - func set(key: CacheKey, value: T) { + func set(key: CacheKey, value: T) { let entry = CacheEntry(value) let cacheKey = key.description as NSString cache.setObject(entry, forKey: cacheKey) } - func invalidate(key: CacheKey) { + func invalidate(key: CacheKey) { let cacheKey = key.description as NSString cache.removeObject(forKey: cacheKey) } } -private extension CacheKey: CustomStringConvertible { +extension CacheKey: CustomStringConvertible { var description: String { if let extraData = extraData { return "\(uri)-\(requestType)-\(extraData)" diff --git a/CodeEdit/Features/LSP/LSPEventHandler.swift b/CodeEdit/Features/LSP/LSPEventHandler.swift index c55c070e50..f2fdd44afc 100644 --- a/CodeEdit/Features/LSP/LSPEventHandler.swift +++ b/CodeEdit/Features/LSP/LSPEventHandler.swift @@ -5,9 +5,12 @@ // Created by Abe Malla on 6/1/24. // +import LanguageClient +import LanguageServerProtocol + extension LSPService { - private func startListeningToEvents(for languageId: LanguageIdentifier) { + internal func startListeningToEvents(for languageId: LanguageIdentifier) { guard let languageClient = languageClients[languageId] else { logger.error("Language client not found for \(languageId.rawValue)") return @@ -22,14 +25,14 @@ extension LSPService { eventListeningTasks[languageId] = task } - private func stopListeningToEvents(for languageId: LanguageIdentifier) { + internal func stopListeningToEvents(for languageId: LanguageIdentifier) { if let task = eventListeningTasks[languageId] { task.cancel() eventListeningTasks.removeValue(forKey: languageId) } } - private func handleEvent(_ event: LSPEvent, for languageId: LanguageIdentifier) { + private func handleEvent(_ event: ServerEvent, for languageId: LanguageIdentifier) { switch event { case let .request(id, request): print("Request ID: \(id) for \(languageId.rawValue)") @@ -41,7 +44,7 @@ extension LSPService { } } - private func handleRequest(_ request: LSPRequest) { + private func handleRequest(_ request: ServerRequest) { switch request { case let .workspaceConfiguration(params, handler): print("workspaceConfiguration: \(params)") @@ -63,10 +66,14 @@ extension LSPService { print("windowShowDocument: \(params)") case let .windowWorkDoneProgressCreate(params, handler): print("windowWorkDoneProgressCreate: \(params)") + + // TODO: + default: + print() } } - private func handleNotification(_ notification: LSPNotification) { + private func handleNotification(_ notification: ServerNotification) { switch notification { case let .windowLogMessage(params): print("windowLogMessage \(params.type)\n```\n\(params.message)\n```\n") diff --git a/CodeEdit/Features/LSP/LSPService.swift b/CodeEdit/Features/LSP/LSPService.swift index c0f017c27e..2359f22451 100644 --- a/CodeEdit/Features/LSP/LSPService.swift +++ b/CodeEdit/Features/LSP/LSPService.swift @@ -22,13 +22,7 @@ import LanguageServerProtocol handling them as they occur. The `LSPService` class also provides functionality to start and stop individual language servers, as well as to stop all running servers. - ## Usage: - To use `LSPService`, create an instance of the class, configure it with the necessary language - server binaries, and invoke the start or stop methods as needed. This class is designed to be - used within a macOS native code editor environment, leveraging the Swift concurrency model for - efficient background processing. - - ## Example: + ## Example Usage ```swift @Service var lspService @@ -42,19 +36,30 @@ import LanguageServerProtocol */ final class LSPService: ObservableObject { - private let logger: Logger + internal let logger: Logger /// Holds the active language clients - private var languageClients: [LanguageIdentifier: LanguageServer] = [:] + internal var languageClients: [LanguageIdentifier: LanguageServer] = [:] /// Holds the language server configurations for all the installed language servers - private var languageConfigs: [LanguageIdentifier: LanguageServerBinary] = [:] + internal var languageConfigs: [LanguageIdentifier: LanguageServerBinary] = [:] /// Holds all the event listeners for each active language client - private var eventListeningTasks: [LanguageIdentifier: Task] = [:] + internal var eventListeningTasks: [LanguageIdentifier: Task] = [:] + + @AppSettings(\.developerSettings.lspBinaries) + internal var lspBinaries init() { self.logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "", category: "LSPService") - self.languageConfigs = loadLSPConfigurations( - from: Bundle.main.url(forResource: "lspConfigs", withExtension: "json") - ) + + // Load the LSP binaries from the developer menu + for binary in lspBinaries { + if let language = LanguageIdentifier(rawValue: binary.key) { + self.languageConfigs[language] = LanguageServerBinary( + execPath: binary.value, + args: [], + env: ProcessInfo.processInfo.environment + ) + } + } } /// Gets the language server for the specified language @@ -90,11 +95,12 @@ final class LSPService: ObservableObject { try await server.initialize() logger.info("Successfully initialized \(languageId.rawValue) language server") - startListeningToEvents(for: languageId) + self.startListeningToEvents(for: languageId) } /// Notify the proper language server that we opened a document. - func documentWasOpened(for languageId: LanguageIdentifier, file fileURL: URL) async throws -> bool { + func documentWasOpened(for languageId: LanguageIdentifier, file fileURL: URL) async throws -> Bool { + // TODO: GET FILE TYPE FROM DOCUMENT, USING NEW FILE SOLUTION guard var languageClient = self.languageClient(for: .python) else { logger.error("Failed to get \(languageId.rawValue) client") throw ServerManagerError.languageClientNotFound @@ -103,12 +109,13 @@ final class LSPService: ObservableObject { } /// Notify the proper language server that we closed a document so we can stop tracking the file. - func documentWasClosed(for languageId: LanguageIdentifier, file fileURL: URL) async throws { + func documentWasClosed(for languageId: LanguageIdentifier, file fileURL: URL) async throws -> Bool { + // TODO: GET FILE TYPE FROM DOCUMENT, USING NEW FILE SOLUTION guard var languageClient = self.languageClient(for: .python) else { logger.error("Failed to get \(languageId.rawValue) client") throw ServerManagerError.languageClientNotFound } - return await languageClient.closeDocument(fileURL) + return await languageClient.closeDocument(fileURL.absoluteString) } /// NOTE: This function is intended to be removed when the frontend is being developed. diff --git a/CodeEdit/Features/LSP/LSPUtil.swift b/CodeEdit/Features/LSP/LSPUtil.swift index 828a1535a6..07af5d1b73 100644 --- a/CodeEdit/Features/LSP/LSPUtil.swift +++ b/CodeEdit/Features/LSP/LSPUtil.swift @@ -32,20 +32,20 @@ func getCompletionItemEdits(startPosition: Position, item: CompletionItem) -> [T } // If the `insertText` value was provided else if let insertText = item.insertText { - // TODO: COMPUTE EDIT BY FINDING MATCHING TEXT, ALSO CHECK FOR TRIGGER CHARACTERS + let endPosition = Position((startPosition.line, startPosition.character + insertText.count)) edits.append( TextEdit( - range: LSPRange(from: startPosition, offsetCharacter: insertText.count), + range: LSPRange(start: startPosition, end: endPosition), newText: insertText ) ) } // Fallback to the label else if item.label != "" { - // TODO: COMPUTE EDIT BY FINDING MATCHING TEXT, ALSO CHECK FOR TRIGGER CHARACTERS + let endPosition = Position((startPosition.line, startPosition.character + item.label.count)) edits.append( TextEdit( - range: LSPRange(from: startPosition, offsetCharacter: item.label.count), + range: LSPRange(start: startPosition, end: endPosition), newText: item.label ) ) diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+CallHierarchy.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+CallHierarchy.swift index f87820d57e..b7360edcc6 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+CallHierarchy.swift +++ b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+CallHierarchy.swift @@ -12,22 +12,20 @@ extension LanguageServer { func requestPrepareCallHierarchy( document documentURI: String, _ position: Position ) async -> CallHierarchyPrepareResponse { - // TODO: SOMEHOW NEED TO INVALIDATE THIS. CURRENTLY STORING EVERYTHING IN callHierarchyItems VARIABLE -// let prepareParams = CallHierarchyPrepareParams( -// textDocument: TextDocumentIdentifier(uri: documentURI), -// position: position, -// workDoneToken: nil -// ) -// -// do { -// guard let items = try await server.prepareCallHierarchy(params: prepareParams) else { -// return [] -// } -// callHierarchyItems[documentURI] = items -// return items -// } catch { -// logger.error("requestPrepareCallHierarchy: Error \(error)") -// } + let prepareParams = CallHierarchyPrepareParams( + textDocument: TextDocumentIdentifier(uri: documentURI), + position: position, + workDoneToken: nil + ) + + do { + guard let items = try await lspInstance.prepareCallHierarchy(prepareParams) else { + return [] + } + return items + } catch { + print("requestPrepareCallHierarchy: Error \(error)") + } return [] } @@ -35,19 +33,19 @@ extension LanguageServer { func requestCallHierarchyIncomingCalls( _ callHierarchyItem: CallHierarchyItem ) async -> CallHierarchyIncomingCallsResponse { -// let incomingParams = CallHierarchyIncomingCallsParams( -// item: callHierarchyItem, -// workDoneToken: nil -// ) -// -// do { -// guard let incomingCalls = try await server.callHierarchyIncomingCalls(params: incomingParams) else { -// return [] -// } -// return incomingCalls -// } catch { -// logger.error("requestCallHierarchyIncomingCalls: Error \(error)") -// } + let incomingParams = CallHierarchyIncomingCallsParams( + item: callHierarchyItem, + workDoneToken: nil + ) + + do { + guard let incomingCalls = try await lspInstance.callHierarchyIncomingCalls(incomingParams) else { + return [] + } + return incomingCalls + } catch { + print("requestCallHierarchyIncomingCalls: Error \(error)") + } return [] } @@ -65,7 +63,7 @@ extension LanguageServer { } return outgoingCalls } catch { - logger.error("requestCallHierarchyOutgoingCalls: Error \(error)") + print("requestCallHierarchyOutgoingCalls: Error \(error)") } return [] } diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+CodeLens.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+CodeLens.swift deleted file mode 100644 index e289200443..0000000000 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+CodeLens.swift +++ /dev/null @@ -1,19 +0,0 @@ -// -// LanguageClient+CodeLens.swift -// CodeEdit -// -// Created by Abe Malla on 2/7/24. -// - -import Foundation -import LanguageServerProtocol - -extension LanguageServer { -// func requestCodeLens() async -> CodeLensResponse { -// -// } -// -// func requestCodeLensResolve() async -> CodeLensResolveResponse { -// -// } -} diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Completion.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Completion.swift index 0b0730afb1..5e411b8915 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Completion.swift +++ b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Completion.swift @@ -15,7 +15,7 @@ extension LanguageServer { requestType: "completion", extraData: position ) - if let cachedResponse: CompletionResponse = lspCache.get(key: cacheKey) { + if let cachedResponse: CompletionResponse = lspCache.get(key: cacheKey, as: CompletionResponse.self) { return cachedResponse } let completionParams = CompletionParams( diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Definition.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Definition.swift index aaf3389e10..87f38e78c7 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Definition.swift +++ b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Definition.swift @@ -14,8 +14,12 @@ extension LanguageServer { document documentURI: String, position: Position ) async throws -> DefinitionResponse { - let cacheKey = CacheKey(uri: documentURI, requestType: "goToDefinition") - if let cachedResponse: DefinitionResponse = lspCache.get(key: cacheKey) { + let cacheKey = CacheKey( + uri: documentURI, + requestType: "goToDefinition", + extraData: NoExtraData() + ) + if let cachedResponse: DefinitionResponse = lspCache.get(key: cacheKey, as: DefinitionResponse.self) { return cachedResponse } diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Diagnostics.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Diagnostics.swift index 710b9eff5f..b088bb5da1 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Diagnostics.swift +++ b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Diagnostics.swift @@ -9,7 +9,22 @@ import Foundation import LanguageServerProtocol extension LanguageServer { - func requestPullDiagnostics() async { - // TODO: IMPLEMENTATION + func requestPullDiagnostics(document documentURI: String) async throws -> DocumentDiagnosticReport { + let cacheKey = CacheKey( + uri: documentURI, + requestType: "diagnostics", + extraData: NoExtraData() + ) + if let cachedResponse: DocumentDiagnosticReport = lspCache.get(key: cacheKey, as: DocumentDiagnosticReport.self) { + return cachedResponse + } + + let response = try await lspInstance.diagnostics( + DocumentDiagnosticParams( + textDocument: TextDocumentIdentifier(uri: documentURI) + ) + ) + lspCache.set(key: cacheKey, value: response) + return response } } diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentHighlight.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentHighlight.swift index 95668aa2b8..7821be45f5 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentHighlight.swift +++ b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentHighlight.swift @@ -5,7 +5,6 @@ // Created by Abe Malla on 2/7/24. // -import Foundation import LanguageServerProtocol extension LanguageServer { diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentLink.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentLink.swift index 355d35e764..1d75abc9f0 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentLink.swift +++ b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentLink.swift @@ -9,21 +9,19 @@ import Foundation import LanguageServerProtocol extension LanguageServer { - func requestDocumentLink() async -> DocumentLinkResponse { - do { - // TODO: DocumentLinkParams IS MISSING `textDocument: TextDocumentIdentifier;` FIELD - } catch { - // TODO: LOGGING - print("requestDocumentLink Error: \(error)") - } - return [] - } +// func requestDocumentLink() async -> DocumentLinkResponse { +// do { +// // TODO: DocumentLinkParams IS MISSING `textDocument: TextDocumentIdentifier;` FIELD IN LSP LIBRARY +// } catch { +// print("requestDocumentLink Error: \(error)") +// } +// return [] +// } func requestDocumentLinkResolve(_ documentLink: DocumentLink) async -> DocumentLink? { do { return try await lspInstance.documentLinkResolve(documentLink) } catch { - // TODO: LOGGING print("requestDocumentLinkResolve Error: \(error)") } return nil diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentUtil.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentUtil.swift index 5a0e12245c..5c8ae04db3 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentUtil.swift +++ b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentUtil.swift @@ -20,7 +20,7 @@ extension LanguageServer { ) return await self.addDocument(textDocument) } catch { - logger.error("addDocument: An error occurred: \(error)") + print("addDocument: An error occurred: \(error)") } return false @@ -37,7 +37,7 @@ extension LanguageServer { try await lspInstance.textDocumentDidOpen(params) return true } catch { - logger.error("addDocument: An error occurred: \(error)") + print("addDocument: An error occurred: \(error)") } return false @@ -53,7 +53,7 @@ extension LanguageServer { try await lspInstance.textDocumentDidClose(params) return true } catch { - logger.error("closeDocument: An error occurred: \(error)") + print("closeDocument: An error occurred: \(error)") } return false } @@ -102,7 +102,7 @@ extension LanguageServer { ) try await lspInstance.textDocumentDidChange(params) } catch { - logger.error("updateDocument: An error occurred: \(error)") + print("updateDocument: An error occurred: \(error)") } return true } diff --git a/CodeEdit/Features/LSP/LanguageConfiguration.swift b/CodeEdit/Features/LSP/LanguageConfiguration.swift deleted file mode 100644 index 00151895b4..0000000000 --- a/CodeEdit/Features/LSP/LanguageConfiguration.swift +++ /dev/null @@ -1,34 +0,0 @@ -// -// LanguageConfiguration.swift -// CodeEdit -// -// Created by Abe Malla on 2/7/24. -// - -import Foundation -import LanguageServerProtocol - -func loadLSPConfigurations(from configFile: URL?) -> [LanguageIdentifier: LanguageServerBinary] { - // TEMP: This is in a variable to avoid lint error - let rustPath = "/Users/abe/.vscode/extensions/rust-lang.rust-analyzer-0.3.1823-darwin-arm64/server/rust-analyzer" - // TODO: LOAD FROM FILE - return [ - .python: LanguageServerBinary( - execPath: "/opt/homebrew/Cellar/python-lsp-server/1.10.0/libexec/bin/pylsp", - args: [ - "--log-file", - "/Users/abe/Documents/Swift/CodeEditLSPExample/CodeEditLSPExample/LSP_Logs/python.log" - ], - env: ProcessInfo.processInfo.environment - ), - .rust: LanguageServerBinary( - execPath: rustPath, - args: [ - "--verbose", - "--log-file", - "/Users/abe/Documents/Swift/CodeEditLSPExample/CodeEditLSPExample/LSP_Logs/rust.log" - ], - env: ProcessInfo.processInfo.environment // ["RUST_BACKTRACE": "full"] - ) - ] -} diff --git a/CodeEdit/Features/LSP/LanguageServer.swift b/CodeEdit/Features/LSP/LanguageServer.swift index 1cce93d0dc..d5664c39d3 100644 --- a/CodeEdit/Features/LSP/LanguageServer.swift +++ b/CodeEdit/Features/LSP/LanguageServer.swift @@ -126,11 +126,23 @@ struct LanguageServer { fileOperations: fileOperations ) + let windowClientCapabilities = WindowClientCapabilities( + workDoneProgress: true, + showMessage: ShowMessageRequestClientCapabilities( + messageActionItem: ShowMessageRequestClientCapabilities.MessageActionItemCapabilities( + additionalPropertiesSupport: true + ) + ), + showDocument: ShowDocumentClientCapabilities( + support: true + ) + ) + // All Client Capabilities let capabilities = ClientCapabilities( workspace: workspaceCapabilities, textDocument: textDocumentCapabilities, - window: nil, + window: windowClientCapabilities, general: nil, experimental: nil ) @@ -153,9 +165,9 @@ struct LanguageServer { public func initialize() async throws { do { _ = try await lspInstance.initializeIfNeeded() - logger.info("Language server for \(languageId.rawValue) initialized successfully") + print("Language server for \(languageId.rawValue) initialized successfully") } catch { - logger.error("Failed to initialize \(languageId.rawValue) LSP instance: \(error.localizedDescription)") + print("Failed to initialize \(languageId.rawValue) LSP instance: \(error.localizedDescription)") throw error } } From e8a0b6975ce0cd0443a35cfb9a6ce025ac42b506 Mon Sep 17 00:00:00 2001 From: Abe M Date: Thu, 13 Jun 2024 03:53:33 -0700 Subject: [PATCH 10/20] Fix lint --- .../LSP/LanguageClient/LanguageClient+Diagnostics.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Diagnostics.swift b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Diagnostics.swift index b088bb5da1..00329016f9 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Diagnostics.swift +++ b/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Diagnostics.swift @@ -15,7 +15,9 @@ extension LanguageServer { requestType: "diagnostics", extraData: NoExtraData() ) - if let cachedResponse: DocumentDiagnosticReport = lspCache.get(key: cacheKey, as: DocumentDiagnosticReport.self) { + if let cachedResponse: DocumentDiagnosticReport = lspCache.get( + key: cacheKey, as: DocumentDiagnosticReport.self + ) { return cachedResponse } From b5d622fe215912648104fafe1ef3b08b12e27bf2 Mon Sep 17 00:00:00 2001 From: Abe M Date: Thu, 13 Jun 2024 03:55:23 -0700 Subject: [PATCH 11/20] Fix lint --- CodeEdit/Features/Documents/WorkspaceDocument.swift | 1 - CodeEdit/Features/LSP/LSPEventHandler.swift | 1 - 2 files changed, 2 deletions(-) diff --git a/CodeEdit/Features/Documents/WorkspaceDocument.swift b/CodeEdit/Features/Documents/WorkspaceDocument.swift index d60988afbd..6c20cb61c7 100644 --- a/CodeEdit/Features/Documents/WorkspaceDocument.swift +++ b/CodeEdit/Features/Documents/WorkspaceDocument.swift @@ -9,7 +9,6 @@ import AppKit import SwiftUI import Combine import Foundation -//import WindowManagement import LanguageServerProtocol @objc(WorkspaceDocument) diff --git a/CodeEdit/Features/LSP/LSPEventHandler.swift b/CodeEdit/Features/LSP/LSPEventHandler.swift index f2fdd44afc..b86082e43a 100644 --- a/CodeEdit/Features/LSP/LSPEventHandler.swift +++ b/CodeEdit/Features/LSP/LSPEventHandler.swift @@ -67,7 +67,6 @@ extension LSPService { case let .windowWorkDoneProgressCreate(params, handler): print("windowWorkDoneProgressCreate: \(params)") - // TODO: default: print() } From 1958b338a1c51d2595d81f84252e4c9bf9028ddf Mon Sep 17 00:00:00 2001 From: Abe M Date: Thu, 13 Jun 2024 04:00:25 -0700 Subject: [PATCH 12/20] Fix lint --- CodeEdit/Features/CodeEditUI/Views/AreaTabBar.swift | 4 ++-- CodeEdit/Features/LSP/LSPEventHandler.swift | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CodeEdit/Features/CodeEditUI/Views/AreaTabBar.swift b/CodeEdit/Features/CodeEditUI/Views/AreaTabBar.swift index 5b7796b93b..5950a97490 100644 --- a/CodeEdit/Features/CodeEditUI/Views/AreaTabBar.swift +++ b/CodeEdit/Features/CodeEditUI/Views/AreaTabBar.swift @@ -185,7 +185,7 @@ struct AreaTabBar: View { case next } - // swiftlint: disable function_parameter_count + // swiftlint:disable function_parameter_count private func swapTab( tab: Tab, currentIndex: Int, @@ -236,7 +236,7 @@ struct AreaTabBar: View { items.swapAt(currentIndex, swapIndex) } } - // swiftlint: enable function_parameter_count + // swiftlint:enable function_parameter_count private func isWithinPrevTopBounds( _ curLocation: CGFloat, _ swapLocation: CGRect, _ swapWidth: CGFloat diff --git a/CodeEdit/Features/LSP/LSPEventHandler.swift b/CodeEdit/Features/LSP/LSPEventHandler.swift index b86082e43a..1cdcb88231 100644 --- a/CodeEdit/Features/LSP/LSPEventHandler.swift +++ b/CodeEdit/Features/LSP/LSPEventHandler.swift @@ -44,6 +44,7 @@ extension LSPService { } } + // swiftlint:disable cyclomatic_complexity private func handleRequest(_ request: ServerRequest) { switch request { case let .workspaceConfiguration(params, handler): @@ -70,6 +71,7 @@ extension LSPService { default: print() } + // swiftlint:enable cyclomatic_complexity } private func handleNotification(_ notification: ServerNotification) { From 3ce1a3cde622209e957346102f5f2e7b9ed64927 Mon Sep 17 00:00:00 2001 From: Khan Winter <35942988+thecoolwinter@users.noreply.github.com> Date: Sat, 15 Jun 2024 18:46:06 -0500 Subject: [PATCH 13/20] File Name Cleanup, Remove `internal` --- CodeEdit.xcodeproj/project.pbxproj | 193 +++++++++--------- .../xcshareddata/swiftpm/Package.resolved | 4 +- CodeEdit/Features/LSP/LSPEventHandler.swift | 4 +- CodeEdit/Features/LSP/LSPService.swift | 56 +++-- .../LanguageServer+CallHierarchy.swift} | 2 +- .../LanguageServer+ColorPresentation.swift} | 2 +- .../LanguageServer+Completion.swift} | 2 +- .../LanguageServer+Declaration.swift} | 2 +- .../LanguageServer+Definition.swift} | 2 +- .../LanguageServer+Diagnostics.swift} | 2 +- .../LanguageServer+DocumentColor.swift} | 2 +- .../LanguageServer+DocumentHighlight.swift} | 2 +- .../LanguageServer+DocumentLink.swift} | 2 +- .../LanguageServer+DocumentSymbol.swift} | 2 +- .../LanguageServer+DocumentUtil.swift} | 2 +- .../LanguageServer+FoldingRange.swift} | 2 +- .../LanguageServer+Formatting.swift} | 2 +- .../LanguageServer+Hover.swift} | 2 +- .../LanguageServer+Implementation.swift} | 2 +- .../LanguageServer+InlayHint.swift} | 2 +- .../LanguageServer+References.swift} | 2 +- .../LanguageServer+Rename.swift} | 2 +- .../LanguageServer+SelectionRange.swift} | 2 +- .../LanguageServer+SemanticTokens.swift} | 2 +- .../LanguageServer+SignatureHelp.swift} | 2 +- .../LanguageServer+TypeDefinition.swift} | 2 +- 26 files changed, 152 insertions(+), 149 deletions(-) rename CodeEdit/Features/LSP/{LanguageClient/LanguageClient+CallHierarchy.swift => LanguageServer+/LanguageServer+CallHierarchy.swift} (98%) rename CodeEdit/Features/LSP/{LanguageClient/LanguageClient+ColorPresentation.swift => LanguageServer+/LanguageServer+ColorPresentation.swift} (94%) rename CodeEdit/Features/LSP/{LanguageClient/LanguageClient+Completion.swift => LanguageServer+/LanguageServer+Completion.swift} (96%) rename CodeEdit/Features/LSP/{LanguageClient/LanguageClient+Declaration.swift => LanguageServer+/LanguageServer+Declaration.swift} (94%) rename CodeEdit/Features/LSP/{LanguageClient/LanguageClient+Definition.swift => LanguageServer+/LanguageServer+Definition.swift} (96%) rename CodeEdit/Features/LSP/{LanguageClient/LanguageClient+Diagnostics.swift => LanguageServer+/LanguageServer+Diagnostics.swift} (95%) rename CodeEdit/Features/LSP/{LanguageClient/LanguageClient+DocumentColor.swift => LanguageServer+/LanguageServer+DocumentColor.swift} (96%) rename CodeEdit/Features/LSP/{LanguageClient/LanguageClient+DocumentHighlight.swift => LanguageServer+/LanguageServer+DocumentHighlight.swift} (95%) rename CodeEdit/Features/LSP/{LanguageClient/LanguageClient+DocumentLink.swift => LanguageServer+/LanguageServer+DocumentLink.swift} (95%) rename CodeEdit/Features/LSP/{LanguageClient/LanguageClient+DocumentSymbol.swift => LanguageServer+/LanguageServer+DocumentSymbol.swift} (93%) rename CodeEdit/Features/LSP/{LanguageClient/LanguageClient+DocumentUtil.swift => LanguageServer+/LanguageServer+DocumentUtil.swift} (99%) rename CodeEdit/Features/LSP/{LanguageClient/LanguageClient+FoldingRange.swift => LanguageServer+/LanguageServer+FoldingRange.swift} (93%) rename CodeEdit/Features/LSP/{LanguageClient/LanguageClient+Formatting.swift => LanguageServer+/LanguageServer+Formatting.swift} (98%) rename CodeEdit/Features/LSP/{LanguageClient/LanguageClient+Hover.swift => LanguageServer+/LanguageServer+Hover.swift} (95%) rename CodeEdit/Features/LSP/{LanguageClient/LanguageClient+Implementation.swift => LanguageServer+/LanguageServer+Implementation.swift} (94%) rename CodeEdit/Features/LSP/{LanguageClient/LanguageClient+InlayHint.swift => LanguageServer+/LanguageServer+InlayHint.swift} (97%) rename CodeEdit/Features/LSP/{LanguageClient/LanguageClient+References.swift => LanguageServer+/LanguageServer+References.swift} (95%) rename CodeEdit/Features/LSP/{LanguageClient/LanguageClient+Rename.swift => LanguageServer+/LanguageServer+Rename.swift} (97%) rename CodeEdit/Features/LSP/{LanguageClient/LanguageClient+SelectionRange.swift => LanguageServer+/LanguageServer+SelectionRange.swift} (94%) rename CodeEdit/Features/LSP/{LanguageClient/LanguageClient+SemanticTokens.swift => LanguageServer+/LanguageServer+SemanticTokens.swift} (97%) rename CodeEdit/Features/LSP/{LanguageClient/LanguageClient+SignatureHelp.swift => LanguageServer+/LanguageServer+SignatureHelp.swift} (94%) rename CodeEdit/Features/LSP/{LanguageClient/LanguageClient+TypeDefinition.swift => LanguageServer+/LanguageServer+TypeDefinition.swift} (94%) diff --git a/CodeEdit.xcodeproj/project.pbxproj b/CodeEdit.xcodeproj/project.pbxproj index f845635919..bbc23f65d5 100644 --- a/CodeEdit.xcodeproj/project.pbxproj +++ b/CodeEdit.xcodeproj/project.pbxproj @@ -67,28 +67,28 @@ 30AB4EBB2BF718A100ED4431 /* DeveloperSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30AB4EBA2BF718A100ED4431 /* DeveloperSettings.swift */; }; 30AB4EBD2BF71CA800ED4431 /* DeveloperSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30AB4EBC2BF71CA800ED4431 /* DeveloperSettingsView.swift */; }; 30AB4EC22BF7253200ED4431 /* KeyValueTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30AB4EC12BF7253200ED4431 /* KeyValueTable.swift */; }; - 30B087FC2C0D53080063A882 /* LanguageClient+CallHierarchy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087DF2C0D53080063A882 /* LanguageClient+CallHierarchy.swift */; }; - 30B087FE2C0D53080063A882 /* LanguageClient+ColorPresentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E12C0D53080063A882 /* LanguageClient+ColorPresentation.swift */; }; - 30B087FF2C0D53080063A882 /* LanguageClient+Completion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E22C0D53080063A882 /* LanguageClient+Completion.swift */; }; - 30B088002C0D53080063A882 /* LanguageClient+Declaration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E32C0D53080063A882 /* LanguageClient+Declaration.swift */; }; - 30B088012C0D53080063A882 /* LanguageClient+Definition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E42C0D53080063A882 /* LanguageClient+Definition.swift */; }; - 30B088022C0D53080063A882 /* LanguageClient+Diagnostics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E52C0D53080063A882 /* LanguageClient+Diagnostics.swift */; }; - 30B088032C0D53080063A882 /* LanguageClient+DocumentColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E62C0D53080063A882 /* LanguageClient+DocumentColor.swift */; }; - 30B088042C0D53080063A882 /* LanguageClient+DocumentHighlight.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E72C0D53080063A882 /* LanguageClient+DocumentHighlight.swift */; }; - 30B088052C0D53080063A882 /* LanguageClient+DocumentLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E82C0D53080063A882 /* LanguageClient+DocumentLink.swift */; }; - 30B088062C0D53080063A882 /* LanguageClient+DocumentSymbol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E92C0D53080063A882 /* LanguageClient+DocumentSymbol.swift */; }; - 30B088072C0D53080063A882 /* LanguageClient+DocumentUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087EA2C0D53080063A882 /* LanguageClient+DocumentUtil.swift */; }; - 30B088082C0D53080063A882 /* LanguageClient+FoldingRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087EB2C0D53080063A882 /* LanguageClient+FoldingRange.swift */; }; - 30B088092C0D53080063A882 /* LanguageClient+Formatting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087EC2C0D53080063A882 /* LanguageClient+Formatting.swift */; }; - 30B0880A2C0D53080063A882 /* LanguageClient+Hover.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087ED2C0D53080063A882 /* LanguageClient+Hover.swift */; }; - 30B0880B2C0D53080063A882 /* LanguageClient+Implementation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087EE2C0D53080063A882 /* LanguageClient+Implementation.swift */; }; - 30B0880C2C0D53080063A882 /* LanguageClient+InlayHint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087EF2C0D53080063A882 /* LanguageClient+InlayHint.swift */; }; - 30B0880D2C0D53080063A882 /* LanguageClient+References.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F02C0D53080063A882 /* LanguageClient+References.swift */; }; - 30B0880E2C0D53080063A882 /* LanguageClient+Rename.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F12C0D53080063A882 /* LanguageClient+Rename.swift */; }; - 30B0880F2C0D53080063A882 /* LanguageClient+SelectionRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F22C0D53080063A882 /* LanguageClient+SelectionRange.swift */; }; - 30B088102C0D53080063A882 /* LanguageClient+SemanticTokens.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F32C0D53080063A882 /* LanguageClient+SemanticTokens.swift */; }; - 30B088112C0D53080063A882 /* LanguageClient+SignatureHelp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F42C0D53080063A882 /* LanguageClient+SignatureHelp.swift */; }; - 30B088122C0D53080063A882 /* LanguageClient+TypeDefinition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F52C0D53080063A882 /* LanguageClient+TypeDefinition.swift */; }; + 30B087FC2C0D53080063A882 /* LanguageServer+CallHierarchy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087DF2C0D53080063A882 /* LanguageServer+CallHierarchy.swift */; }; + 30B087FE2C0D53080063A882 /* LanguageServer+ColorPresentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E12C0D53080063A882 /* LanguageServer+ColorPresentation.swift */; }; + 30B087FF2C0D53080063A882 /* LanguageServer+Completion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E22C0D53080063A882 /* LanguageServer+Completion.swift */; }; + 30B088002C0D53080063A882 /* LanguageServer+Declaration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E32C0D53080063A882 /* LanguageServer+Declaration.swift */; }; + 30B088012C0D53080063A882 /* LanguageServer+Definition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E42C0D53080063A882 /* LanguageServer+Definition.swift */; }; + 30B088022C0D53080063A882 /* LanguageServer+Diagnostics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E52C0D53080063A882 /* LanguageServer+Diagnostics.swift */; }; + 30B088032C0D53080063A882 /* LanguageServer+DocumentColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E62C0D53080063A882 /* LanguageServer+DocumentColor.swift */; }; + 30B088042C0D53080063A882 /* LanguageServer+DocumentHighlight.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E72C0D53080063A882 /* LanguageServer+DocumentHighlight.swift */; }; + 30B088052C0D53080063A882 /* LanguageServer+DocumentLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E82C0D53080063A882 /* LanguageServer+DocumentLink.swift */; }; + 30B088062C0D53080063A882 /* LanguageServer+DocumentSymbol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087E92C0D53080063A882 /* LanguageServer+DocumentSymbol.swift */; }; + 30B088072C0D53080063A882 /* LanguageServer+DocumentUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087EA2C0D53080063A882 /* LanguageServer+DocumentUtil.swift */; }; + 30B088082C0D53080063A882 /* LanguageServer+FoldingRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087EB2C0D53080063A882 /* LanguageServer+FoldingRange.swift */; }; + 30B088092C0D53080063A882 /* LanguageServer+Formatting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087EC2C0D53080063A882 /* LanguageServer+Formatting.swift */; }; + 30B0880A2C0D53080063A882 /* LanguageServer+Hover.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087ED2C0D53080063A882 /* LanguageServer+Hover.swift */; }; + 30B0880B2C0D53080063A882 /* LanguageServer+Implementation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087EE2C0D53080063A882 /* LanguageServer+Implementation.swift */; }; + 30B0880C2C0D53080063A882 /* LanguageServer+InlayHint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087EF2C0D53080063A882 /* LanguageServer+InlayHint.swift */; }; + 30B0880D2C0D53080063A882 /* LanguageServer+References.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F02C0D53080063A882 /* LanguageServer+References.swift */; }; + 30B0880E2C0D53080063A882 /* LanguageServer+Rename.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F12C0D53080063A882 /* LanguageServer+Rename.swift */; }; + 30B0880F2C0D53080063A882 /* LanguageServer+SelectionRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F22C0D53080063A882 /* LanguageServer+SelectionRange.swift */; }; + 30B088102C0D53080063A882 /* LanguageServer+SemanticTokens.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F32C0D53080063A882 /* LanguageServer+SemanticTokens.swift */; }; + 30B088112C0D53080063A882 /* LanguageServer+SignatureHelp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F42C0D53080063A882 /* LanguageServer+SignatureHelp.swift */; }; + 30B088122C0D53080063A882 /* LanguageServer+TypeDefinition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F52C0D53080063A882 /* LanguageServer+TypeDefinition.swift */; }; 30B088142C0D53080063A882 /* LanguageServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F72C0D53080063A882 /* LanguageServer.swift */; }; 30B088152C0D53080063A882 /* LSPService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F82C0D53080063A882 /* LSPService.swift */; }; 30B088162C0D53080063A882 /* LSPCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B087F92C0D53080063A882 /* LSPCache.swift */; }; @@ -383,6 +383,7 @@ 6C82D6B929BFE34900495C54 /* HelpCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C82D6B829BFE34900495C54 /* HelpCommands.swift */; }; 6C82D6BC29C00CD900495C54 /* FirstResponderPropertyWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C82D6BB29C00CD900495C54 /* FirstResponderPropertyWrapper.swift */; }; 6C82D6C629C012AD00495C54 /* NSApp+openWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C82D6C529C012AD00495C54 /* NSApp+openWindow.swift */; }; + 6C85BB3C2C1E3D1000EB5DEF /* CodeEditKit in Frameworks */ = {isa = PBXBuildFile; productRef = 6C85BB3B2C1E3D1000EB5DEF /* CodeEditKit */; }; 6C91D57229B176FF0059A90D /* EditorManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C91D57129B176FF0059A90D /* EditorManager.swift */; }; 6C97EBCC2978760400302F95 /* AcknowledgementsWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C97EBCB2978760400302F95 /* AcknowledgementsWindowController.swift */; }; 6CA1AE952B46950000378EAB /* EditorInstance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CA1AE942B46950000378EAB /* EditorInstance.swift */; }; @@ -668,28 +669,28 @@ 30AB4EBA2BF718A100ED4431 /* DeveloperSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperSettings.swift; sourceTree = ""; }; 30AB4EBC2BF71CA800ED4431 /* DeveloperSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperSettingsView.swift; sourceTree = ""; }; 30AB4EC12BF7253200ED4431 /* KeyValueTable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyValueTable.swift; sourceTree = ""; }; - 30B087DF2C0D53080063A882 /* LanguageClient+CallHierarchy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+CallHierarchy.swift"; sourceTree = ""; }; - 30B087E12C0D53080063A882 /* LanguageClient+ColorPresentation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+ColorPresentation.swift"; sourceTree = ""; }; - 30B087E22C0D53080063A882 /* LanguageClient+Completion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+Completion.swift"; sourceTree = ""; }; - 30B087E32C0D53080063A882 /* LanguageClient+Declaration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+Declaration.swift"; sourceTree = ""; }; - 30B087E42C0D53080063A882 /* LanguageClient+Definition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+Definition.swift"; sourceTree = ""; }; - 30B087E52C0D53080063A882 /* LanguageClient+Diagnostics.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+Diagnostics.swift"; sourceTree = ""; }; - 30B087E62C0D53080063A882 /* LanguageClient+DocumentColor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+DocumentColor.swift"; sourceTree = ""; }; - 30B087E72C0D53080063A882 /* LanguageClient+DocumentHighlight.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+DocumentHighlight.swift"; sourceTree = ""; }; - 30B087E82C0D53080063A882 /* LanguageClient+DocumentLink.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+DocumentLink.swift"; sourceTree = ""; }; - 30B087E92C0D53080063A882 /* LanguageClient+DocumentSymbol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+DocumentSymbol.swift"; sourceTree = ""; }; - 30B087EA2C0D53080063A882 /* LanguageClient+DocumentUtil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+DocumentUtil.swift"; sourceTree = ""; }; - 30B087EB2C0D53080063A882 /* LanguageClient+FoldingRange.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+FoldingRange.swift"; sourceTree = ""; }; - 30B087EC2C0D53080063A882 /* LanguageClient+Formatting.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+Formatting.swift"; sourceTree = ""; }; - 30B087ED2C0D53080063A882 /* LanguageClient+Hover.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+Hover.swift"; sourceTree = ""; }; - 30B087EE2C0D53080063A882 /* LanguageClient+Implementation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+Implementation.swift"; sourceTree = ""; }; - 30B087EF2C0D53080063A882 /* LanguageClient+InlayHint.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+InlayHint.swift"; sourceTree = ""; }; - 30B087F02C0D53080063A882 /* LanguageClient+References.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+References.swift"; sourceTree = ""; }; - 30B087F12C0D53080063A882 /* LanguageClient+Rename.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+Rename.swift"; sourceTree = ""; }; - 30B087F22C0D53080063A882 /* LanguageClient+SelectionRange.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+SelectionRange.swift"; sourceTree = ""; }; - 30B087F32C0D53080063A882 /* LanguageClient+SemanticTokens.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+SemanticTokens.swift"; sourceTree = ""; }; - 30B087F42C0D53080063A882 /* LanguageClient+SignatureHelp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+SignatureHelp.swift"; sourceTree = ""; }; - 30B087F52C0D53080063A882 /* LanguageClient+TypeDefinition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageClient+TypeDefinition.swift"; sourceTree = ""; }; + 30B087DF2C0D53080063A882 /* LanguageServer+CallHierarchy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageServer+CallHierarchy.swift"; sourceTree = ""; }; + 30B087E12C0D53080063A882 /* LanguageServer+ColorPresentation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageServer+ColorPresentation.swift"; sourceTree = ""; }; + 30B087E22C0D53080063A882 /* LanguageServer+Completion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageServer+Completion.swift"; sourceTree = ""; }; + 30B087E32C0D53080063A882 /* LanguageServer+Declaration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageServer+Declaration.swift"; sourceTree = ""; }; + 30B087E42C0D53080063A882 /* LanguageServer+Definition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageServer+Definition.swift"; sourceTree = ""; }; + 30B087E52C0D53080063A882 /* LanguageServer+Diagnostics.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageServer+Diagnostics.swift"; sourceTree = ""; }; + 30B087E62C0D53080063A882 /* LanguageServer+DocumentColor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageServer+DocumentColor.swift"; sourceTree = ""; }; + 30B087E72C0D53080063A882 /* LanguageServer+DocumentHighlight.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageServer+DocumentHighlight.swift"; sourceTree = ""; }; + 30B087E82C0D53080063A882 /* LanguageServer+DocumentLink.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageServer+DocumentLink.swift"; sourceTree = ""; }; + 30B087E92C0D53080063A882 /* LanguageServer+DocumentSymbol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageServer+DocumentSymbol.swift"; sourceTree = ""; }; + 30B087EA2C0D53080063A882 /* LanguageServer+DocumentUtil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageServer+DocumentUtil.swift"; sourceTree = ""; }; + 30B087EB2C0D53080063A882 /* LanguageServer+FoldingRange.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageServer+FoldingRange.swift"; sourceTree = ""; }; + 30B087EC2C0D53080063A882 /* LanguageServer+Formatting.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageServer+Formatting.swift"; sourceTree = ""; }; + 30B087ED2C0D53080063A882 /* LanguageServer+Hover.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageServer+Hover.swift"; sourceTree = ""; }; + 30B087EE2C0D53080063A882 /* LanguageServer+Implementation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageServer+Implementation.swift"; sourceTree = ""; }; + 30B087EF2C0D53080063A882 /* LanguageServer+InlayHint.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageServer+InlayHint.swift"; sourceTree = ""; }; + 30B087F02C0D53080063A882 /* LanguageServer+References.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageServer+References.swift"; sourceTree = ""; }; + 30B087F12C0D53080063A882 /* LanguageServer+Rename.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageServer+Rename.swift"; sourceTree = ""; }; + 30B087F22C0D53080063A882 /* LanguageServer+SelectionRange.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageServer+SelectionRange.swift"; sourceTree = ""; }; + 30B087F32C0D53080063A882 /* LanguageServer+SemanticTokens.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageServer+SemanticTokens.swift"; sourceTree = ""; }; + 30B087F42C0D53080063A882 /* LanguageServer+SignatureHelp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageServer+SignatureHelp.swift"; sourceTree = ""; }; + 30B087F52C0D53080063A882 /* LanguageServer+TypeDefinition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageServer+TypeDefinition.swift"; sourceTree = ""; }; 30B087F72C0D53080063A882 /* LanguageServer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LanguageServer.swift; sourceTree = ""; }; 30B087F82C0D53080063A882 /* LSPService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LSPService.swift; sourceTree = ""; }; 30B087F92C0D53080063A882 /* LSPCache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LSPCache.swift; sourceTree = ""; }; @@ -1149,6 +1150,7 @@ 6C66C31329D05CDC00DE9ED2 /* GRDB in Frameworks */, 58F2EB1E292FB954004A9BDE /* Sparkle in Frameworks */, 6CBE1D002B720565003AC32E /* CodeEditSourceEditor in Frameworks */, + 6C85BB3C2C1E3D1000EB5DEF /* CodeEditKit in Frameworks */, 6C147C4529A329350089B630 /* OrderedCollections in Frameworks */, 6C0617D62BDB4432008C9C42 /* LogStream in Frameworks */, 30CB64912C16CA8100CC8A9E /* LanguageServerProtocol in Frameworks */, @@ -1412,7 +1414,7 @@ 30B087FB2C0D53080063A882 /* LSP */ = { isa = PBXGroup; children = ( - 30B0881E2C12626B0063A882 /* LanguageClient */, + 30B0881E2C12626B0063A882 /* LanguageServer+ */, 30B087F72C0D53080063A882 /* LanguageServer.swift */, 30B087F82C0D53080063A882 /* LSPService.swift */, 30B087F92C0D53080063A882 /* LSPCache.swift */, @@ -1422,33 +1424,33 @@ path = LSP; sourceTree = ""; }; - 30B0881E2C12626B0063A882 /* LanguageClient */ = { + 30B0881E2C12626B0063A882 /* LanguageServer+ */ = { isa = PBXGroup; children = ( - 30B087DF2C0D53080063A882 /* LanguageClient+CallHierarchy.swift */, - 30B087E12C0D53080063A882 /* LanguageClient+ColorPresentation.swift */, - 30B087E22C0D53080063A882 /* LanguageClient+Completion.swift */, - 30B087E32C0D53080063A882 /* LanguageClient+Declaration.swift */, - 30B087E42C0D53080063A882 /* LanguageClient+Definition.swift */, - 30B087E52C0D53080063A882 /* LanguageClient+Diagnostics.swift */, - 30B087E62C0D53080063A882 /* LanguageClient+DocumentColor.swift */, - 30B087E72C0D53080063A882 /* LanguageClient+DocumentHighlight.swift */, - 30B087E82C0D53080063A882 /* LanguageClient+DocumentLink.swift */, - 30B087E92C0D53080063A882 /* LanguageClient+DocumentSymbol.swift */, - 30B087EA2C0D53080063A882 /* LanguageClient+DocumentUtil.swift */, - 30B087EB2C0D53080063A882 /* LanguageClient+FoldingRange.swift */, - 30B087EC2C0D53080063A882 /* LanguageClient+Formatting.swift */, - 30B087ED2C0D53080063A882 /* LanguageClient+Hover.swift */, - 30B087EE2C0D53080063A882 /* LanguageClient+Implementation.swift */, - 30B087EF2C0D53080063A882 /* LanguageClient+InlayHint.swift */, - 30B087F02C0D53080063A882 /* LanguageClient+References.swift */, - 30B087F12C0D53080063A882 /* LanguageClient+Rename.swift */, - 30B087F22C0D53080063A882 /* LanguageClient+SelectionRange.swift */, - 30B087F32C0D53080063A882 /* LanguageClient+SemanticTokens.swift */, - 30B087F42C0D53080063A882 /* LanguageClient+SignatureHelp.swift */, - 30B087F52C0D53080063A882 /* LanguageClient+TypeDefinition.swift */, + 30B087DF2C0D53080063A882 /* LanguageServer+CallHierarchy.swift */, + 30B087E12C0D53080063A882 /* LanguageServer+ColorPresentation.swift */, + 30B087E22C0D53080063A882 /* LanguageServer+Completion.swift */, + 30B087E32C0D53080063A882 /* LanguageServer+Declaration.swift */, + 30B087E42C0D53080063A882 /* LanguageServer+Definition.swift */, + 30B087E52C0D53080063A882 /* LanguageServer+Diagnostics.swift */, + 30B087E62C0D53080063A882 /* LanguageServer+DocumentColor.swift */, + 30B087E72C0D53080063A882 /* LanguageServer+DocumentHighlight.swift */, + 30B087E82C0D53080063A882 /* LanguageServer+DocumentLink.swift */, + 30B087E92C0D53080063A882 /* LanguageServer+DocumentSymbol.swift */, + 30B087EA2C0D53080063A882 /* LanguageServer+DocumentUtil.swift */, + 30B087EB2C0D53080063A882 /* LanguageServer+FoldingRange.swift */, + 30B087EC2C0D53080063A882 /* LanguageServer+Formatting.swift */, + 30B087ED2C0D53080063A882 /* LanguageServer+Hover.swift */, + 30B087EE2C0D53080063A882 /* LanguageServer+Implementation.swift */, + 30B087EF2C0D53080063A882 /* LanguageServer+InlayHint.swift */, + 30B087F02C0D53080063A882 /* LanguageServer+References.swift */, + 30B087F12C0D53080063A882 /* LanguageServer+Rename.swift */, + 30B087F22C0D53080063A882 /* LanguageServer+SelectionRange.swift */, + 30B087F32C0D53080063A882 /* LanguageServer+SemanticTokens.swift */, + 30B087F42C0D53080063A882 /* LanguageServer+SignatureHelp.swift */, + 30B087F52C0D53080063A882 /* LanguageServer+TypeDefinition.swift */, ); - path = LanguageClient; + path = "LanguageServer+"; sourceTree = ""; }; 3E0196712A392170002648D8 /* ShellIntegration */ = { @@ -3205,6 +3207,7 @@ 6C0617D52BDB4432008C9C42 /* LogStream */, 30CB64902C16CA8100CC8A9E /* LanguageServerProtocol */, 30CB64932C16CA9100CC8A9E /* LanguageClient */, + 6C85BB3B2C1E3D1000EB5DEF /* CodeEditKit */, ); productName = CodeEdit; productReference = B658FB2C27DA9E0F00EA4DBD /* CodeEdit.app */; @@ -3301,7 +3304,7 @@ 6C0617D42BDB4432008C9C42 /* XCRemoteSwiftPackageReference "LogStream" */, 30CB648F2C16CA8100CC8A9E /* XCRemoteSwiftPackageReference "LanguageServerProtocol" */, 30CB64922C16CA9100CC8A9E /* XCRemoteSwiftPackageReference "LanguageClient" */, - 30CB64952C16CAA200CC8A9E /* XCLocalSwiftPackageReference "../CodeEditKit" */, + 6C85BB3A2C1E3D1000EB5DEF /* XCLocalSwiftPackageReference "../CodeEditKit" */, ); productRefGroup = B658FB2D27DA9E0F00EA4DBD /* Products */; projectDirPath = ""; @@ -3424,7 +3427,7 @@ buildActionMask = 2147483647; files = ( 58798285292ED0FB0085B254 /* TerminalEmulatorView+Coordinator.swift in Sources */, - 30B0880E2C0D53080063A882 /* LanguageClient+Rename.swift in Sources */, + 30B0880E2C0D53080063A882 /* LanguageServer+Rename.swift in Sources */, 587B9E7D29301D8F00AC7927 /* GitHubPullRequestRouter.swift in Sources */, B67DB0EF2AF3E381002DC647 /* PaneTextField.swift in Sources */, 5878DA842918642000DD95A3 /* ParsePackagesResolved.swift in Sources */, @@ -3460,7 +3463,7 @@ 6C82D6C629C012AD00495C54 /* NSApp+openWindow.swift in Sources */, 6C14CEB028777D3C001468FE /* FindNavigatorListViewController.swift in Sources */, 587B9E7F29301D8F00AC7927 /* GitHubUserRouter.swift in Sources */, - 30B088042C0D53080063A882 /* LanguageClient+DocumentHighlight.swift in Sources */, + 30B088042C0D53080063A882 /* LanguageServer+DocumentHighlight.swift in Sources */, B62AEDBC2A210DBB009A9F52 /* UtilityAreaTerminalTab.swift in Sources */, B67DB0F62AFC2A7A002DC647 /* FindNavigatorToolbarBottom.swift in Sources */, 04BA7C142AE2AA7300584E1C /* GitCloneViewModel.swift in Sources */, @@ -3471,7 +3474,7 @@ 2813F93827ECC4AA00E305E4 /* FindNavigatorResultList.swift in Sources */, 30B088152C0D53080063A882 /* LSPService.swift in Sources */, 613899B92B6E704500A5CAF6 /* String+Normalise.swift in Sources */, - 30B088002C0D53080063A882 /* LanguageClient+Declaration.swift in Sources */, + 30B088002C0D53080063A882 /* LanguageServer+Declaration.swift in Sources */, 04BA7C192AE2D7C600584E1C /* GitClient+Branches.swift in Sources */, 587B9E8829301D8F00AC7927 /* GitHubFiles.swift in Sources */, 77A01E232BB423A800F0EA38 /* CEWorkspaceSettingsPage.swift in Sources */, @@ -3481,7 +3484,7 @@ 58F2EB08292FB2B0004A9BDE /* TextEditingSettings.swift in Sources */, 201169DB2837B34000F92B46 /* SourceControlNavigatorChangedFileView.swift in Sources */, 5882252E292C280D00E83CDE /* UtilityAreaMaximizeButton.swift in Sources */, - 30B0880D2C0D53080063A882 /* LanguageClient+References.swift in Sources */, + 30B0880D2C0D53080063A882 /* LanguageServer+References.swift in Sources */, 77A01E2E2BB4261200F0EA38 /* CEWorkspaceSettings.swift in Sources */, 6C4104E9297C970F00F472BA /* AboutDefaultView.swift in Sources */, 587B9E6F29301D8F00AC7927 /* GitLabProjectAccess.swift in Sources */, @@ -3502,7 +3505,7 @@ B6C4F2A62B3CABD200B2B140 /* HistoryInspectorItemView.swift in Sources */, B65B10FE2B08B07D002852CF /* SourceControlNavigatorChangesList.swift in Sources */, 58F2EB03292FB2B0004A9BDE /* Documentation.docc in Sources */, - 30B087FE2C0D53080063A882 /* LanguageClient+ColorPresentation.swift in Sources */, + 30B087FE2C0D53080063A882 /* LanguageServer+ColorPresentation.swift in Sources */, 66F2C8C42BEAA939004674F7 /* PDFFileView.swift in Sources */, 611192042B08CCED00D4459B /* SearchIndexer+ProgressiveSearch.swift in Sources */, 611192022B08CCDC00D4459B /* SearchIndexer+Search.swift in Sources */, @@ -3555,7 +3558,7 @@ B66A4E4C29C9179B004573B4 /* CodeEditApp.swift in Sources */, 661EF7B82BEE215300C3E577 /* ImageFileView.swift in Sources */, 4E7F066629602E7B00BB3C12 /* CodeEditSplitViewController.swift in Sources */, - 30B088022C0D53080063A882 /* LanguageClient+Diagnostics.swift in Sources */, + 30B088022C0D53080063A882 /* LanguageServer+Diagnostics.swift in Sources */, 587B9E8D29301D8F00AC7927 /* GitHubAccount.swift in Sources */, 201169E72837B5CA00F92B46 /* SourceControlManager.swift in Sources */, 58822528292C280D00E83CDE /* StatusBarEncodingSelector.swift in Sources */, @@ -3563,8 +3566,8 @@ 6C7F37FE2A3EA6FA00217B83 /* View+focusedValue.swift in Sources */, B6C4F2A12B3CA37500B2B140 /* SourceControlNavigatorHistoryView.swift in Sources */, 6CBE1CFB2B71DAA6003AC32E /* Loopable.swift in Sources */, - 30B088092C0D53080063A882 /* LanguageClient+Formatting.swift in Sources */, - 30B088102C0D53080063A882 /* LanguageClient+SemanticTokens.swift in Sources */, + 30B088092C0D53080063A882 /* LanguageServer+Formatting.swift in Sources */, + 30B088102C0D53080063A882 /* LanguageServer+SemanticTokens.swift in Sources */, B6C6A43029771F7100A3D28F /* EditorTabBackground.swift in Sources */, B60718372B170638009CDAB4 /* SourceControlNavigatorRenameBranchView.swift in Sources */, 6C578D8129CD294800DC73B2 /* ExtensionActivatorView.swift in Sources */, @@ -3574,7 +3577,7 @@ 9D36E1BF2B5E7D7500443C41 /* GitBranchesGroup.swift in Sources */, 587B9E8229301D8F00AC7927 /* GitHubPreviewHeader.swift in Sources */, 611191FC2B08CCB800D4459B /* SearchIndexer+AsyncController.swift in Sources */, - 30B088112C0D53080063A882 /* LanguageClient+SignatureHelp.swift in Sources */, + 30B088112C0D53080063A882 /* LanguageServer+SignatureHelp.swift in Sources */, 6C578D8929CD36E400DC73B2 /* Commands+ForEach.swift in Sources */, 611192082B08CCFD00D4459B /* SearchIndexer+Terms.swift in Sources */, 28B8F884280FFE4600596236 /* NSTableView+Background.swift in Sources */, @@ -3589,7 +3592,7 @@ 613899B12B6E6FDC00A5CAF6 /* Collection+FuzzySearch.swift in Sources */, 581550D129FBD30400684881 /* TextTableViewCell.swift in Sources */, 587B9E6629301D8F00AC7927 /* GitLabProjectHook.swift in Sources */, - 30B088032C0D53080063A882 /* LanguageClient+DocumentColor.swift in Sources */, + 30B088032C0D53080063A882 /* LanguageServer+DocumentColor.swift in Sources */, 587B9E9329301D8F00AC7927 /* BitBucketOAuthConfiguration.swift in Sources */, 6C18620A298BF5A800C663EA /* RecentProjectsListView.swift in Sources */, 58F2EB0A292FB2B0004A9BDE /* SettingsData.swift in Sources */, @@ -3655,7 +3658,7 @@ 669BC4082BED306400D1197C /* AnyFileView.swift in Sources */, 20D839AE280E0CA700B27357 /* HistoryPopoverView.swift in Sources */, B6E41C7029DD157F0088F9F4 /* AccountsSettingsView.swift in Sources */, - 30B088122C0D53080063A882 /* LanguageClient+TypeDefinition.swift in Sources */, + 30B088122C0D53080063A882 /* LanguageServer+TypeDefinition.swift in Sources */, 6CFF967A29BEBD2400182D6F /* ViewCommands.swift in Sources */, 850C631229D6B03400E1444C /* SettingsPage.swift in Sources */, 587B9E6729301D8F00AC7927 /* GitLabEventData.swift in Sources */, @@ -3722,7 +3725,7 @@ 587B9E7129301D8F00AC7927 /* GitURLSession.swift in Sources */, 610C0FDA2B44438F00A01CA7 /* WorkspaceDocument+FindAndReplace.swift in Sources */, 5882252C292C280D00E83CDE /* UtilityAreaView.swift in Sources */, - 30B088072C0D53080063A882 /* LanguageClient+DocumentUtil.swift in Sources */, + 30B088072C0D53080063A882 /* LanguageServer+DocumentUtil.swift in Sources */, 2847019E27FDDF7600F87B6B /* ProjectNavigatorOutlineView.swift in Sources */, B607184C2B17E037009CDAB4 /* SourceControlStashChangesView.swift in Sources */, 6C14CEB32877A68F001468FE /* FindNavigatorMatchListCell.swift in Sources */, @@ -3738,15 +3741,15 @@ 286471AB27ED51FD0039369D /* ProjectNavigatorView.swift in Sources */, B6E41C7C29DE2B110088F9F4 /* AccountsSettingsProviderRow.swift in Sources */, B62AEDB52A1FE295009A9F52 /* UtilityAreaDebugView.swift in Sources */, - 30B0880B2C0D53080063A882 /* LanguageClient+Implementation.swift in Sources */, + 30B0880B2C0D53080063A882 /* LanguageServer+Implementation.swift in Sources */, 6C049A372A49E2DB00D42923 /* DirectoryEventStream.swift in Sources */, - 30B088062C0D53080063A882 /* LanguageClient+DocumentSymbol.swift in Sources */, + 30B088062C0D53080063A882 /* LanguageServer+DocumentSymbol.swift in Sources */, 04BA7C0E2AE2A76E00584E1C /* SourceControlNavigatorChangesCommitView.swift in Sources */, 615AA21A2B0CFD480013FCCC /* LazyStringLoader.swift in Sources */, 6CAAF68A29BC9C2300A1F48A /* (null) in Sources */, 30AB4EBD2BF71CA800ED4431 /* DeveloperSettingsView.swift in Sources */, 6C6BD6EF29CD12E900235D17 /* ExtensionManagerWindow.swift in Sources */, - 30B087FF2C0D53080063A882 /* LanguageClient+Completion.swift in Sources */, + 30B087FF2C0D53080063A882 /* LanguageServer+Completion.swift in Sources */, 6CFF967629BEBCD900182D6F /* FileCommands.swift in Sources */, B60718462B17DC15009CDAB4 /* RepoOutlineGroupItem.swift in Sources */, 613899B32B6E6FEE00A5CAF6 /* FuzzySearchable.swift in Sources */, @@ -3770,7 +3773,7 @@ 6CA1AE952B46950000378EAB /* EditorInstance.swift in Sources */, 30AB4EBB2BF718A100ED4431 /* DeveloperSettings.swift in Sources */, B6C4F2A92B3CB00100B2B140 /* CommitDetailsHeaderView.swift in Sources */, - 30B088012C0D53080063A882 /* LanguageClient+Definition.swift in Sources */, + 30B088012C0D53080063A882 /* LanguageServer+Definition.swift in Sources */, B6EA1FFB29DB78F6001BF195 /* ThemeSettingsThemeDetails.swift in Sources */, 587B9E7029301D8F00AC7927 /* GitLabUser.swift in Sources */, 04660F6A27E51E5C00477777 /* CodeEditWindowController.swift in Sources */, @@ -3779,7 +3782,7 @@ 587B9E6129301D8F00AC7927 /* GitLabOAuthConfiguration.swift in Sources */, 587B9E6229301D8F00AC7927 /* GitLabConfiguration.swift in Sources */, 61A53A7E2B4449870093BF8A /* WorkspaceDocument+Find.swift in Sources */, - 30B0880A2C0D53080063A882 /* LanguageClient+Hover.swift in Sources */, + 30B0880A2C0D53080063A882 /* LanguageServer+Hover.swift in Sources */, 6CABB19E29C5591D00340467 /* NSTableViewWrapper.swift in Sources */, 5879821B292D92370085B254 /* SearchResultMatchModel.swift in Sources */, 04BA7C1E2AE2D8A000584E1C /* GitClient+Clone.swift in Sources */, @@ -3826,7 +3829,7 @@ 6C97EBCC2978760400302F95 /* AcknowledgementsWindowController.swift in Sources */, 284DC84F2978B7B400BF2770 /* ContributorsView.swift in Sources */, B62AEDC92A2704F3009A9F52 /* UtilityAreaTabView.swift in Sources */, - 30B088052C0D53080063A882 /* LanguageClient+DocumentLink.swift in Sources */, + 30B088052C0D53080063A882 /* LanguageServer+DocumentLink.swift in Sources */, 58798250292E78D80085B254 /* CodeFileDocument.swift in Sources */, 5878DAA5291AE76700DD95A3 /* QuickOpenView.swift in Sources */, 201169D72837B2E300F92B46 /* SourceControlNavigatorView.swift in Sources */, @@ -3838,8 +3841,8 @@ 58D01C9A293167DC00C5B6B4 /* CodeEditKeychain.swift in Sources */, B62AEDAA2A1FCBE5009A9F52 /* AreaTabBar.swift in Sources */, 20D839AB280DEB2900B27357 /* NoSelectionInspectorView.swift in Sources */, - 30B0880F2C0D53080063A882 /* LanguageClient+SelectionRange.swift in Sources */, - 30B0880C2C0D53080063A882 /* LanguageClient+InlayHint.swift in Sources */, + 30B0880F2C0D53080063A882 /* LanguageServer+SelectionRange.swift in Sources */, + 30B0880C2C0D53080063A882 /* LanguageServer+InlayHint.swift in Sources */, 587B9E5A29301D8F00AC7927 /* GitCloneView.swift in Sources */, B65B10F52B081A0C002852CF /* SourceControlAddRemoteView.swift in Sources */, 58D01C99293167DC00C5B6B4 /* String+MD5.swift in Sources */, @@ -3862,7 +3865,7 @@ 587B9E9629301D8F00AC7927 /* BitBucketRepositories.swift in Sources */, 5878DAA6291AE76700DD95A3 /* QuickOpenPreviewView.swift in Sources */, 58798286292ED0FB0085B254 /* SwiftTerm+Color+Init.swift in Sources */, - 30B087FC2C0D53080063A882 /* LanguageClient+CallHierarchy.swift in Sources */, + 30B087FC2C0D53080063A882 /* LanguageServer+CallHierarchy.swift in Sources */, 6CFF967C29BEBD5200182D6F /* WindowCommands.swift in Sources */, 587B9E7229301D8F00AC7927 /* GitJSONPostRouter.swift in Sources */, 5878DAB0291D627C00DD95A3 /* EditorPathBarMenu.swift in Sources */, @@ -3895,7 +3898,7 @@ B6AB09B32AB919CF0003A3A6 /* View+actionBar.swift in Sources */, 6C05A8AF284D0CA3007F4EAA /* WorkspaceDocument+Listeners.swift in Sources */, 588847632992A2A200996D95 /* CEWorkspaceFile.swift in Sources */, - 30B088082C0D53080063A882 /* LanguageClient+FoldingRange.swift in Sources */, + 30B088082C0D53080063A882 /* LanguageServer+FoldingRange.swift in Sources */, 6C2C155D29B4F4E500EA60A5 /* SplitViewReader.swift in Sources */, B65B10EF2B07C454002852CF /* GitClient+Remote.swift in Sources */, 58AFAA2F2933C69E00482B53 /* EditorItemID.swift in Sources */, @@ -4996,7 +4999,7 @@ /* End XCConfigurationList section */ /* Begin XCLocalSwiftPackageReference section */ - 30CB64952C16CAA200CC8A9E /* XCLocalSwiftPackageReference "../CodeEditKit" */ = { + 6C85BB3A2C1E3D1000EB5DEF /* XCLocalSwiftPackageReference "../CodeEditKit" */ = { isa = XCLocalSwiftPackageReference; relativePath = ../CodeEditKit; }; @@ -5174,6 +5177,10 @@ package = 6C147C4329A329350089B630 /* XCRemoteSwiftPackageReference "swift-collections" */; productName = DequeModule; }; + 6C85BB3B2C1E3D1000EB5DEF /* CodeEditKit */ = { + isa = XCSwiftPackageProductDependency; + productName = CodeEditKit; + }; 6CB4463F2B6DFF3A00539ED0 /* CodeEditSourceEditor */ = { isa = XCSwiftPackageProductDependency; productName = CodeEditSourceEditor; diff --git a/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 9cb51d677a..9adc05afe6 100644 --- a/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "2fa7c60efc338d0f03199598f0092f98e50b91e5117f3b0f4ed3dbb35f45b701", + "originHash" : "4609370d19df4e0c3099cc09a290c4badc33969ef8a1687fbc4ef73c62133e13", "pins" : [ { "identity" : "anycodable", @@ -22,7 +22,7 @@ { "identity" : "codeeditsourceeditor", "kind" : "remoteSourceControl", - "location" : "https://github.com/CodeEditApp/CodeEditSourceEditor.git", + "location" : "https://github.com/CodeEditApp/CodeEditSourceEditor", "state" : { "revision" : "cf85789d527d569e94edfd674c5ac8071b244dd9", "version" : "0.7.3" diff --git a/CodeEdit/Features/LSP/LSPEventHandler.swift b/CodeEdit/Features/LSP/LSPEventHandler.swift index 1cdcb88231..1cfc9ec2f1 100644 --- a/CodeEdit/Features/LSP/LSPEventHandler.swift +++ b/CodeEdit/Features/LSP/LSPEventHandler.swift @@ -10,7 +10,7 @@ import LanguageServerProtocol extension LSPService { - internal func startListeningToEvents(for languageId: LanguageIdentifier) { + func startListeningToEvents(for languageId: LanguageIdentifier) { guard let languageClient = languageClients[languageId] else { logger.error("Language client not found for \(languageId.rawValue)") return @@ -25,7 +25,7 @@ extension LSPService { eventListeningTasks[languageId] = task } - internal func stopListeningToEvents(for languageId: LanguageIdentifier) { + func stopListeningToEvents(for languageId: LanguageIdentifier) { if let task = eventListeningTasks[languageId] { task.cancel() eventListeningTasks.removeValue(forKey: languageId) diff --git a/CodeEdit/Features/LSP/LSPService.swift b/CodeEdit/Features/LSP/LSPService.swift index 2359f22451..4838ca0969 100644 --- a/CodeEdit/Features/LSP/LSPService.swift +++ b/CodeEdit/Features/LSP/LSPService.swift @@ -11,45 +11,41 @@ import Foundation import LanguageClient import LanguageServerProtocol -/** - `LSPService` is a service class responsible for managing the lifecycle and event handling - of Language Server Protocol (LSP) clients within the CodeEdit application. It handles the initialization, - communication, and termination of language servers, ensuring that code assistance features - such as code completion, diagnostics, and more are available for various programming languages. - - This class uses Swift's concurrency model to manage background tasks and event streams - efficiently. Each language server runs in its own asynchronous task, listening for events and - handling them as they occur. The `LSPService` class also provides functionality to start - and stop individual language servers, as well as to stop all running servers. - - ## Example Usage - ```swift - @Service var lspService - - try await lspService.startServer( - for: .python, - projectURL: projectURL, - workspaceFolders: workspaceFolders - ) - try await lspService.stopServer(for: .python) - ``` -*/ +/// `LSPService` is a service class responsible for managing the lifecycle and event handling +/// of Language Server Protocol (LSP) clients within the CodeEdit application. It handles the initialization, +/// communication, and termination of language servers, ensuring that code assistance features +/// such as code completion, diagnostics, and more are available for various programming languages. +/// +/// This class uses Swift's concurrency model to manage background tasks and event streams +/// efficiently. Each language server runs in its own asynchronous task, listening for events and +/// handling them as they occur. The `LSPService` class also provides functionality to start +/// and stop individual language servers, as well as to stop all running servers. +/// +/// ## Example Usage +/// ```swift +/// @Service var lspService +/// +/// try await lspService.startServer( +/// for: .python, +/// projectURL: projectURL, +/// workspaceFolders: workspaceFolders +/// ) +/// try await lspService.stopServer(for: .python) +/// ``` final class LSPService: ObservableObject { + let logger: Logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "", category: "LSPService") - internal let logger: Logger /// Holds the active language clients - internal var languageClients: [LanguageIdentifier: LanguageServer] = [:] + var languageClients: [LanguageIdentifier: LanguageServer] = [:] /// Holds the language server configurations for all the installed language servers - internal var languageConfigs: [LanguageIdentifier: LanguageServerBinary] = [:] + var languageConfigs: [LanguageIdentifier: LanguageServerBinary] = [:] /// Holds all the event listeners for each active language client - internal var eventListeningTasks: [LanguageIdentifier: Task] = [:] + var eventListeningTasks: [LanguageIdentifier: Task] = [:] @AppSettings(\.developerSettings.lspBinaries) - internal var lspBinaries + var lspBinaries init() { - self.logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "", category: "LSPService") - // Load the LSP binaries from the developer menu for binary in lspBinaries { if let language = LanguageIdentifier(rawValue: binary.key) { diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+CallHierarchy.swift b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+CallHierarchy.swift similarity index 98% rename from CodeEdit/Features/LSP/LanguageClient/LanguageClient+CallHierarchy.swift rename to CodeEdit/Features/LSP/LanguageServer+/LanguageServer+CallHierarchy.swift index b7360edcc6..d01227a79c 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+CallHierarchy.swift +++ b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+CallHierarchy.swift @@ -1,5 +1,5 @@ // -// LanguageClient+CallHierarchy.swift +// LanguageServer+CallHierarchy.swift // CodeEdit // // Created by Abe Malla on 2/7/24. diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+ColorPresentation.swift b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+ColorPresentation.swift similarity index 94% rename from CodeEdit/Features/LSP/LanguageClient/LanguageClient+ColorPresentation.swift rename to CodeEdit/Features/LSP/LanguageServer+/LanguageServer+ColorPresentation.swift index 4c5ebdf0ad..070de5bfd5 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+ColorPresentation.swift +++ b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+ColorPresentation.swift @@ -1,5 +1,5 @@ // -// LanguageClient+ColorPresentation.swift +// LanguageServer+ColorPresentation.swift // CodeEdit // // Created by Abe Malla on 2/7/24. diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Completion.swift b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Completion.swift similarity index 96% rename from CodeEdit/Features/LSP/LanguageClient/LanguageClient+Completion.swift rename to CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Completion.swift index 5e411b8915..2b1a43a70e 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Completion.swift +++ b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Completion.swift @@ -1,5 +1,5 @@ // -// LanguageClient+Completion.swift +// LanguageServer+Completion.swift // CodeEdit // // Created by Abe Malla on 2/7/24. diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Declaration.swift b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Declaration.swift similarity index 94% rename from CodeEdit/Features/LSP/LanguageClient/LanguageClient+Declaration.swift rename to CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Declaration.swift index 41374f6bce..28aec4a609 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Declaration.swift +++ b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Declaration.swift @@ -1,5 +1,5 @@ // -// LanguageClient+Declaration.swift +// LanguageServer+Declaration.swift // CodeEdit // // Created by Abe Malla on 2/7/24. diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Definition.swift b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Definition.swift similarity index 96% rename from CodeEdit/Features/LSP/LanguageClient/LanguageClient+Definition.swift rename to CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Definition.swift index 87f38e78c7..394eb2f355 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Definition.swift +++ b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Definition.swift @@ -1,5 +1,5 @@ // -// LanguageClient+Definition.swift +// LanguageServer+Definition.swift // CodeEdit // // Created by Abe Malla on 2/7/24. diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Diagnostics.swift b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Diagnostics.swift similarity index 95% rename from CodeEdit/Features/LSP/LanguageClient/LanguageClient+Diagnostics.swift rename to CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Diagnostics.swift index 00329016f9..83bcda43f7 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Diagnostics.swift +++ b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Diagnostics.swift @@ -1,5 +1,5 @@ // -// LanguageClient+Diagnostics.swift +// LanguageServer+Diagnostics.swift // CodeEdit // // Created by Abe Malla on 2/7/24. diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentColor.swift b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+DocumentColor.swift similarity index 96% rename from CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentColor.swift rename to CodeEdit/Features/LSP/LanguageServer+/LanguageServer+DocumentColor.swift index 4599d327d5..711bc6ab74 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentColor.swift +++ b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+DocumentColor.swift @@ -1,5 +1,5 @@ // -// LanguageClient+DocumentColor.swift +// LanguageServer+DocumentColor.swift // CodeEdit // // Created by Abe Malla on 2/7/24. diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentHighlight.swift b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+DocumentHighlight.swift similarity index 95% rename from CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentHighlight.swift rename to CodeEdit/Features/LSP/LanguageServer+/LanguageServer+DocumentHighlight.swift index 7821be45f5..dec93142c7 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentHighlight.swift +++ b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+DocumentHighlight.swift @@ -1,5 +1,5 @@ // -// LanguageClient+DocumentHighlight.swift +// LanguageServer+DocumentHighlight.swift // CodeEdit // // Created by Abe Malla on 2/7/24. diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentLink.swift b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+DocumentLink.swift similarity index 95% rename from CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentLink.swift rename to CodeEdit/Features/LSP/LanguageServer+/LanguageServer+DocumentLink.swift index 1d75abc9f0..bf60d4e9ff 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentLink.swift +++ b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+DocumentLink.swift @@ -1,5 +1,5 @@ // -// LanguageClient+DocumentLink.swift +// LanguageServer+DocumentLink.swift // CodeEdit // // Created by Abe Malla on 2/7/24. diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentSymbol.swift b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+DocumentSymbol.swift similarity index 93% rename from CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentSymbol.swift rename to CodeEdit/Features/LSP/LanguageServer+/LanguageServer+DocumentSymbol.swift index 1a66968a7e..b224c7f4de 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentSymbol.swift +++ b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+DocumentSymbol.swift @@ -1,5 +1,5 @@ // -// LanguageClient+DocumentSymbol.swift +// LanguageServer+DocumentSymbol.swift // CodeEdit // // Created by Abe Malla on 2/7/24. diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentUtil.swift b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+DocumentUtil.swift similarity index 99% rename from CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentUtil.swift rename to CodeEdit/Features/LSP/LanguageServer+/LanguageServer+DocumentUtil.swift index 5c8ae04db3..5dda0c77f4 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+DocumentUtil.swift +++ b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+DocumentUtil.swift @@ -1,5 +1,5 @@ // -// LanguageClient+DocumentUtil.swift +// LanguageServer+DocumentUtil.swift // CodeEdit // // Created by Abe Malla on 2/7/24. diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+FoldingRange.swift b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+FoldingRange.swift similarity index 93% rename from CodeEdit/Features/LSP/LanguageClient/LanguageClient+FoldingRange.swift rename to CodeEdit/Features/LSP/LanguageServer+/LanguageServer+FoldingRange.swift index 1cd6e3ba7a..0e0c2b5b6d 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+FoldingRange.swift +++ b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+FoldingRange.swift @@ -1,5 +1,5 @@ // -// LanguageClient+FoldingRange.swift +// LanguageServer+FoldingRange.swift // CodeEdit // // Created by Abe Malla on 2/7/24. diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Formatting.swift b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Formatting.swift similarity index 98% rename from CodeEdit/Features/LSP/LanguageClient/LanguageClient+Formatting.swift rename to CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Formatting.swift index c4ced5c0f8..4de818e6c4 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Formatting.swift +++ b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Formatting.swift @@ -1,5 +1,5 @@ // -// LanguageClient+Formatting.swift +// LanguageServer+Formatting.swift // CodeEdit // // Created by Abe Malla on 2/7/24. diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Hover.swift b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Hover.swift similarity index 95% rename from CodeEdit/Features/LSP/LanguageClient/LanguageClient+Hover.swift rename to CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Hover.swift index 4aef5e2040..01c213d562 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Hover.swift +++ b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Hover.swift @@ -1,5 +1,5 @@ // -// LanguageClient+Hover.swift +// LanguageServer+Hover.swift // CodeEdit // // Created by Abe Malla on 2/7/24. diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Implementation.swift b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Implementation.swift similarity index 94% rename from CodeEdit/Features/LSP/LanguageClient/LanguageClient+Implementation.swift rename to CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Implementation.swift index 22d3296e9b..b22f978487 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Implementation.swift +++ b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Implementation.swift @@ -1,5 +1,5 @@ // -// LanguageClient+Implementation.swift +// LanguageServer+Implementation.swift // CodeEdit // // Created by Abe Malla on 2/7/24. diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+InlayHint.swift b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+InlayHint.swift similarity index 97% rename from CodeEdit/Features/LSP/LanguageClient/LanguageClient+InlayHint.swift rename to CodeEdit/Features/LSP/LanguageServer+/LanguageServer+InlayHint.swift index c882d34430..2bc9cbca2d 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+InlayHint.swift +++ b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+InlayHint.swift @@ -1,5 +1,5 @@ // -// LanguageClient+InlayHint.swift +// LanguageServer+InlayHint.swift // CodeEdit // // Created by Abe Malla on 2/7/24. diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+References.swift b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+References.swift similarity index 95% rename from CodeEdit/Features/LSP/LanguageClient/LanguageClient+References.swift rename to CodeEdit/Features/LSP/LanguageServer+/LanguageServer+References.swift index 47aaab063b..56c8737cfa 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+References.swift +++ b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+References.swift @@ -1,5 +1,5 @@ // -// LanguageClient+References.swift +// LanguageServer+References.swift // CodeEdit // // Created by Abe Malla on 2/7/24. diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Rename.swift b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Rename.swift similarity index 97% rename from CodeEdit/Features/LSP/LanguageClient/LanguageClient+Rename.swift rename to CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Rename.swift index 314135a223..7fa5e3f2c3 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+Rename.swift +++ b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Rename.swift @@ -1,5 +1,5 @@ // -// LanguageClient+Rename.swift +// LanguageServer+Rename.swift // CodeEdit // // Created by Abe Malla on 2/7/24. diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+SelectionRange.swift b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+SelectionRange.swift similarity index 94% rename from CodeEdit/Features/LSP/LanguageClient/LanguageClient+SelectionRange.swift rename to CodeEdit/Features/LSP/LanguageServer+/LanguageServer+SelectionRange.swift index c0f2795a7e..328c8f5620 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+SelectionRange.swift +++ b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+SelectionRange.swift @@ -1,5 +1,5 @@ // -// LanguageClient+SelectionRange.swift +// LanguageServer+SelectionRange.swift // CodeEdit // // Created by Abe Malla on 2/7/24. diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+SemanticTokens.swift b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+SemanticTokens.swift similarity index 97% rename from CodeEdit/Features/LSP/LanguageClient/LanguageClient+SemanticTokens.swift rename to CodeEdit/Features/LSP/LanguageServer+/LanguageServer+SemanticTokens.swift index 4918699474..76e5b13966 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+SemanticTokens.swift +++ b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+SemanticTokens.swift @@ -1,5 +1,5 @@ // -// LanguageClient+SemanticTokens.swift +// LanguageServer+SemanticTokens.swift // CodeEdit // // Created by Abe Malla on 2/7/24. diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+SignatureHelp.swift b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+SignatureHelp.swift similarity index 94% rename from CodeEdit/Features/LSP/LanguageClient/LanguageClient+SignatureHelp.swift rename to CodeEdit/Features/LSP/LanguageServer+/LanguageServer+SignatureHelp.swift index 93dfe5629f..1fd3c991b2 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+SignatureHelp.swift +++ b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+SignatureHelp.swift @@ -1,5 +1,5 @@ // -// LanguageClient+SignatureHelp.swift +// LanguageServer+SignatureHelp.swift // CodeEdit // // Created by Abe Malla on 2/7/24. diff --git a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+TypeDefinition.swift b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+TypeDefinition.swift similarity index 94% rename from CodeEdit/Features/LSP/LanguageClient/LanguageClient+TypeDefinition.swift rename to CodeEdit/Features/LSP/LanguageServer+/LanguageServer+TypeDefinition.swift index a6f9a90a60..3b68a6a5b3 100644 --- a/CodeEdit/Features/LSP/LanguageClient/LanguageClient+TypeDefinition.swift +++ b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+TypeDefinition.swift @@ -1,5 +1,5 @@ // -// LanguageClient+TypeDefinition.swift +// LanguageServer+TypeDefinition.swift // CodeEdit // // Created by Abe Malla on 2/7/24. From 665839b8b8dc77d25b21fa992050ffbcaa6c03b8 Mon Sep 17 00:00:00 2001 From: Khan Winter <35942988+thecoolwinter@users.noreply.github.com> Date: Sat, 15 Jun 2024 18:47:58 -0500 Subject: [PATCH 14/20] Use `AnyHashable` --- CodeEdit/Features/LSP/LSPCache.swift | 30 +++------------------------- 1 file changed, 3 insertions(+), 27 deletions(-) diff --git a/CodeEdit/Features/LSP/LSPCache.swift b/CodeEdit/Features/LSP/LSPCache.swift index c45d78d105..c15ff5860e 100644 --- a/CodeEdit/Features/LSP/LSPCache.swift +++ b/CodeEdit/Features/LSP/LSPCache.swift @@ -7,41 +7,17 @@ import Foundation -struct AnyHashableData: Hashable { - private let value: Any - private let hashValueFunc: () -> Int - private let equalsFunc: (Any) -> Bool - - init(_ value: T) { - self.value = value - self.hashValueFunc = { value.hashValue } - self.equalsFunc = { ($0 as? T) == value } - } - - static func == (lhs: AnyHashableData, rhs: AnyHashableData) -> Bool { - return lhs.equalsFunc(rhs.value) - } - - func hash(into hasher: inout Hasher) { - hasher.combine(hashValueFunc()) - } - - var description: String { - return String(describing: value) - } -} - struct NoExtraData: Hashable { } struct CacheKey: Hashable { let uri: String let requestType: String - let extraData: AnyHashableData? + let extraData: AnyHashable? - init(uri: String, requestType: String, extraData: ExtraData? = nil) { + init(uri: String, requestType: String, extraData: AnyHashable? = nil) { self.uri = uri self.requestType = requestType - self.extraData = extraData.map(AnyHashableData.init) + self.extraData = extraData } static func == (lhs: CacheKey, rhs: CacheKey) -> Bool { From 93e61389690542494d28747530005703f7c49a1b Mon Sep 17 00:00:00 2001 From: Khan Winter <35942988+thecoolwinter@users.noreply.github.com> Date: Sat, 15 Jun 2024 18:53:47 -0500 Subject: [PATCH 15/20] Add `LSPCompletionItemsUtil` Namespace --- CodeEdit/Features/LSP/LSPService.swift | 10 ++++- CodeEdit/Features/LSP/LSPUtil.swift | 61 ++++++++++++++++---------- 2 files changed, 45 insertions(+), 26 deletions(-) diff --git a/CodeEdit/Features/LSP/LSPService.swift b/CodeEdit/Features/LSP/LSPService.swift index 4838ca0969..d0555cc0f5 100644 --- a/CodeEdit/Features/LSP/LSPService.swift +++ b/CodeEdit/Features/LSP/LSPService.swift @@ -140,7 +140,10 @@ final class LSPService: ObservableObject { // Handle the case where completions is an array of CompletionItem print("\n*******\nCompletion Items:\n*******\n") for item in completionItems { - let textEdits = getCompletionItemEdits(startPosition: textPosition, item: item) + let textEdits = LSPCompletionItemsUtil.getCompletionItemEdits( + startPosition: textPosition, + item: item + ) for edit in textEdits { print(edit) } @@ -150,7 +153,10 @@ final class LSPService: ObservableObject { // Handle the case where completions is a CompletionList print("\n*******\nCompletion Items:\n*******\n") for item in completionList.items { - let textEdits = getCompletionItemEdits(startPosition: textPosition, item: item) + let textEdits = LSPCompletionItemsUtil.getCompletionItemEdits( + startPosition: textPosition, + item: item + ) for edit in textEdits { print(edit) } diff --git a/CodeEdit/Features/LSP/LSPUtil.swift b/CodeEdit/Features/LSP/LSPUtil.swift index 07af5d1b73..740a821041 100644 --- a/CodeEdit/Features/LSP/LSPUtil.swift +++ b/CodeEdit/Features/LSP/LSPUtil.swift @@ -8,16 +8,37 @@ import Foundation import LanguageServerProtocol -/// Helper function to get the edits from a completion item -/// - Parameters: -/// - startPosition: The position where the completion was requested -/// - item: The completion item -/// - Returns: An array of TextEdit objects -func getCompletionItemEdits(startPosition: Position, item: CompletionItem) -> [TextEdit] { - var edits: [TextEdit] = [] - - // If a TextEdit or InsertReplaceEdit value was provided - if let edit = item.textEdit { +enum LSPCompletionItemsUtil { + + /// Helper function to get the edits from a completion item + /// - Parameters: + /// - startPosition: The position where the completion was requested + /// - item: The completion item + /// - Returns: An array of TextEdit objects + static func getCompletionItemEdits(startPosition: Position, item: CompletionItem) -> [TextEdit] { + var edits: [TextEdit] = [] + + // If a TextEdit or InsertReplaceEdit value was provided + if let edit = item.textEdit { + editOrReplaceItem(edit: edit, &edits) + } else if let insertText = item.insertText { + // If the `insertText` value was provided + insertTextItem(startPosition: startPosition, insertText: insertText, &edits) + } else if !item.label.isEmpty { + // Fallback to the label + labelItem(startPosition: startPosition, label: item.label, &edits) + } + + // If additional edits were provided + // An example would be to also include an 'import' statement at the top of the file + if let additionalEdits = item.additionalTextEdits { + edits.append(contentsOf: additionalEdits) + } + + return edits + } + + private static func editOrReplaceItem(edit: TwoTypeOption, _ edits: inout [TextEdit]) { switch edit { case .optionA(let textEdit): edits.append(textEdit) @@ -30,8 +51,8 @@ func getCompletionItemEdits(startPosition: Position, item: CompletionItem) -> [T ) } } - // If the `insertText` value was provided - else if let insertText = item.insertText { + + private static func insertTextItem(startPosition: Position, insertText: String, _ edits: inout [TextEdit]) { let endPosition = Position((startPosition.line, startPosition.character + insertText.count)) edits.append( TextEdit( @@ -40,22 +61,14 @@ func getCompletionItemEdits(startPosition: Position, item: CompletionItem) -> [T ) ) } - // Fallback to the label - else if item.label != "" { - let endPosition = Position((startPosition.line, startPosition.character + item.label.count)) + + private static func labelItem(startPosition: Position, label: String, _ edits: inout [TextEdit]) { + let endPosition = Position((startPosition.line, startPosition.character + label.count)) edits.append( TextEdit( range: LSPRange(start: startPosition, end: endPosition), - newText: item.label + newText: label ) ) } - - // If additional edits were provided - // An example would be to also include an 'import' statement at the top of the file - if let additionalEdits = item.additionalTextEdits { - edits.append(contentsOf: additionalEdits) - } - - return edits } From 3203b5895a319d3e987c7442abbccc3912c72061 Mon Sep 17 00:00:00 2001 From: Khan Winter <35942988+thecoolwinter@users.noreply.github.com> Date: Sat, 15 Jun 2024 19:25:54 -0500 Subject: [PATCH 16/20] Spruce up the lsp binary menu --- .../CodeEditUI/Views/KeyValueTable.swift | 98 +++++++++++-------- .../DeveloperSettingsView.swift | 2 + 2 files changed, 58 insertions(+), 42 deletions(-) diff --git a/CodeEdit/Features/CodeEditUI/Views/KeyValueTable.swift b/CodeEdit/Features/CodeEditUI/Views/KeyValueTable.swift index 46ce8d3bce..edaa883059 100644 --- a/CodeEdit/Features/CodeEditUI/Views/KeyValueTable.swift +++ b/CodeEdit/Features/CodeEditUI/Views/KeyValueTable.swift @@ -23,6 +23,7 @@ private struct NewListTableItemView: View { let keyColumnName: String let valueColumnName: String let newItemInstruction: String + let validKeys: [String] let headerView: AnyView? var completion: (String, String) -> Void @@ -30,12 +31,14 @@ private struct NewListTableItemView: View { _ keyColumnName: String, _ valueColumnName: String, _ newItemInstruction: String, + validKeys: [String], headerView: AnyView? = nil, completion: @escaping (String, String) -> Void ) { self.keyColumnName = keyColumnName self.valueColumnName = valueColumnName self.newItemInstruction = newItemInstruction + self.validKeys = validKeys self.headerView = headerView self.completion = completion } @@ -44,8 +47,18 @@ private struct NewListTableItemView: View { VStack(spacing: 0) { Form { Section { - TextField(keyColumnName, text: $key) - .textFieldStyle(.plain) + if validKeys.isEmpty { + TextField(keyColumnName, text: $key) + .textFieldStyle(.plain) + } else { + Picker(keyColumnName, selection: $key) { + ForEach(validKeys, id: \.self) { key in + Text(key).tag(key) + } + Divider() + Text("No Selection").tag("") + } + } TextField(valueColumnName, text: $value) .textFieldStyle(.plain) } header: { @@ -75,7 +88,6 @@ private struct NewListTableItemView: View { .disabled(key.isEmpty || value.isEmpty) } .padding(.horizontal, 20) -// .padding(.top, 2) .padding(.bottom, 20) } .frame(maxWidth: 480) @@ -85,6 +97,7 @@ private struct NewListTableItemView: View { struct KeyValueTable: View { @Binding var items: [String: String] + let validKeys: [String] let keyColumnName: String let valueColumnName: String let newItemInstruction: String @@ -96,12 +109,14 @@ struct KeyValueTable: View { init( items: Binding<[String: String]>, + validKeys: [String] = [], keyColumnName: String, valueColumnName: String, newItemInstruction: String, @ViewBuilder header: @escaping () -> Header = { EmptyView() } ) { self._items = items + self.validKeys = validKeys self.keyColumnName = keyColumnName self.valueColumnName = valueColumnName self.newItemInstruction = newItemInstruction @@ -109,52 +124,51 @@ struct KeyValueTable: View { } var body: some View { - VStack { - Table(tableItems, selection: $selection) { - TableColumn(keyColumnName) { item in - Text(item.key) - } - TableColumn(valueColumnName) { item in - Text(item.value) - } + Table(tableItems, selection: $selection) { + TableColumn(keyColumnName) { item in + Text(item.key) } - .frame(height: 200) - .actionBar { - HStack(spacing: 2) { - Button { - showingModal = true - } label: { - Image(systemName: "plus") - } + TableColumn(valueColumnName) { item in + Text(item.value) + } + } + .frame(height: 200) + .actionBar { + HStack(spacing: 2) { + Button { + showingModal = true + } label: { + Image(systemName: "plus") + } - Divider() - .frame(minHeight: 15) + Divider() + .frame(minHeight: 15) - Button { - removeItem() - } label: { - Image(systemName: "minus") - } - .disabled(selection == nil) - .opacity(selection == nil ? 0.5 : 1) + Button { + removeItem() + } label: { + Image(systemName: "minus") } - Spacer() + .disabled(selection == nil) + .opacity(selection == nil ? 0.5 : 1) } - .sheet(isPresented: $showingModal) { - NewListTableItemView( - keyColumnName, - valueColumnName, - newItemInstruction, - headerView: AnyView(header()) - ) { key, value in - items[key] = value - updateTableItems() - showingModal = false - } + Spacer() + } + .sheet(isPresented: $showingModal) { + NewListTableItemView( + keyColumnName, + valueColumnName, + newItemInstruction, + validKeys: validKeys, + headerView: AnyView(header()) + ) { key, value in + items[key] = value + updateTableItems() + showingModal = false } - .cornerRadius(6) - .onAppear(perform: updateTableItems) } + .cornerRadius(6) + .onAppear(perform: updateTableItems) } private func updateTableItems() { diff --git a/CodeEdit/Features/Settings/Pages/DeveloperSettings/DeveloperSettingsView.swift b/CodeEdit/Features/Settings/Pages/DeveloperSettings/DeveloperSettingsView.swift index 315c5e1c5a..fa552ace93 100644 --- a/CodeEdit/Features/Settings/Pages/DeveloperSettings/DeveloperSettingsView.swift +++ b/CodeEdit/Features/Settings/Pages/DeveloperSettings/DeveloperSettingsView.swift @@ -6,6 +6,7 @@ // import SwiftUI +import LanguageServerProtocol /// A view that implements the Developer settings section struct DeveloperSettingsView: View { @@ -17,6 +18,7 @@ struct DeveloperSettingsView: View { Section { KeyValueTable( items: $lspBinaries, + validKeys: LanguageIdentifier.allCases.map { $0.rawValue }, keyColumnName: "Language", valueColumnName: "Language Server Path", newItemInstruction: "Add a language server" From 221414566be2bcc5ded3589beaeba3f538393e03 Mon Sep 17 00:00:00 2001 From: Abe M Date: Tue, 18 Jun 2024 20:58:46 -0700 Subject: [PATCH 17/20] Propagate error, remove commented function --- .../xcshareddata/swiftpm/Package.resolved | 4 ++-- CodeEdit/Features/LSP/LSPService.swift | 3 ++- .../LanguageServer+/LanguageServer+DocumentLink.swift | 11 ++--------- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 9adc05afe6..adbbbec8af 100644 --- a/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "4609370d19df4e0c3099cc09a290c4badc33969ef8a1687fbc4ef73c62133e13", + "originHash" : "a5aaedb8104c5585252b9ff590dace9dae6a8a64b4ead61dfc33bf264504304b", "pins" : [ { "identity" : "anycodable", @@ -22,7 +22,7 @@ { "identity" : "codeeditsourceeditor", "kind" : "remoteSourceControl", - "location" : "https://github.com/CodeEditApp/CodeEditSourceEditor", + "location" : "https://github.com/CodeEditApp/CodeEditSourceEditor.git", "state" : { "revision" : "cf85789d527d569e94edfd674c5ac8071b244dd9", "version" : "0.7.3" diff --git a/CodeEdit/Features/LSP/LSPService.swift b/CodeEdit/Features/LSP/LSPService.swift index d0555cc0f5..bb38f41160 100644 --- a/CodeEdit/Features/LSP/LSPService.swift +++ b/CodeEdit/Features/LSP/LSPService.swift @@ -185,7 +185,8 @@ final class LSPService: ObservableObject { do { try await server.shutdownAndExit() } catch { - logger.error("Failed to stop server for language \(languageId.rawValue)") + logger.error("Failed to stop server for language \(languageId.rawValue): \(error.localizedDescription)") + throw error } languageClients.removeValue(forKey: languageId) logger.info("Server stopped for language \(languageId.rawValue)") diff --git a/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+DocumentLink.swift b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+DocumentLink.swift index bf60d4e9ff..075729f914 100644 --- a/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+DocumentLink.swift +++ b/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+DocumentLink.swift @@ -8,16 +8,9 @@ import Foundation import LanguageServerProtocol -extension LanguageServer { -// func requestDocumentLink() async -> DocumentLinkResponse { -// do { -// // TODO: DocumentLinkParams IS MISSING `textDocument: TextDocumentIdentifier;` FIELD IN LSP LIBRARY -// } catch { -// print("requestDocumentLink Error: \(error)") -// } -// return [] -// } +// TODO: DocumentLinkParams IS MISSING `textDocument: TextDocumentIdentifier;` FIELD IN LSP LIBRARY +extension LanguageServer { func requestDocumentLinkResolve(_ documentLink: DocumentLink) async -> DocumentLink? { do { return try await lspInstance.documentLinkResolve(documentLink) From 82363295e5072ff210be5f91c97b8662d5203452 Mon Sep 17 00:00:00 2001 From: Abe M Date: Fri, 21 Jun 2024 15:30:08 -0700 Subject: [PATCH 18/20] Update CodeEditKit --- CodeEdit.xcodeproj/project.pbxproj | 19 ++++++++++--------- .../xcshareddata/swiftpm/Package.resolved | 11 ++++++++++- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/CodeEdit.xcodeproj/project.pbxproj b/CodeEdit.xcodeproj/project.pbxproj index b25af250a8..d24493d34d 100644 --- a/CodeEdit.xcodeproj/project.pbxproj +++ b/CodeEdit.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 60; + objectVersion = 55; objects = { /* Begin PBXBuildFile section */ @@ -3349,7 +3349,7 @@ 6C0617D42BDB4432008C9C42 /* XCRemoteSwiftPackageReference "LogStream" */, 30CB648F2C16CA8100CC8A9E /* XCRemoteSwiftPackageReference "LanguageServerProtocol" */, 30CB64922C16CA9100CC8A9E /* XCRemoteSwiftPackageReference "LanguageClient" */, - 6C85BB3A2C1E3D1000EB5DEF /* XCLocalSwiftPackageReference "../CodeEditKit" */, + 305F53292C26363200EC94BA /* XCRemoteSwiftPackageReference "CodeEditKit" */, ); productRefGroup = B658FB2D27DA9E0F00EA4DBD /* Products */; projectDirPath = ""; @@ -5050,13 +5050,6 @@ }; /* End XCConfigurationList section */ -/* Begin XCLocalSwiftPackageReference section */ - 6C85BB3A2C1E3D1000EB5DEF /* XCLocalSwiftPackageReference "../CodeEditKit" */ = { - isa = XCLocalSwiftPackageReference; - relativePath = ../CodeEditKit; - }; -/* End XCLocalSwiftPackageReference section */ - /* Begin XCRemoteSwiftPackageReference section */ 2816F592280CF50500DD548B /* XCRemoteSwiftPackageReference "CodeEditSymbols" */ = { isa = XCRemoteSwiftPackageReference; @@ -5074,6 +5067,14 @@ minimumVersion = 0.2.2; }; }; + 305F53292C26363200EC94BA /* XCRemoteSwiftPackageReference "CodeEditKit" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/CodeEditApp/CodeEditKit.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 0.1.0; + }; + }; 30CB648F2C16CA8100CC8A9E /* XCRemoteSwiftPackageReference "LanguageServerProtocol" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/ChimeHQ/LanguageServerProtocol"; diff --git a/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index adbbbec8af..d07b560e84 100644 --- a/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "a5aaedb8104c5585252b9ff590dace9dae6a8a64b4ead61dfc33bf264504304b", + "originHash" : "3f435bbb242e2262b1bdd6b6f5508ee8a8a9efac204b80f77dd8fae7187a710b", "pins" : [ { "identity" : "anycodable", @@ -10,6 +10,15 @@ "version" : "0.6.7" } }, + { + "identity" : "codeeditkit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/CodeEditApp/CodeEditKit.git", + "state" : { + "revision" : "ad28213a968586abb0cb21a8a56a3587227895f1", + "version" : "0.1.2" + } + }, { "identity" : "codeeditlanguages", "kind" : "remoteSourceControl", From bfa8dc099b2b6d734672a3cbe9c61aac937807fe Mon Sep 17 00:00:00 2001 From: Abe M Date: Sat, 22 Jun 2024 13:49:05 -0700 Subject: [PATCH 19/20] Add internal --- CodeEdit.xcodeproj/project.pbxproj | 28 ++++++++++++-------------- CodeEdit/Features/LSP/LSPService.swift | 10 ++++----- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/CodeEdit.xcodeproj/project.pbxproj b/CodeEdit.xcodeproj/project.pbxproj index 4b2d380257..5002cb67ce 100644 --- a/CodeEdit.xcodeproj/project.pbxproj +++ b/CodeEdit.xcodeproj/project.pbxproj @@ -351,7 +351,6 @@ 6C4104E6297C884F00F472BA /* AboutDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C4104E5297C884F00F472BA /* AboutDetailView.swift */; }; 6C4104E9297C970F00F472BA /* AboutDefaultView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C4104E8297C970F00F472BA /* AboutDefaultView.swift */; }; 6C48B5C52C0A2835001E9955 /* FileEncoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C48B5C42C0A2835001E9955 /* FileEncoding.swift */; }; - 6C48B5C92C0B5F7A001E9955 /* NSTextStorage+isEmpty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C48B5C72C0B5F7A001E9955 /* NSTextStorage+isEmpty.swift */; }; 6C48B5CE2C0C1BE4001E9955 /* Shell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C48B5CD2C0C1BE4001E9955 /* Shell.swift */; }; 6C48B5D12C0D0519001E9955 /* ShellIntegration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C48B5D02C0D0519001E9955 /* ShellIntegration.swift */; }; 6C48B5D42C0D0743001E9955 /* codeedit_shell_integration_env.zsh in Resources */ = {isa = PBXBuildFile; fileRef = 6C48B5D32C0D0743001E9955 /* codeedit_shell_integration_env.zsh */; }; @@ -957,7 +956,6 @@ 6C4104E5297C884F00F472BA /* AboutDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutDetailView.swift; sourceTree = ""; }; 6C4104E8297C970F00F472BA /* AboutDefaultView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutDefaultView.swift; sourceTree = ""; }; 6C48B5C42C0A2835001E9955 /* FileEncoding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileEncoding.swift; sourceTree = ""; }; - 6C48B5C72C0B5F7A001E9955 /* NSTextStorage+isEmpty.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSTextStorage+isEmpty.swift"; sourceTree = ""; }; 6C48B5CD2C0C1BE4001E9955 /* Shell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Shell.swift; sourceTree = ""; }; 6C48B5D02C0D0519001E9955 /* ShellIntegration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShellIntegration.swift; sourceTree = ""; }; 6C48B5D32C0D0743001E9955 /* codeedit_shell_integration_env.zsh */ = {isa = PBXFileReference; lastKnownFileType = text; path = codeedit_shell_integration_env.zsh; sourceTree = ""; }; @@ -1166,7 +1164,6 @@ 6C66C31329D05CDC00DE9ED2 /* GRDB in Frameworks */, 58F2EB1E292FB954004A9BDE /* Sparkle in Frameworks */, 6CBE1D002B720565003AC32E /* CodeEditSourceEditor in Frameworks */, - 6C85BB3C2C1E3D1000EB5DEF /* CodeEditKit in Frameworks */, 6C147C4529A329350089B630 /* OrderedCollections in Frameworks */, 6C0617D62BDB4432008C9C42 /* LogStream in Frameworks */, 30CB64912C16CA8100CC8A9E /* LanguageServerProtocol in Frameworks */, @@ -2567,15 +2564,6 @@ path = TerminalEmulator; sourceTree = ""; }; - 6C48B5C82C0B5F7A001E9955 /* NSTextStorage */ = { - isa = PBXGroup; - children = ( - 6C48B5C72C0B5F7A001E9955 /* NSTextStorage+isEmpty.swift */, - ); - name = NSTextStorage; - path = CodeEdit/Utils/Extensions/NSTextStorage; - sourceTree = SOURCE_ROOT; - }; 6C48B5DB2C0D664A001E9955 /* Model */ = { isa = PBXGroup; children = ( @@ -3339,6 +3327,8 @@ 6C0617D42BDB4432008C9C42 /* XCRemoteSwiftPackageReference "LogStream" */, 6C85BB3E2C2105ED00EB5DEF /* XCRemoteSwiftPackageReference "CodeEditKit" */, 6C85BB422C210EFD00EB5DEF /* XCRemoteSwiftPackageReference "SwiftUI-Introspect" */, + 303E88452C276FD100EEA8D9 /* XCRemoteSwiftPackageReference "LanguageClient" */, + 303E88462C276FD600EEA8D9 /* XCRemoteSwiftPackageReference "LanguageServerProtocol" */, ); productRefGroup = B658FB2D27DA9E0F00EA4DBD /* Products */; projectDirPath = ""; @@ -5057,12 +5047,20 @@ minimumVersion = 0.2.2; }; }; - 305F53292C26363200EC94BA /* XCRemoteSwiftPackageReference "CodeEditKit" */ = { + 303E88452C276FD100EEA8D9 /* XCRemoteSwiftPackageReference "LanguageClient" */ = { isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/CodeEditApp/CodeEditKit.git"; + repositoryURL = "https://github.com/ChimeHQ/LanguageClient"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.1.0; + minimumVersion = 0.8.0; + }; + }; + 303E88462C276FD600EEA8D9 /* XCRemoteSwiftPackageReference "LanguageServerProtocol" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/ChimeHQ/LanguageServerProtocol"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 0.13.2; }; }; 30CB648F2C16CA8100CC8A9E /* XCRemoteSwiftPackageReference "LanguageServerProtocol" */ = { diff --git a/CodeEdit/Features/LSP/LSPService.swift b/CodeEdit/Features/LSP/LSPService.swift index bb38f41160..984468b54e 100644 --- a/CodeEdit/Features/LSP/LSPService.swift +++ b/CodeEdit/Features/LSP/LSPService.swift @@ -33,17 +33,17 @@ import LanguageServerProtocol /// try await lspService.stopServer(for: .python) /// ``` final class LSPService: ObservableObject { - let logger: Logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "", category: "LSPService") + internal let logger: Logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "", category: "LSPService") /// Holds the active language clients - var languageClients: [LanguageIdentifier: LanguageServer] = [:] + internal var languageClients: [LanguageIdentifier: LanguageServer] = [:] /// Holds the language server configurations for all the installed language servers - var languageConfigs: [LanguageIdentifier: LanguageServerBinary] = [:] + internal var languageConfigs: [LanguageIdentifier: LanguageServerBinary] = [:] /// Holds all the event listeners for each active language client - var eventListeningTasks: [LanguageIdentifier: Task] = [:] + internal var eventListeningTasks: [LanguageIdentifier: Task] = [:] @AppSettings(\.developerSettings.lspBinaries) - var lspBinaries + internal var lspBinaries init() { // Load the LSP binaries from the developer menu From 469aa27a66801dafb8fa40c9050dc80f94a8e88d Mon Sep 17 00:00:00 2001 From: Abe M Date: Sun, 23 Jun 2024 02:43:45 -0700 Subject: [PATCH 20/20] Added suggestions --- CodeEdit.xcodeproj/project.pbxproj | 10 +++- .../CodeEditUI/Views/AreaTabBar.swift | 3 +- CodeEdit/Features/LSP/LSPCache+Data.swift | 36 ++++++++++++ CodeEdit/Features/LSP/LSPCache.swift | 58 +++++-------------- CodeEdit/Features/LSP/LSPEventHandler.swift | 4 +- CodeEdit/Features/LSP/LSPService.swift | 2 +- .../LanguageServer+CallHierarchy.swift | 0 .../LanguageServer+ColorPresentation.swift | 0 .../LanguageServer+Completion.swift | 0 .../LanguageServer+Declaration.swift | 0 .../LanguageServer+Definition.swift | 0 .../LanguageServer+Diagnostics.swift | 0 .../LanguageServer+DocumentColor.swift | 0 .../LanguageServer+DocumentHighlight.swift | 0 .../LanguageServer+DocumentLink.swift | 0 .../LanguageServer+DocumentSymbol.swift | 0 .../LanguageServer+DocumentUtil.swift | 0 .../LanguageServer+FoldingRange.swift | 0 .../LanguageServer+Formatting.swift | 0 .../LanguageServer+Hover.swift | 0 .../LanguageServer+Implementation.swift | 0 .../LanguageServer+InlayHint.swift | 0 .../LanguageServer+References.swift | 0 .../LanguageServer+Rename.swift | 0 .../LanguageServer+SelectionRange.swift | 0 .../LanguageServer+SemanticTokens.swift | 0 .../LanguageServer+SignatureHelp.swift | 0 .../LanguageServer+TypeDefinition.swift | 0 28 files changed, 61 insertions(+), 52 deletions(-) create mode 100644 CodeEdit/Features/LSP/LSPCache+Data.swift rename CodeEdit/Features/LSP/{LanguageServer+ => LanguageServerExtensions}/LanguageServer+CallHierarchy.swift (100%) rename CodeEdit/Features/LSP/{LanguageServer+ => LanguageServerExtensions}/LanguageServer+ColorPresentation.swift (100%) rename CodeEdit/Features/LSP/{LanguageServer+ => LanguageServerExtensions}/LanguageServer+Completion.swift (100%) rename CodeEdit/Features/LSP/{LanguageServer+ => LanguageServerExtensions}/LanguageServer+Declaration.swift (100%) rename CodeEdit/Features/LSP/{LanguageServer+ => LanguageServerExtensions}/LanguageServer+Definition.swift (100%) rename CodeEdit/Features/LSP/{LanguageServer+ => LanguageServerExtensions}/LanguageServer+Diagnostics.swift (100%) rename CodeEdit/Features/LSP/{LanguageServer+ => LanguageServerExtensions}/LanguageServer+DocumentColor.swift (100%) rename CodeEdit/Features/LSP/{LanguageServer+ => LanguageServerExtensions}/LanguageServer+DocumentHighlight.swift (100%) rename CodeEdit/Features/LSP/{LanguageServer+ => LanguageServerExtensions}/LanguageServer+DocumentLink.swift (100%) rename CodeEdit/Features/LSP/{LanguageServer+ => LanguageServerExtensions}/LanguageServer+DocumentSymbol.swift (100%) rename CodeEdit/Features/LSP/{LanguageServer+ => LanguageServerExtensions}/LanguageServer+DocumentUtil.swift (100%) rename CodeEdit/Features/LSP/{LanguageServer+ => LanguageServerExtensions}/LanguageServer+FoldingRange.swift (100%) rename CodeEdit/Features/LSP/{LanguageServer+ => LanguageServerExtensions}/LanguageServer+Formatting.swift (100%) rename CodeEdit/Features/LSP/{LanguageServer+ => LanguageServerExtensions}/LanguageServer+Hover.swift (100%) rename CodeEdit/Features/LSP/{LanguageServer+ => LanguageServerExtensions}/LanguageServer+Implementation.swift (100%) rename CodeEdit/Features/LSP/{LanguageServer+ => LanguageServerExtensions}/LanguageServer+InlayHint.swift (100%) rename CodeEdit/Features/LSP/{LanguageServer+ => LanguageServerExtensions}/LanguageServer+References.swift (100%) rename CodeEdit/Features/LSP/{LanguageServer+ => LanguageServerExtensions}/LanguageServer+Rename.swift (100%) rename CodeEdit/Features/LSP/{LanguageServer+ => LanguageServerExtensions}/LanguageServer+SelectionRange.swift (100%) rename CodeEdit/Features/LSP/{LanguageServer+ => LanguageServerExtensions}/LanguageServer+SemanticTokens.swift (100%) rename CodeEdit/Features/LSP/{LanguageServer+ => LanguageServerExtensions}/LanguageServer+SignatureHelp.swift (100%) rename CodeEdit/Features/LSP/{LanguageServer+ => LanguageServerExtensions}/LanguageServer+TypeDefinition.swift (100%) diff --git a/CodeEdit.xcodeproj/project.pbxproj b/CodeEdit.xcodeproj/project.pbxproj index 5002cb67ce..568a3ccc9b 100644 --- a/CodeEdit.xcodeproj/project.pbxproj +++ b/CodeEdit.xcodeproj/project.pbxproj @@ -64,6 +64,7 @@ 3000516A2BBD3A8200A98562 /* ServiceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 300051692BBD3A8200A98562 /* ServiceType.swift */; }; 3000516C2BBD3A9500A98562 /* ServiceWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3000516B2BBD3A9500A98562 /* ServiceWrapper.swift */; }; 3026F50F2AC006C80061227E /* InspectorAreaViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3026F50E2AC006C80061227E /* InspectorAreaViewModel.swift */; }; + 30571B762C282592009CD5BB /* LSPCache+Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30571B752C282592009CD5BB /* LSPCache+Data.swift */; }; 30AB4EBB2BF718A100ED4431 /* DeveloperSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30AB4EBA2BF718A100ED4431 /* DeveloperSettings.swift */; }; 30AB4EBD2BF71CA800ED4431 /* DeveloperSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30AB4EBC2BF71CA800ED4431 /* DeveloperSettingsView.swift */; }; 30AB4EC22BF7253200ED4431 /* KeyValueTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30AB4EC12BF7253200ED4431 /* KeyValueTable.swift */; }; @@ -673,6 +674,7 @@ 300051692BBD3A8200A98562 /* ServiceType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServiceType.swift; sourceTree = ""; }; 3000516B2BBD3A9500A98562 /* ServiceWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServiceWrapper.swift; sourceTree = ""; }; 3026F50E2AC006C80061227E /* InspectorAreaViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InspectorAreaViewModel.swift; sourceTree = ""; }; + 30571B752C282592009CD5BB /* LSPCache+Data.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LSPCache+Data.swift"; sourceTree = ""; }; 30AB4EBA2BF718A100ED4431 /* DeveloperSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperSettings.swift; sourceTree = ""; }; 30AB4EBC2BF71CA800ED4431 /* DeveloperSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperSettingsView.swift; sourceTree = ""; }; 30AB4EC12BF7253200ED4431 /* KeyValueTable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyValueTable.swift; sourceTree = ""; }; @@ -1427,17 +1429,18 @@ 30B087FB2C0D53080063A882 /* LSP */ = { isa = PBXGroup; children = ( - 30B0881E2C12626B0063A882 /* LanguageServer+ */, + 30B0881E2C12626B0063A882 /* LanguageServerExtensions */, 30B087F72C0D53080063A882 /* LanguageServer.swift */, 30B087F82C0D53080063A882 /* LSPService.swift */, 30B087F92C0D53080063A882 /* LSPCache.swift */, 30B087FA2C0D53080063A882 /* LSPUtil.swift */, 30CB648C2C12680F00CC8A9E /* LSPEventHandler.swift */, + 30571B752C282592009CD5BB /* LSPCache+Data.swift */, ); path = LSP; sourceTree = ""; }; - 30B0881E2C12626B0063A882 /* LanguageServer+ */ = { + 30B0881E2C12626B0063A882 /* LanguageServerExtensions */ = { isa = PBXGroup; children = ( 30B087DF2C0D53080063A882 /* LanguageServer+CallHierarchy.swift */, @@ -1463,7 +1466,7 @@ 30B087F42C0D53080063A882 /* LanguageServer+SignatureHelp.swift */, 30B087F52C0D53080063A882 /* LanguageServer+TypeDefinition.swift */, ); - path = "LanguageServer+"; + path = LanguageServerExtensions; sourceTree = ""; }; 3E0196712A392170002648D8 /* ShellIntegration */ = { @@ -3521,6 +3524,7 @@ 66AF6CE42BF17F6800D83C9D /* StatusBarFileInfoView.swift in Sources */, 587B9E5E29301D8F00AC7927 /* GitLabCommitRouter.swift in Sources */, 58F2EB0D292FB2B0004A9BDE /* ThemeSettings.swift in Sources */, + 30571B762C282592009CD5BB /* LSPCache+Data.swift in Sources */, 587B9D9F29300ABD00AC7927 /* SegmentedControl.swift in Sources */, 6C7256D729A3D7D000C2D3E0 /* SplitViewControllerView.swift in Sources */, B6EA1FE529DA33DB001BF195 /* ThemeModel.swift in Sources */, diff --git a/CodeEdit/Features/CodeEditUI/Views/AreaTabBar.swift b/CodeEdit/Features/CodeEditUI/Views/AreaTabBar.swift index 5950a97490..a49446cb0a 100644 --- a/CodeEdit/Features/CodeEditUI/Views/AreaTabBar.swift +++ b/CodeEdit/Features/CodeEditUI/Views/AreaTabBar.swift @@ -185,7 +185,7 @@ struct AreaTabBar: View { case next } - // swiftlint:disable function_parameter_count + // swiftlint:disable:next function_parameter_count private func swapTab( tab: Tab, currentIndex: Int, @@ -236,7 +236,6 @@ struct AreaTabBar: View { items.swapAt(currentIndex, swapIndex) } } - // swiftlint:enable function_parameter_count private func isWithinPrevTopBounds( _ curLocation: CGFloat, _ swapLocation: CGRect, _ swapWidth: CGFloat diff --git a/CodeEdit/Features/LSP/LSPCache+Data.swift b/CodeEdit/Features/LSP/LSPCache+Data.swift new file mode 100644 index 0000000000..0e64634b6a --- /dev/null +++ b/CodeEdit/Features/LSP/LSPCache+Data.swift @@ -0,0 +1,36 @@ +// +// LSPCache+Data.swift +// CodeEdit +// +// Created by Abe Malla on 6/23/24. +// + +import Foundation + +struct NoExtraData: Hashable { } + +struct CacheKey: Hashable { + let uri: String + let requestType: String + let extraData: AnyHashable? + + init(uri: String, requestType: String, extraData: AnyHashable? = nil) { + self.uri = uri + self.requestType = requestType + self.extraData = extraData + } + + static func == (lhs: CacheKey, rhs: CacheKey) -> Bool { + return lhs.uri == rhs.uri && + lhs.requestType == rhs.requestType && + lhs.extraData == rhs.extraData + } + + func hash(into hasher: inout Hasher) { + hasher.combine(uri) + hasher.combine(requestType) + if let extraData = extraData { + hasher.combine(extraData) + } + } +} diff --git a/CodeEdit/Features/LSP/LSPCache.swift b/CodeEdit/Features/LSP/LSPCache.swift index c15ff5860e..7045fc7b01 100644 --- a/CodeEdit/Features/LSP/LSPCache.swift +++ b/CodeEdit/Features/LSP/LSPCache.swift @@ -7,50 +7,7 @@ import Foundation -struct NoExtraData: Hashable { } - -struct CacheKey: Hashable { - let uri: String - let requestType: String - let extraData: AnyHashable? - - init(uri: String, requestType: String, extraData: AnyHashable? = nil) { - self.uri = uri - self.requestType = requestType - self.extraData = extraData - } - - static func == (lhs: CacheKey, rhs: CacheKey) -> Bool { - return lhs.uri == rhs.uri && - lhs.requestType == rhs.requestType && - lhs.extraData == rhs.extraData - } - - func hash(into hasher: inout Hasher) { - hasher.combine(uri) - hasher.combine(requestType) - if let extraData = extraData { - hasher.combine(extraData) - } - } -} - final class LSPCache { - /// Represents a single cache entry with a generic type. - final class CacheEntry: NSObject { - let value: Any - let type: Any.Type - - init(_ value: T) { - self.value = value - self.type = T.self - } - - func getValue(as type: T.Type) -> T? { - return value as? T - } - } - private var cache = NSCache() func get(key: CacheKey, as type: T.Type) -> T? { @@ -71,6 +28,21 @@ final class LSPCache { let cacheKey = key.description as NSString cache.removeObject(forKey: cacheKey) } + + /// Represents a single cache entry with a generic type. + final class CacheEntry: NSObject { + let value: Any + let type: Any.Type + + init(_ value: T) { + self.value = value + self.type = T.self + } + + func getValue(as type: T.Type) -> T? { + return value as? T + } + } } extension CacheKey: CustomStringConvertible { diff --git a/CodeEdit/Features/LSP/LSPEventHandler.swift b/CodeEdit/Features/LSP/LSPEventHandler.swift index 1cfc9ec2f1..187edf8e43 100644 --- a/CodeEdit/Features/LSP/LSPEventHandler.swift +++ b/CodeEdit/Features/LSP/LSPEventHandler.swift @@ -9,7 +9,6 @@ import LanguageClient import LanguageServerProtocol extension LSPService { - func startListeningToEvents(for languageId: LanguageIdentifier) { guard let languageClient = languageClients[languageId] else { logger.error("Language client not found for \(languageId.rawValue)") @@ -44,7 +43,7 @@ extension LSPService { } } - // swiftlint:disable cyclomatic_complexity + // swiftlint:disable:next cyclomatic_complexity private func handleRequest(_ request: ServerRequest) { switch request { case let .workspaceConfiguration(params, handler): @@ -71,7 +70,6 @@ extension LSPService { default: print() } - // swiftlint:enable cyclomatic_complexity } private func handleNotification(_ notification: ServerNotification) { diff --git a/CodeEdit/Features/LSP/LSPService.swift b/CodeEdit/Features/LSP/LSPService.swift index 984468b54e..a4846b560b 100644 --- a/CodeEdit/Features/LSP/LSPService.swift +++ b/CodeEdit/Features/LSP/LSPService.swift @@ -194,7 +194,7 @@ final class LSPService: ObservableObject { stopListeningToEvents(for: languageId) } - /// Goes through all active langauge servers and attempts to shut them down. + /// Goes through all active language servers and attempts to shut them down. func stopAllServers() async throws { for languageId in languageClients.keys { try await stopServer(for: languageId) diff --git a/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+CallHierarchy.swift b/CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+CallHierarchy.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageServer+/LanguageServer+CallHierarchy.swift rename to CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+CallHierarchy.swift diff --git a/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+ColorPresentation.swift b/CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+ColorPresentation.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageServer+/LanguageServer+ColorPresentation.swift rename to CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+ColorPresentation.swift diff --git a/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Completion.swift b/CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+Completion.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Completion.swift rename to CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+Completion.swift diff --git a/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Declaration.swift b/CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+Declaration.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Declaration.swift rename to CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+Declaration.swift diff --git a/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Definition.swift b/CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+Definition.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Definition.swift rename to CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+Definition.swift diff --git a/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Diagnostics.swift b/CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+Diagnostics.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Diagnostics.swift rename to CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+Diagnostics.swift diff --git a/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+DocumentColor.swift b/CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+DocumentColor.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageServer+/LanguageServer+DocumentColor.swift rename to CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+DocumentColor.swift diff --git a/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+DocumentHighlight.swift b/CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+DocumentHighlight.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageServer+/LanguageServer+DocumentHighlight.swift rename to CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+DocumentHighlight.swift diff --git a/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+DocumentLink.swift b/CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+DocumentLink.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageServer+/LanguageServer+DocumentLink.swift rename to CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+DocumentLink.swift diff --git a/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+DocumentSymbol.swift b/CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+DocumentSymbol.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageServer+/LanguageServer+DocumentSymbol.swift rename to CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+DocumentSymbol.swift diff --git a/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+DocumentUtil.swift b/CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+DocumentUtil.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageServer+/LanguageServer+DocumentUtil.swift rename to CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+DocumentUtil.swift diff --git a/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+FoldingRange.swift b/CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+FoldingRange.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageServer+/LanguageServer+FoldingRange.swift rename to CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+FoldingRange.swift diff --git a/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Formatting.swift b/CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+Formatting.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Formatting.swift rename to CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+Formatting.swift diff --git a/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Hover.swift b/CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+Hover.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Hover.swift rename to CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+Hover.swift diff --git a/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Implementation.swift b/CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+Implementation.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Implementation.swift rename to CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+Implementation.swift diff --git a/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+InlayHint.swift b/CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+InlayHint.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageServer+/LanguageServer+InlayHint.swift rename to CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+InlayHint.swift diff --git a/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+References.swift b/CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+References.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageServer+/LanguageServer+References.swift rename to CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+References.swift diff --git a/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Rename.swift b/CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+Rename.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageServer+/LanguageServer+Rename.swift rename to CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+Rename.swift diff --git a/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+SelectionRange.swift b/CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+SelectionRange.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageServer+/LanguageServer+SelectionRange.swift rename to CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+SelectionRange.swift diff --git a/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+SemanticTokens.swift b/CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+SemanticTokens.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageServer+/LanguageServer+SemanticTokens.swift rename to CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+SemanticTokens.swift diff --git a/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+SignatureHelp.swift b/CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+SignatureHelp.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageServer+/LanguageServer+SignatureHelp.swift rename to CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+SignatureHelp.swift diff --git a/CodeEdit/Features/LSP/LanguageServer+/LanguageServer+TypeDefinition.swift b/CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+TypeDefinition.swift similarity index 100% rename from CodeEdit/Features/LSP/LanguageServer+/LanguageServer+TypeDefinition.swift rename to CodeEdit/Features/LSP/LanguageServerExtensions/LanguageServer+TypeDefinition.swift