Skip to content

Commit c78ef96

Browse files
LSP Backend (#1739)
* Updated packages * Use local packages, fix errors * Adding LSP features * New cache, more documentation, fixes, setup LSP service * Add `LSPCompletionItemsUtil` Namespace * Spruce up the lsp binary menu * Propagate error, remove commented function * Update CodeEditKit --------- Co-authored-by: Khan Winter <[email protected]>
1 parent e8b1bf5 commit c78ef96

40 files changed

+1877
-64
lines changed

.swiftlint.yml

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ type_name:
88
- ID
99

1010
identifier_name:
11+
allowed_symbols: ["$", "_"]
1112
excluded:
1213
- id
1314
- vc

CodeEdit.xcodeproj/project.pbxproj

+177-2
Large diffs are not rendered by default.

CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

+74-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
{
1414
"identity" : "codeeditkit",
1515
"kind" : "remoteSourceControl",
16-
"location" : "https://github.com/CodeEditApp/CodeEditKit",
16+
"location" : "https://github.com/CodeEditApp/CodeEditKit.git",
1717
"state" : {
1818
"revision" : "ad28213a968586abb0cb21a8a56a3587227895f1",
1919
"version" : "0.1.2"
@@ -31,7 +31,7 @@
3131
{
3232
"identity" : "codeeditsourceeditor",
3333
"kind" : "remoteSourceControl",
34-
"location" : "https://github.com/CodeEditApp/CodeEditSourceEditor",
34+
"location" : "https://github.com/CodeEditApp/CodeEditSourceEditor.git",
3535
"state" : {
3636
"revision" : "cf85789d527d569e94edfd674c5ac8071b244dd9",
3737
"version" : "0.7.3"
@@ -73,6 +73,24 @@
7373
"version" : "0.4.2"
7474
}
7575
},
76+
{
77+
"identity" : "fseventswrapper",
78+
"kind" : "remoteSourceControl",
79+
"location" : "https://github.com/Frizlab/FSEventsWrapper",
80+
"state" : {
81+
"revision" : "70bbea4b108221fcabfce8dbced8502831c0ae04",
82+
"version" : "2.1.0"
83+
}
84+
},
85+
{
86+
"identity" : "globpattern",
87+
"kind" : "remoteSourceControl",
88+
"location" : "https://github.com/ChimeHQ/GlobPattern",
89+
"state" : {
90+
"revision" : "4ebb9e89e07cc475efa74f87dc6d21f4a9e060f8",
91+
"version" : "0.1.1"
92+
}
93+
},
7694
{
7795
"identity" : "grdb.swift",
7896
"kind" : "remoteSourceControl",
@@ -82,6 +100,33 @@
82100
"version" : "5.26.1"
83101
}
84102
},
103+
{
104+
"identity" : "jsonrpc",
105+
"kind" : "remoteSourceControl",
106+
"location" : "https://github.com/ChimeHQ/JSONRPC",
107+
"state" : {
108+
"revision" : "c6ec759d41a76ac88fe7327c41a77d9033943374",
109+
"version" : "0.9.0"
110+
}
111+
},
112+
{
113+
"identity" : "languageclient",
114+
"kind" : "remoteSourceControl",
115+
"location" : "https://github.com/ChimeHQ/LanguageClient",
116+
"state" : {
117+
"revision" : "f8fdeaed850fbc3e542cd038e952758887f6be5d",
118+
"version" : "0.8.0"
119+
}
120+
},
121+
{
122+
"identity" : "languageserverprotocol",
123+
"kind" : "remoteSourceControl",
124+
"location" : "https://github.com/ChimeHQ/LanguageServerProtocol",
125+
"state" : {
126+
"revision" : "ac76fccf0e981c8e30c5ee4de1b15adc1decd697",
127+
"version" : "0.13.2"
128+
}
129+
},
85130
{
86131
"identity" : "logstream",
87132
"kind" : "remoteSourceControl",
@@ -100,6 +145,24 @@
100145
"version" : "0.2.1"
101146
}
102147
},
148+
{
149+
"identity" : "processenv",
150+
"kind" : "remoteSourceControl",
151+
"location" : "https://github.com/ChimeHQ/ProcessEnv",
152+
"state" : {
153+
"revision" : "83f1ebc9dd6fb1db0bd89a3fcae00488a0f3fdd9",
154+
"version" : "1.0.0"
155+
}
156+
},
157+
{
158+
"identity" : "queue",
159+
"kind" : "remoteSourceControl",
160+
"location" : "https://github.com/mattmassicotte/Queue",
161+
"state" : {
162+
"revision" : "8d6f936097888f97011610ced40313655dc5948d",
163+
"version" : "0.1.4"
164+
}
165+
},
103166
{
104167
"identity" : "rearrange",
105168
"kind" : "remoteSourceControl",
@@ -109,6 +172,15 @@
109172
"version" : "1.8.1"
110173
}
111174
},
175+
{
176+
"identity" : "semaphore",
177+
"kind" : "remoteSourceControl",
178+
"location" : "https://github.com/groue/Semaphore",
179+
"state" : {
180+
"revision" : "f1c4a0acabeb591068dea6cffdd39660b86dec28",
181+
"version" : "0.0.8"
182+
}
183+
},
112184
{
113185
"identity" : "sparkle",
114186
"kind" : "remoteSourceControl",

CodeEdit/AppDelegate.swift

+4-5
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
//
77

88
import SwiftUI
9-
import CodeEditSourceEditor
109
import CodeEditSymbols
10+
import CodeEditSourceEditor
1111

1212
final class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
1313
private let updater = SoftwareUpdater()
@@ -230,10 +230,9 @@ final class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
230230

231231
/// Setup all the services into a ServiceContainer for the application to use.
232232
private func setupServiceContainer() {
233-
// Example for how services will be instantiated
234-
// ServiceContainer.register(
235-
// PasteboardService()
236-
// )
233+
ServiceContainer.register(
234+
LSPService()
235+
)
237236
}
238237

239238
extension AppDelegate {

CodeEdit/Features/CodeEditUI/Views/AreaTabBar.swift

+1-2
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ struct AreaTabBar<Tab: AreaTab>: View {
185185
case next
186186
}
187187

188-
// swiftlint: disable function_parameter_count
188+
// swiftlint:disable:next function_parameter_count
189189
private func swapTab(
190190
tab: Tab,
191191
currentIndex: Int,
@@ -236,7 +236,6 @@ struct AreaTabBar<Tab: AreaTab>: View {
236236
items.swapAt(currentIndex, swapIndex)
237237
}
238238
}
239-
// swiftlint: enable function_parameter_count
240239

241240
private func isWithinPrevTopBounds(
242241
_ curLocation: CGFloat, _ swapLocation: CGRect, _ swapWidth: CGFloat

CodeEdit/Features/CodeEditUI/Views/KeyValueTable.swift

+56-41
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,22 @@ private struct NewListTableItemView: View {
2323
let keyColumnName: String
2424
let valueColumnName: String
2525
let newItemInstruction: String
26+
let validKeys: [String]
2627
let headerView: AnyView?
2728
var completion: (String, String) -> Void
2829

2930
init(
3031
_ keyColumnName: String,
3132
_ valueColumnName: String,
3233
_ newItemInstruction: String,
34+
validKeys: [String],
3335
headerView: AnyView? = nil,
3436
completion: @escaping (String, String) -> Void
3537
) {
3638
self.keyColumnName = keyColumnName
3739
self.valueColumnName = valueColumnName
3840
self.newItemInstruction = newItemInstruction
41+
self.validKeys = validKeys
3942
self.headerView = headerView
4043
self.completion = completion
4144
}
@@ -44,8 +47,18 @@ private struct NewListTableItemView: View {
4447
VStack(spacing: 0) {
4548
Form {
4649
Section {
47-
TextField(keyColumnName, text: $key)
48-
.textFieldStyle(.plain)
50+
if validKeys.isEmpty {
51+
TextField(keyColumnName, text: $key)
52+
.textFieldStyle(.plain)
53+
} else {
54+
Picker(keyColumnName, selection: $key) {
55+
ForEach(validKeys, id: \.self) { key in
56+
Text(key).tag(key)
57+
}
58+
Divider()
59+
Text("No Selection").tag("")
60+
}
61+
}
4962
TextField(valueColumnName, text: $value)
5063
.textFieldStyle(.plain)
5164
} header: {
@@ -84,6 +97,7 @@ private struct NewListTableItemView: View {
8497
struct KeyValueTable<Header: View>: View {
8598
@Binding var items: [String: String]
8699

100+
let validKeys: [String]
87101
let keyColumnName: String
88102
let valueColumnName: String
89103
let newItemInstruction: String
@@ -95,65 +109,66 @@ struct KeyValueTable<Header: View>: View {
95109

96110
init(
97111
items: Binding<[String: String]>,
112+
validKeys: [String] = [],
98113
keyColumnName: String,
99114
valueColumnName: String,
100115
newItemInstruction: String,
101116
@ViewBuilder header: @escaping () -> Header = { EmptyView() }
102117
) {
103118
self._items = items
119+
self.validKeys = validKeys
104120
self.keyColumnName = keyColumnName
105121
self.valueColumnName = valueColumnName
106122
self.newItemInstruction = newItemInstruction
107123
self.header = header
108124
}
109125

110126
var body: some View {
111-
VStack {
112-
Table(tableItems, selection: $selection) {
113-
TableColumn(keyColumnName) { item in
114-
Text(item.key)
115-
}
116-
TableColumn(valueColumnName) { item in
117-
Text(item.value)
118-
}
127+
Table(tableItems, selection: $selection) {
128+
TableColumn(keyColumnName) { item in
129+
Text(item.key)
119130
}
120-
.frame(height: 200)
121-
.actionBar {
122-
HStack(spacing: 2) {
123-
Button {
124-
showingModal = true
125-
} label: {
126-
Image(systemName: "plus")
127-
}
131+
TableColumn(valueColumnName) { item in
132+
Text(item.value)
133+
}
134+
}
135+
.frame(height: 200)
136+
.actionBar {
137+
HStack(spacing: 2) {
138+
Button {
139+
showingModal = true
140+
} label: {
141+
Image(systemName: "plus")
142+
}
128143

129-
Divider()
130-
.frame(minHeight: 15)
144+
Divider()
145+
.frame(minHeight: 15)
131146

132-
Button {
133-
removeItem()
134-
} label: {
135-
Image(systemName: "minus")
136-
}
137-
.disabled(selection == nil)
138-
.opacity(selection == nil ? 0.5 : 1)
147+
Button {
148+
removeItem()
149+
} label: {
150+
Image(systemName: "minus")
139151
}
140-
Spacer()
152+
.disabled(selection == nil)
153+
.opacity(selection == nil ? 0.5 : 1)
141154
}
142-
.sheet(isPresented: $showingModal) {
143-
NewListTableItemView(
144-
keyColumnName,
145-
valueColumnName,
146-
newItemInstruction,
147-
headerView: AnyView(header())
148-
) { key, value in
149-
items[key] = value
150-
updateTableItems()
151-
showingModal = false
152-
}
155+
Spacer()
156+
}
157+
.sheet(isPresented: $showingModal) {
158+
NewListTableItemView(
159+
keyColumnName,
160+
valueColumnName,
161+
newItemInstruction,
162+
validKeys: validKeys,
163+
headerView: AnyView(header())
164+
) { key, value in
165+
items[key] = value
166+
updateTableItems()
167+
showingModal = false
153168
}
154-
.clipShape(RoundedRectangle(cornerRadius: 6))
155-
.onAppear(perform: updateTableItems)
156169
}
170+
.cornerRadius(6)
171+
.onAppear(perform: updateTableItems)
157172
}
158173

159174
private func updateTableItems() {

CodeEdit/Features/Documents/WorkspaceDocument.swift

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
// Created by Pavel Kasila on 17.03.22.
66
//
77

8-
import Foundation
98
import AppKit
109
import SwiftUI
1110
import Combine
11+
import Foundation
12+
import LanguageServerProtocol
1213

1314
@objc(WorkspaceDocument)
1415
final class WorkspaceDocument: NSDocument, ObservableObject, NSToolbarDelegate {
@@ -113,6 +114,7 @@ final class WorkspaceDocument: NSDocument, ObservableObject, NSToolbarDelegate {
113114
workspaceURL: url,
114115
editorManager: editorManager
115116
)
117+
116118
self.workspaceFileManager = .init(
117119
folderUrl: url,
118120
ignoredFilesAndFolders: Set(ignoredFilesAndDirectory),

CodeEdit/Features/Editor/Models/Editor.swift

+2-6
Original file line numberDiff line numberDiff line change
@@ -177,12 +177,6 @@ final class Editor: ObservableObject, Identifiable {
177177
default:
178178
break
179179
}
180-
181-
do {
182-
try openFile(item: item)
183-
} catch {
184-
print(error)
185-
}
186180
}
187181

188182
/// Opens a tab in the editor.
@@ -201,6 +195,7 @@ final class Editor: ObservableObject, Identifiable {
201195
tabs.append(item)
202196
}
203197
}
198+
204199
selectedTab = item
205200
if !fromHistory {
206201
history.removeFirst(historyOffset)
@@ -222,6 +217,7 @@ final class Editor: ObservableObject, Identifiable {
222217
let contentType = try item.file.url.resourceValues(forKeys: [.contentTypeKey]).contentType
223218
let codeFile = try CodeFileDocument(
224219
for: item.file.url,
220+
// TODO: FILE CONTENTS ARE READ MULTIPLE TIMES
225221
withContentsOf: item.file.url,
226222
ofType: contentType?.identifier ?? ""
227223
)

CodeEdit/Features/Editor/Models/EditorManager.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ class EditorManager: ObservableObject {
9393
/// - editor: The editor to add the tab to. If nil, it is added to the active tab group.
9494
func openTab(item: CEWorkspaceFile, in editor: Editor? = nil) {
9595
let editor = editor ?? activeEditor
96-
editor.openTab(file: item)
96+
editor.openTab(file: item, asTemporary: false)
9797
}
9898

9999
/// bind active tap group to listen to file selection changes.

0 commit comments

Comments
 (0)