Skip to content

Commit

Permalink
Throttle Content Updates
Browse files Browse the repository at this point in the history
  • Loading branch information
thecoolwinter committed Sep 24, 2024
1 parent 7351dee commit 989df27
Show file tree
Hide file tree
Showing 10 changed files with 328 additions and 110 deletions.
63 changes: 40 additions & 23 deletions CodeEdit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 60;
objectVersion = 55;
objects = {

/* Begin PBXBuildFile section */
Expand Down Expand Up @@ -375,7 +375,6 @@
6C1F3DA22C18C55800F6DEF6 /* ShellIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C1F3DA12C18C55800F6DEF6 /* ShellIntegrationTests.swift */; };
6C23842F2C796B4C003FBDD4 /* GitChangedFileLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C23842E2C796B4C003FBDD4 /* GitChangedFileLabel.swift */; };
6C278CC72C93971F0066F6D9 /* LSPContentCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C278CC62C93971F0066F6D9 /* LSPContentCoordinator.swift */; };
6C278CCA2C949D4A0066F6D9 /* CodeEditSourceEditor in Frameworks */ = {isa = PBXBuildFile; productRef = 6C278CC92C949D4A0066F6D9 /* CodeEditSourceEditor */; };
6C2C155829B4F49100EA60A5 /* SplitViewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C2C155729B4F49100EA60A5 /* SplitViewItem.swift */; };
6C2C155A29B4F4CC00EA60A5 /* Variadic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C2C155929B4F4CC00EA60A5 /* Variadic.swift */; };
6C2C155D29B4F4E500EA60A5 /* SplitViewReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C2C155C29B4F4E500EA60A5 /* SplitViewReader.swift */; };
Expand Down Expand Up @@ -443,6 +442,8 @@
6CB446402B6DFF3A00539ED0 /* CodeEditSourceEditor in Frameworks */ = {isa = PBXBuildFile; productRef = 6CB4463F2B6DFF3A00539ED0 /* CodeEditSourceEditor */; };
6CB52DC92AC8DC3E002E75B3 /* CEWorkspaceFileManager+FileManagement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CB52DC82AC8DC3E002E75B3 /* CEWorkspaceFileManager+FileManagement.swift */; };
6CB9144B29BEC7F100BC47F2 /* (null) in Sources */ = {isa = PBXBuildFile; };
6CB94CFE2C9F1C9A00E8651C /* TextView+LSPRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CB94CFD2C9F1C9A00E8651C /* TextView+LSPRange.swift */; };
6CB94D032CA1205100E8651C /* AsyncAlgorithms in Frameworks */ = {isa = PBXBuildFile; productRef = 6CB94D022CA1205100E8651C /* AsyncAlgorithms */; };
6CBA0D512A1BF524002C6FAA /* SegmentedControlImproved.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CBA0D502A1BF524002C6FAA /* SegmentedControlImproved.swift */; };
6CBD1BC62978DE53006639D5 /* Font+Caption3.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CBD1BC52978DE53006639D5 /* Font+Caption3.swift */; };
6CBE1CFB2B71DAA6003AC32E /* Loopable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CBE1CFA2B71DAA6003AC32E /* Loopable.swift */; };
Expand Down Expand Up @@ -1100,6 +1101,7 @@
6CA1AE942B46950000378EAB /* EditorInstance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditorInstance.swift; sourceTree = "<group>"; };
6CABB1A029C5593800340467 /* SearchPanelView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchPanelView.swift; sourceTree = "<group>"; };
6CB52DC82AC8DC3E002E75B3 /* CEWorkspaceFileManager+FileManagement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CEWorkspaceFileManager+FileManagement.swift"; sourceTree = "<group>"; };
6CB94CFD2C9F1C9A00E8651C /* TextView+LSPRange.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TextView+LSPRange.swift"; sourceTree = "<group>"; };
6CBA0D502A1BF524002C6FAA /* SegmentedControlImproved.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SegmentedControlImproved.swift; sourceTree = "<group>"; };
6CBD1BC52978DE53006639D5 /* Font+Caption3.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Font+Caption3.swift"; sourceTree = "<group>"; };
6CBE1CFA2B71DAA6003AC32E /* Loopable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Loopable.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1307,6 +1309,7 @@
6C6BD6F829CD14D100235D17 /* CodeEditKit in Frameworks */,
6C0824A12C5C0C9700A0751E /* SwiftTerm in Frameworks */,
6C81916B29B41DD300B75C92 /* DequeModule in Frameworks */,
6CB94D032CA1205100E8651C /* AsyncAlgorithms in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -1549,7 +1552,6 @@
30B087FB2C0D53080063A882 /* LSP */ = {
isa = PBXGroup;
children = (
6CD26C822C8F8A5F00ADBA38 /* Extensions */,
6CD26C732C8EA71F00ADBA38 /* LanguageServer */,
6CD26C742C8EA79100ADBA38 /* Service */,
30B087FA2C0D53080063A882 /* LSPUtil.swift */,
Expand Down Expand Up @@ -2437,9 +2439,11 @@
5831E3C62933E7E600D5A6D2 /* Color */,
669A504F2C380BFD00304CD8 /* Collection */,
5831E3C82933E80500D5A6D2 /* Date */,
6CB94D002C9F1CF900E8651C /* LanguageIdentifier */,
6C82D6C429C0129E00495C54 /* NSApplication */,
5831E3D02934036D00D5A6D2 /* NSTableView */,
77A01E922BCA9C0400F0EA38 /* NSWindow */,
6CB94CFF2C9F1CB600E8651C /* TextView */,
77EF6C042C57DE4B00984B69 /* URL */,
58D01C8B293167DC00C5B6B4 /* String */,
5831E3CB2933E89A00D5A6D2 /* SwiftTerm */,
Expand Down Expand Up @@ -2963,6 +2967,22 @@
path = WindowCommands;
sourceTree = "<group>";
};
6CB94CFF2C9F1CB600E8651C /* TextView */ = {
isa = PBXGroup;
children = (
6CB94CFD2C9F1C9A00E8651C /* TextView+LSPRange.swift */,
);
path = TextView;
sourceTree = "<group>";
};
6CB94D002C9F1CF900E8651C /* LanguageIdentifier */ = {
isa = PBXGroup;
children = (
6CD26C802C8F8A4400ADBA38 /* LanguageIdentifier+CodeLanguage.swift */,
);
path = LanguageIdentifier;
sourceTree = "<group>";
};
6CBD1BC42978DE3E006639D5 /* Text */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -3026,14 +3046,6 @@
path = URL;
sourceTree = "<group>";
};
6CD26C822C8F8A5F00ADBA38 /* Extensions */ = {
isa = PBXGroup;
children = (
6CD26C802C8F8A4400ADBA38 /* LanguageIdentifier+CodeLanguage.swift */,
);
path = Extensions;
sourceTree = "<group>";
};
6CD26C882C8F91B600ADBA38 /* LSP */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -3673,6 +3685,7 @@
6C4E37FB2C73E00700AEE7B5 /* SwiftTerm */,
6CD3CA542C8B508200D83DCD /* CodeEditSourceEditor */,
6CD26C842C8F907800ADBA38 /* CodeEditSourceEditor */,
6CB94D022CA1205100E8651C /* AsyncAlgorithms */,
);
productName = CodeEdit;
productReference = B658FB2C27DA9E0F00EA4DBD /* CodeEdit.app */;
Expand Down Expand Up @@ -3770,6 +3783,7 @@
303E88462C276FD600EEA8D9 /* XCRemoteSwiftPackageReference "LanguageServerProtocol" */,
6C4E37FA2C73E00700AEE7B5 /* XCRemoteSwiftPackageReference "SwiftTerm" */,
6CD26C832C8F907800ADBA38 /* XCRemoteSwiftPackageReference "CodeEditSourceEditor" */,
6CB94D012CA1205100E8651C /* XCRemoteSwiftPackageReference "swift-async-algorithms" */,
);
productRefGroup = B658FB2D27DA9E0F00EA4DBD /* Products */;
projectDirPath = "";
Expand Down Expand Up @@ -4349,6 +4363,7 @@
5878DA82291863F900DD95A3 /* AcknowledgementsView.swift in Sources */,
587B9E8529301D8F00AC7927 /* GitHubReview.swift in Sources */,
58D01C9A293167DC00C5B6B4 /* CodeEditKeychain.swift in Sources */,
6CB94CFE2C9F1C9A00E8651C /* TextView+LSPRange.swift in Sources */,
B6966A2E2C3056AD00259C2D /* SourceControlCommands.swift in Sources */,
B62AEDAA2A1FCBE5009A9F52 /* AreaTabBar.swift in Sources */,
20D839AB280DEB2900B27357 /* NoSelectionInspectorView.swift in Sources */,
Expand Down Expand Up @@ -5531,13 +5546,6 @@
};
/* End XCConfigurationList section */

