Skip to content

Commit f7e4127

Browse files
committed
added swifty json module and implementation of several commands
1 parent ad82991 commit f7e4127

5 files changed

Lines changed: 293 additions & 49 deletions

File tree

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
[submodule "XPCService/Starscream"]
22
path = XPCService/Starscream
33
url = https://github.com/daltoniam/Starscream
4+
[submodule "SourceEditorExtension/SwiftyJSON"]
5+
path = SourceEditorExtension/SwiftyJSON
6+
url = https://github.com/SwiftyJSON/SwiftyJSON.git

SourceEditorExtension/SwiftyJSON

Submodule SwiftyJSON added at d932f64

SourceEditorExtension/VoiceCodeSourceEditorCommand.swift

Lines changed: 137 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import Foundation
1010
import XcodeKit
11+
import SwiftyJSON
1112

1213
class SourceEditorCommand: NSObject, XCSourceEditorCommand {
1314

@@ -21,17 +22,68 @@ class SourceEditorCommand: NSObject, XCSourceEditorCommand {
2122
deinit {
2223
}
2324

24-
// func convertToDictionary(text: String) -> [String: Any]? {
25-
// if let data = text.data(using: .utf8) {
26-
// do {
27-
// return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
28-
// } catch {
29-
// print(error.localizedDescription)
30-
// }
31-
// }
32-
// return nil
33-
// }
25+
func isInsertionPoint(range: XCSourceTextRange) -> Bool{
26+
27+
if (range.start.line != range.end.line) {
28+
return false
29+
}
30+
31+
if (range.start.column != range.end.column) {
32+
return false
33+
}
34+
35+
return true
36+
}
37+
38+
func checkLineNumber(lineNumber: Int, nLinesInBuffer: Int) -> Int {
39+
var checkedLineNumber = -1 //TODO: probably better to use an optional
40+
41+
if(lineNumber < 0) {
42+
checkedLineNumber = 0
43+
}
44+
else if(lineNumber >= nLinesInBuffer) {
45+
checkedLineNumber = nLinesInBuffer - 1
46+
}
47+
else {
48+
checkedLineNumber = lineNumber
49+
}
50+
51+
return checkedLineNumber
52+
}
53+
54+
func getLineLength(lineNumber: Int, nLinesInBuffer: Int, buffer: XCSourceTextBuffer) -> Int{
55+
let text = buffer.lines[checkLineNumber(lineNumber: lineNumber, nLinesInBuffer: nLinesInBuffer)] as! String
56+
return text.characters.count
57+
}
58+
59+
func makeRange(startLine: Int, endLine: Int, nLinesInBuffer: Int, startColumn: Int = 0, endColumn: Int = 0, numberOfColumnsInLine: Int = 0) -> XCSourceTextRange {
60+
let newRange = XCSourceTextRange()
61+
62+
if(startColumn < 0) {
63+
newRange.start.column = 0
64+
}
65+
else if(startColumn > numberOfColumnsInLine) {
66+
newRange.start.column = numberOfColumnsInLine
67+
}
68+
else {
69+
newRange.start.column = startColumn
70+
}
71+
72+
if(endColumn < 0) {
73+
newRange.end.column = 0
74+
}
75+
else if(endColumn > numberOfColumnsInLine) {
76+
newRange.end.column = numberOfColumnsInLine
77+
}
78+
else {
79+
newRange.end.column = endColumn
80+
}
3481

82+
newRange.start.line = checkLineNumber(lineNumber: startLine, nLinesInBuffer: nLinesInBuffer)
83+
newRange.end.line = checkLineNumber(lineNumber: endLine, nLinesInBuffer: nLinesInBuffer)
84+
85+
return newRange
86+
}
3587

3688
func perform(with invocation: XCSourceEditorCommandInvocation, completionHandler: @escaping (Error?) -> Void) -> Void
3789
{
@@ -46,46 +98,88 @@ class SourceEditorCommand: NSObject, XCSourceEditorCommand {
4698
//NSLog(buffer.contentUTI)
4799
NSLog(command)
48100

49-
// let dict = convertToDictionary(text: command)
50-
//
51-
// switch(dict!["id"]) {
52-
//
53-
// case "initial-state":
54-
// NSLog("initial state - not handled")
55-
// break
56-
// case "editor:move-to-line-number":
57-
// let newRange = XCSourceTextRange()
58-
// newRange.start.column = 0
59-
// newRange.start.line = 3
60-
// newRange.end.column = 0
61-
// newRange.end.line = 3
62-
//
63-
// buffer.selections[0] = newRange
64-
// break
65-
// case "editor:move-to-line-number-and-way-right":
66-
// break
67-
// case "editor:move-to-line-number-and-way-left":
68-
// break
69-
// case "editor:insert-under-line-number":
70-
// break
71-
// case "editor:select-line-number":
72-
// break
101+
let dataFromString = command.data(using: .utf8)
102+
let json = try? JSON(data: dataFromString!)
103+
let nLinesInBuffer = buffer.lines.count
104+
105+
switch(json!["id"].stringValue) {
106+
107+
case "initial-state":
108+
NSLog("initial state - not handled")
109+
break
110+
// MARK: -
111+
// MARK: Editor overrides
112+
case "editor:move-to-line-number":
113+
let line = json!["line"].intValue - 1
114+
buffer.selections[0] = makeRange(startLine: line, endLine: line, nLinesInBuffer: nLinesInBuffer)
115+
break
116+
case "editor:move-to-line-number-and-way-right":
117+
let line = json!["line"].intValue - 1
118+
let lineLength = getLineLength(lineNumber: line, nLinesInBuffer: nLinesInBuffer, buffer: buffer)
119+
120+
buffer.selections[0] = makeRange(startLine: line, endLine: line, nLinesInBuffer: nLinesInBuffer, startColumn: lineLength - 1, endColumn: lineLength - 1, numberOfColumnsInLine: lineLength)
121+
// TODO: tell xcode 2 navigate to selection in case selection was offscreen
122+
break
123+
case "editor:move-to-line-number-and-way-left":
124+
let line = json!["line"].intValue - 1
125+
let lineLength = getLineLength(lineNumber: line, nLinesInBuffer: nLinesInBuffer, buffer: buffer)
126+
127+
buffer.selections[0] = makeRange(startLine: line, endLine: line, nLinesInBuffer: nLinesInBuffer, startColumn: 0, endColumn: 0, numberOfColumnsInLine: lineLength)
128+
// TODO: tell xcode 2 navigate to selection in case selection was offscreen
129+
break
130+
case "editor:insert-under-line-number":
131+
let line = checkLineNumber(lineNumber: json!["line"].intValue - 1, nLinesInBuffer: nLinesInBuffer)
132+
//TODO: probably better to use an optional
133+
if line > -1 {
134+
buffer.lines.insert("", at: line)
135+
}
136+
break
137+
case "editor:select-line-number":
138+
let line = json!["line"].intValue - 1
139+
let lineLength = getLineLength(lineNumber: line, nLinesInBuffer: nLinesInBuffer, buffer: buffer)
140+
141+
buffer.selections[0] = makeRange(startLine: line, endLine: line, nLinesInBuffer: nLinesInBuffer, startColumn: 0, endColumn: lineLength, numberOfColumnsInLine: lineLength)
142+
143+
// TODO: tell xcode 2 navigate to selection in case selection was offscreen
144+
break
73145
// case "editor:expand-selection-to-scope":
74146
// break
75147
// case "editor:click-expand-selection-to-scope":
76148
// break
77-
// case "editor:select-line-number-range":
78-
// break
79-
// case "editor:extend-selection-to-line-number":
80-
// break
81-
// case "editor:insert-from-line-number":
82-
// break
149+
case "editor:select-line-number-range":
150+
let firstLine = json!["first"].intValue - 1
151+
let lastLine = json!["last"].intValue - 1
152+
let lineLength = getLineLength(lineNumber: lastLine, nLinesInBuffer: nLinesInBuffer, buffer: buffer)
153+
154+
buffer.selections[0] = makeRange(startLine: firstLine, endLine: lastLine, nLinesInBuffer: nLinesInBuffer, startColumn: 0, endColumn: lineLength, numberOfColumnsInLine: lineLength)
155+
156+
// TODO: tell xcode 2 navigate to selection in case selection was offscreen
157+
break
158+
case "editor:extend-selection-to-line-number":
159+
break
160+
case "editor:insert-from-line-number":
161+
//TODO: this is not quite working
162+
let line = json!["line"].intValue - 1
163+
let checkedLine = checkLineNumber(lineNumber: line, nLinesInBuffer: nLinesInBuffer)
164+
//TODO: probably better to use an optional
165+
let range = buffer.selections[0] as! XCSourceTextRange
166+
if checkedLine > -1 && isInsertionPoint(range: range) {
167+
var currentLine = buffer.lines[range.start.line] as! String
168+
let textToInsert = buffer.lines[checkedLine] as! String
169+
let insertIndex = currentLine.index(currentLine.startIndex, offsetBy: range.start.column)
170+
currentLine.insert(contentsOf: textToInsert.characters, at: insertIndex)
171+
buffer.lines.replaceObject(at: range.start.line, with: currentLine)
172+
}
173+
 break
83174
// case "editor:toggle-comments":
84175
// break
85176
// case "editor:insert-code-template":
86177
// break
87178
// case "editor:complete-code-template":
88179
// break
180+
181+
// MARK: -
182+
// MARK: Selection overrides
89183
// case "selection:previous-occurrence":
90184
// break
91185
// case "selection:next-occurrence":
@@ -108,11 +202,10 @@ class SourceEditorCommand: NSObject, XCSourceEditorCommand {
108202
// break
109203
// case "selection:next-word-by-surrounding-characters":
110204
// break
111-
// default:
112-
// NSLog("not handled")
113-
// }
205+
default:
206+
NSLog("not handled")
207+
}
114208

115-
//TODO: do something with the invocation buffer
116209
connection.invalidate()
117210
completionHandler(nil)
118211
}

0 commit comments

Comments
 (0)