Skip to content

Commit 711ea33

Browse files
committed
Use Copy option
1 parent 89d989b commit 711ea33

File tree

2 files changed

+35
-64
lines changed

2 files changed

+35
-64
lines changed

Sources/SwiftLanguageService/CopyObjCSelector.swift

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,32 +17,35 @@ import SourceKitD
1717
import SourceKitLSP
1818

1919
extension SwiftLanguageService {
20-
/// Executes the direct SourceKitD request to fetch the Objective-C selector at the cursor position.
20+
/// Executes the refactoring-based copy and extracts the selector string without applying edits.
2121
func copyObjCSelector(
2222
_ command: CopyObjCSelectorCommand
2323
) async throws -> LSPAny {
24-
let snapshot = try documentManager.latestSnapshot(command.textDocument.uri)
25-
let compileCommand = await self.compileCommand(for: snapshot.uri, fallbackAfterTimeout: true)
26-
let offset = snapshot.utf8Offset(of: command.positionRange.lowerBound)
24+
let refactorCommand = SemanticRefactorCommand(
25+
title: command.title,
26+
actionString: command.actionString,
27+
positionRange: command.positionRange,
28+
textDocument: command.textDocument
29+
)
2730

28-
let keys = self.keys
29-
let skreq = sourcekitd.dictionary([
30-
keys.offset: offset,
31-
keys.sourceFile: snapshot.uri.sourcekitdSourceFile,
32-
])
31+
let semanticRefactor = try await self.refactoring(refactorCommand)
3332

34-
if let primaryFile = snapshot.uri.primaryFile?.pseudoPath {
35-
skreq.set(keys.primaryFile, to: primaryFile)
36-
}
37-
if let compilerArgs = compileCommand?.compilerArgs {
38-
skreq.set(keys.compilerArgs, to: compilerArgs as [any SKDRequestValue])
33+
guard let edit = semanticRefactor.edit.changes?.first?.value.first else {
34+
throw ResponseError.unknown("No selector found at cursor position")
3935
}
4036

41-
let dict = try await send(sourcekitdRequest: \.objcSelector, skreq, snapshot: snapshot)
42-
if let selectorText: String = dict[keys.text] {
43-
return .string(selectorText)
37+
let prefix = "// Objective-C Selector: "
38+
if let range = edit.newText.range(of: prefix) {
39+
let selector = String(edit.newText[range.upperBound...]).trimmingCharacters(in: .whitespacesAndNewlines)
40+
if let sourceKitLSPServer {
41+
// Send a simple notification; clients like noice can render this nicely.
42+
sourceKitLSPServer.sendNotificationToClient(
43+
ShowMessageNotification(type: .info, message: "Objective-C selector: \(selector)")
44+
)
45+
}
46+
return .string(selector)
4447
}
4548

46-
throw ResponseError.unknown("No Objective-C selector found at cursor position")
49+
throw ResponseError.unknown("Could not extract selector from refactoring result")
4750
}
4851
}

Sources/SwiftLanguageService/SwiftLanguageService.swift

Lines changed: 14 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -965,13 +965,23 @@ extension SwiftLanguageService {
965965

966966
var canInlineMacro = false
967967

968-
var refactorActions = cursorInfoResponse.refactorActions.compactMap {
969-
let lspCommand = $0.asCommand()
968+
var refactorActions: [CodeAction] = cursorInfoResponse.refactorActions.compactMap { action in
969+
if action.actionString == "source.refactoring.kind.copy.objc.selector" {
970+
let copyCommand = CopyObjCSelectorCommand(
971+
title: "Copy Objective-C Selector",
972+
actionString: action.actionString,
973+
positionRange: params.range,
974+
textDocument: params.textDocument
975+
).asCommand()
976+
return CodeAction(title: "Copy Objective-C Selector", kind: .refactor, command: copyCommand)
977+
}
978+
979+
let lspCommand = action.asCommand()
970980
if !canInlineMacro {
971-
canInlineMacro = $0.actionString == "source.refactoring.kind.inline.macro"
981+
canInlineMacro = action.actionString == "source.refactoring.kind.inline.macro"
972982
}
973983

974-
return CodeAction(title: $0.title, kind: .refactor, command: lspCommand)
984+
return CodeAction(title: action.title, kind: .refactor, command: lspCommand)
975985
}
976986

977987
if canInlineMacro {
@@ -981,51 +991,9 @@ extension SwiftLanguageService {
981991
refactorActions.append(CodeAction(title: expandMacroCommand.title, kind: .refactor, command: expandMacroCommand))
982992
}
983993

984-
if let copySelectorAction = await makeCopyObjCSelectorAction(
985-
range: params.range,
986-
textDocument: params.textDocument,
987-
snapshot: snapshot
988-
) {
989-
refactorActions.append(copySelectorAction)
990-
}
991-
992994
return refactorActions
993995
}
994996

995-
private func makeCopyObjCSelectorAction(
996-
range: Range<Position>,
997-
textDocument: LanguageServerProtocol.TextDocumentIdentifier,
998-
snapshot: DocumentSnapshot
999-
) async -> CodeAction? {
1000-
let compileCommand = await self.compileCommand(for: snapshot.uri, fallbackAfterTimeout: true)
1001-
let offset = snapshot.utf8Offset(of: range.lowerBound)
1002-
1003-
let keys = self.keys
1004-
let primaryFile = snapshot.uri.primaryFile?.pseudoPath
1005-
let compilerArgs: [any SKDRequestValue] = compileCommand?.compilerArgs ?? []
1006-
let skreq = sourcekitd.dictionary([
1007-
keys.offset: offset,
1008-
keys.sourceFile: snapshot.uri.sourcekitdSourceFile,
1009-
keys.primaryFile: primaryFile,
1010-
keys.compilerArgs: compilerArgs
1011-
])
1012-
1013-
do {
1014-
let dict = try await send(sourcekitdRequest: \.objcSelector, skreq, snapshot: snapshot)
1015-
if dict[keys.text] as String? != nil {
1016-
let copyCommand = CopyObjCSelectorCommand(
1017-
positionRange: range,
1018-
textDocument: textDocument
1019-
).asCommand()
1020-
return CodeAction(title: "Copy Objective-C Selector", kind: .refactor, command: copyCommand)
1021-
}
1022-
} catch {
1023-
logger.debug("CopyObjCSelector: applicability check failed: \(error.forLogging)")
1024-
}
1025-
1026-
return nil
1027-
}
1028-
1029997
func retrieveQuickFixCodeActions(_ params: CodeActionRequest) async throws -> [CodeAction] {
1030998
let snapshot = try await self.latestSnapshot(for: params.textDocument.uri)
1031999
let buildSettings = await self.compileCommand(for: params.textDocument.uri, fallbackAfterTimeout: true)

0 commit comments

Comments
 (0)