/* Begin XCLocalSwiftPackageReference section */
6C278CC82C949D4A0066F6D9 /* XCLocalSwiftPackageReference "../CodeEditSourceEditor" */ = {
isa = XCLocalSwiftPackageReference;
relativePath = ../CodeEditSourceEditor;
};
/* End XCLocalSwiftPackageReference section */

/* Begin XCRemoteSwiftPackageReference section */
2816F592280CF50500DD548B /* XCRemoteSwiftPackageReference "CodeEditSymbols" */ = {
isa = XCRemoteSwiftPackageReference;
Expand Down Expand Up @@ -5659,12 +5667,20 @@
minimumVersion = 1.2.0;
};
};
6CB94D012CA1205100E8651C /* XCRemoteSwiftPackageReference "swift-async-algorithms" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/apple/swift-async-algorithms.git";
requirement = {
kind = exactVersion;
version = 1.0.1;
};
};
6CD26C832C8F907800ADBA38 /* XCRemoteSwiftPackageReference "CodeEditSourceEditor" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/CodeEditApp/CodeEditSourceEditor";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 0.8.0;
minimumVersion = 0.8.1;
};
};
/* End XCRemoteSwiftPackageReference section */
Expand Down Expand Up @@ -5709,10 +5725,6 @@
package = 6C147C4329A329350089B630 /* XCRemoteSwiftPackageReference "swift-collections" */;
productName = OrderedCollections;
};
6C278CC92C949D4A0066F6D9 /* CodeEditSourceEditor */ = {
isa = XCSwiftPackageProductDependency;
productName = CodeEditSourceEditor;
};
6C4E37FB2C73E00700AEE7B5 /* SwiftTerm */ = {
isa = XCSwiftPackageProductDependency;
package = 6C4E37FA2C73E00700AEE7B5 /* XCRemoteSwiftPackageReference "SwiftTerm" */;
Expand Down Expand Up @@ -5756,6 +5768,11 @@
isa = XCSwiftPackageProductDependency;
productName = CodeEditSourceEditor;
};
6CB94D022CA1205100E8651C /* AsyncAlgorithms */ = {
isa = XCSwiftPackageProductDependency;
package = 6CB94D012CA1205100E8651C /* XCRemoteSwiftPackageReference "swift-async-algorithms" */;
productName = AsyncAlgorithms;
};
6CC17B4E2C432AE000834E2C /* CodeEditSourceEditor */ = {
isa = XCSwiftPackageProductDependency;
productName = CodeEditSourceEditor;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"originHash" : "fed6d2ac4770e7fa9354a624690858c88d25add66264ffe858710496c8ca5e48",
"originHash" : "5c4a5d433333474763817b9804d7f1856ab3b416ed87b190a2bd6e86c0c9834c",
"pins" : [
{
"identity" : "anycodable",
Expand All @@ -13,7 +13,7 @@
{
"identity" : "codeeditkit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/CodeEditApp/CodeEditKit",
"location" : "https://github.com/CodeEditApp/CodeEditKit.git",
"state" : {
"revision" : "ad28213a968586abb0cb21a8a56a3587227895f1",
"version" : "0.1.2"
Expand All @@ -28,6 +28,15 @@
"version" : "0.1.19"
}
},
{
"identity" : "codeeditsourceeditor",
"kind" : "remoteSourceControl",
"location" : "https://github.com/CodeEditApp/CodeEditSourceEditor",
"state" : {
"revision" : "033b68d3e3e845984fbc3d405720d5cc6ce61f71",
"version" : "0.8.1"
}
},
{
"identity" : "codeeditsymbols",
"kind" : "remoteSourceControl",
Expand Down Expand Up @@ -172,6 +181,15 @@
"version" : "2.3.0"
}
},
{
"identity" : "swift-async-algorithms",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-async-algorithms.git",
"state" : {
"revision" : "6ae9a051f76b81cc668305ceed5b0e0a7fd93d20",
"version" : "1.0.1"
}
},
{
"identity" : "swift-collections",
"kind" : "remoteSourceControl",
Expand Down
1 change: 1 addition & 0 deletions CodeEdit/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import SwiftUI
import CodeEditSymbols
import CodeEditSourceEditor


Check failure on line 12 in CodeEdit/AppDelegate.swift

View workflow job for this annotation

GitHub Actions / SwiftLint / SwiftLint

Limit vertical whitespace to a single empty line; currently 2 (vertical_whitespace)
final class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
private let updater = SoftwareUpdater()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ final class CodeFileDocument: NSDocument, ObservableObject {
/// See ``CodeEditSourceEditor/CombineCoordinator``.
@Published var contentCoordinator: CombineCoordinator = CombineCoordinator()

lazy var lspCoordinator: LSPContentCoordinator = {
lazy var languageServerCoordinator: LSPContentCoordinator = {
let coordinator = LSPContentCoordinator()
coordinator.uri = self.languageServerURI
return coordinator
Expand Down
5 changes: 4 additions & 1 deletion CodeEdit/Features/Editor/Views/CodeFileView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,10 @@ struct CodeFileView: View {

init(codeFile: CodeFileDocument, textViewCoordinators: [TextViewCoordinator] = [], isEditable: Bool = true) {
self._codeFile = .init(wrappedValue: codeFile)
self.textViewCoordinators = textViewCoordinators + [codeFile.contentCoordinator, codeFile.lspCoordinator]
self.textViewCoordinators = textViewCoordinators + [
codeFile.contentCoordinator,
codeFile.languageServerCoordinator
]
self.isEditable = isEditable

if let openOptions = codeFile.openOptions {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,42 +9,6 @@ import Foundation
import LanguageServerProtocol

extension LanguageServer {
// swiftlint:disable line_length
/// Determines the type of document sync the server supports.
/// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_synchronization_sc
fileprivate func resolveDocumentSyncKind() -> TextDocumentSyncKind {
// swiftlint:enable line_length
var syncKind: TextDocumentSyncKind = .none
switch serverCapabilities.textDocumentSync {
case .optionA(let options):
syncKind = options.change ?? .none
case .optionB(let kind):
syncKind = kind
default:
syncKind = .none
}
return syncKind
}

/// Determines whether or not the server supports document tracking.
fileprivate func resolveOpenCloseSupport() -> Bool {
switch serverCapabilities.textDocumentSync {
case .optionA(let options):
return options.openClose ?? false
case .optionB:
return true
default:
return true
}
}

// Used to avoid a lint error (`large_tuple`) for the return type of `getIsolatedDocumentContent`
fileprivate struct DocumentContent {
let uri: String
let language: LanguageIdentifier
let content: String
}

/// Tells the language server we've opened a document and would like to begin working with it.
/// - Parameter document: The code document to open.
/// - Throws: Throws errors produced by the language server connection.
Expand All @@ -61,26 +25,16 @@ extension LanguageServer {
uri: content.uri,
languageId: content.language,
version: 0,
text: content.content
text: content.string
)
try await lspInstance.textDocumentDidOpen(DidOpenTextDocumentParams(textDocument: textDocument))
await updateIsolatedTextCoordinator(for: document)
} catch {
logger.warning("addDocument: Error \(error)")
throw error
}
}

/// Helper function for grabbing a document's content from the main actor.
@MainActor
private func getIsolatedDocumentContent(_ document: CodeFileDocument) -> DocumentContent? {
guard let uri = document.languageServerURI,
let language = document.getLanguage().lspLanguage,
let content = document.content?.string else {
return nil
}
return DocumentContent(uri: uri, language: language, content: content)
}

/// Stops tracking a file and notifies the language server.
/// - Parameter uri: The URI of the document to close.
/// - Throws: Throws errors produced by the language server connection.
Expand Down Expand Up @@ -135,4 +89,59 @@ extension LanguageServer {
throw error
}
}

// MARK: File Private Helpers

/// Helper function for grabbing a document's content from the main actor.
@MainActor
private func getIsolatedDocumentContent(_ document: CodeFileDocument) -> DocumentContent? {
guard let uri = document.languageServerURI,
let language = document.getLanguage().lspLanguage,
let content = document.content?.string else {
return nil
}
return DocumentContent(uri: uri, language: language, string: content)
}

/// Updates the actor-isolated document's text coordinator to map to this server.
@MainActor
fileprivate func updateIsolatedTextCoordinator(for document: CodeFileDocument) {
document.languageServerCoordinator.languageServer = self
}

// swiftlint:disable line_length
/// Determines the type of document sync the server supports.
/// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_synchronization_sc
fileprivate func resolveDocumentSyncKind() -> TextDocumentSyncKind {
// swiftlint:enable line_length
var syncKind: TextDocumentSyncKind = .none
switch serverCapabilities.textDocumentSync {
case .optionA(let options): // interface TextDocumentSyncOptions
syncKind = options.change ?? .none
case .optionB(let kind): // interface TextDocumentSyncKind
syncKind = kind
default:
syncKind = .none
}
return syncKind
}

/// Determines whether or not the server supports document tracking.
fileprivate func resolveOpenCloseSupport() -> Bool {
switch serverCapabilities.textDocumentSync {
case .optionA(let options): // interface TextDocumentSyncOptions
return options.openClose ?? false
case .optionB: // interface TextDocumentSyncKind
return true
default:
return true
}
}

// Used to avoid a lint error (`large_tuple`) for the return type of `getIsolatedDocumentContent`
fileprivate struct DocumentContent {
let uri: String
let language: LanguageIdentifier
let string: String
}
}
Loading

0 comments on commit 989df27

Please sign in to comment.