Skip to content

Commit d0224e8

Browse files
committed
Release 0.23.0
1 parent 4a8ae39 commit d0224e8

File tree

12 files changed

+3358
-28
lines changed

12 files changed

+3358
-28
lines changed

Copilot for Xcode.xcodeproj/project.pbxproj

+4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
3ABBEA2B2C8BA00300C61D61 /* copilot-language-server-arm64 in Resources */ = {isa = PBXBuildFile; fileRef = 3ABBEA2A2C8BA00300C61D61 /* copilot-language-server-arm64 */; };
1212
3ABBEA2C2C8BA00800C61D61 /* copilot-language-server-arm64 in Resources */ = {isa = PBXBuildFile; fileRef = 3ABBEA2A2C8BA00300C61D61 /* copilot-language-server-arm64 */; };
1313
3ABBEA2D2C8BA00B00C61D61 /* copilot-language-server in Resources */ = {isa = PBXBuildFile; fileRef = 3ABBEA282C8B9FE100C61D61 /* copilot-language-server */; };
14+
424ACA212CA4697200FA20F2 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 424ACA202CA4697200FA20F2 /* Credits.rtf */; };
1415
427C63282C6E868B000E557C /* OpenSettingsCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 427C63272C6E868B000E557C /* OpenSettingsCommand.swift */; };
1516
42888D512C66B10100DEF835 /* AuthStatusChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42888D502C66B10100DEF835 /* AuthStatusChecker.swift */; };
1617
C8009BFF2941C551007AA7E8 /* ToggleRealtimeSuggestionsCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8009BFE2941C551007AA7E8 /* ToggleRealtimeSuggestionsCommand.swift */; };
@@ -185,6 +186,7 @@
185186
/* Begin PBXFileReference section */
186187
3ABBEA282C8B9FE100C61D61 /* copilot-language-server */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; name = "copilot-language-server"; path = "Server/node_modules/@github/copilot-language-server/native/darwin-x64/copilot-language-server"; sourceTree = SOURCE_ROOT; };
187188
3ABBEA2A2C8BA00300C61D61 /* copilot-language-server-arm64 */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; name = "copilot-language-server-arm64"; path = "Server/node_modules/@github/copilot-language-server/native/darwin-arm64/copilot-language-server-arm64"; sourceTree = SOURCE_ROOT; };
189+
424ACA202CA4697200FA20F2 /* Credits.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = Credits.rtf; sourceTree = "<group>"; };
188190
427C63272C6E868B000E557C /* OpenSettingsCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenSettingsCommand.swift; sourceTree = "<group>"; };
189191
42888D502C66B10100DEF835 /* AuthStatusChecker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthStatusChecker.swift; sourceTree = "<group>"; };
190192
C8009BFE2941C551007AA7E8 /* ToggleRealtimeSuggestionsCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToggleRealtimeSuggestionsCommand.swift; sourceTree = "<group>"; };
@@ -379,6 +381,7 @@
379381
C8189B182938972F00C9DCDA /* Copilot for Xcode */ = {
380382
isa = PBXGroup;
381383
children = (
384+
424ACA202CA4697200FA20F2 /* Credits.rtf */,
382385
3ABBEA2A2C8BA00300C61D61 /* copilot-language-server-arm64 */,
383386
3ABBEA282C8B9FE100C61D61 /* copilot-language-server */,
384387
C87B03A3293B24AB00C77EAE /* Copilot-for-Xcode-Info.plist */,
@@ -655,6 +658,7 @@
655658
isa = PBXResourcesBuildPhase;
656659
buildActionMask = 2147483647;
657660
files = (
661+
424ACA212CA4697200FA20F2 /* Credits.rtf in Resources */,
658662
C8189B212938973000C9DCDA /* Preview Assets.xcassets in Resources */,
659663
C8189B1E2938973000C9DCDA /* Assets.xcassets in Resources */,
660664
3ABBEA292C8B9FE100C61D61 /* copilot-language-server in Resources */,

Copilot for Xcode/Credits.rtf

+3,219
Large diffs are not rendered by default.

Docs/accessibility-permission.png

-569 KB
Loading

Docs/dmg-open.png

78.8 KB
Loading

Docs/extension-permission.png

-572 KB
Loading

Docs/xcode-menu.png

-10.8 KB
Loading

README.md

+20-17
Original file line numberDiff line numberDiff line change
@@ -24,35 +24,38 @@ As per [GitHub's Terms of Service](https://docs.github.com/en/github/site-policy
2424
Updates can be downloaded and installed by the app.
2525

2626
1. Open the `dmg` and drag the `GitHub Copilot for Xcode.app` into the `Applications` folder.
27-
<br>
28-
<img alt="Screenshot of opened dmg" src="./Docs/dmg-open.png" width="468" />
27+
<p align="center">
28+
<img alt="Screenshot of opened dmg" src="./Docs/dmg-open.png" width="512" />
29+
</p>
2930

3031
1. On the first opening the application it will warn that it was downloaded from the internet. Click `Open` to proceed.
31-
<br>
32-
<img alt="Screenshot of downloaded from the internet warning" src="./Docs/downloaded-from-internet.png" width="372" />
32+
<p align="center">
33+
<img alt="Screenshot of downloaded from the internet warning" src="./Docs/downloaded-from-internet.png" width="372" />
34+
</p>
3335

3436
1. A background item will be added for the application to be able to start itself when Xcode starts.
35-
<br>
36-
<img alt="Screenshot of background item" src="./Docs/background-item.png" width="370" />
37+
<p align="center">
38+
<img alt="Screenshot of background item" src="./Docs/background-item.png" width="370" />
39+
</p>
3740

3841
1. Two important permissions are required for the application to operate well: `Accessibility` and `Xcode Source Editor Extension`. The first time the application is run these permissions should be requested. You may need to click `Refresh` in the settings if not prompted.
39-
<br>
40-
<img alt="Screenshot of accessibility permission request" src="./Docs/accessibility-permission-request.png" width="529" />
41-
<img alt="Screenshot of accessibility permission" src="./Docs/accessibility-permission.png" width="827" />
42-
<img alt="Screenshot of extension permission" src="./Docs/extension-permission.png" width="827" />
42+
<p align="center">
43+
<img alt="Screenshot of accessibility permission request" src="./Docs/accessibility-permission-request.png" width="529" />
44+
<img alt="Screenshot of extension permission" src="./Docs/extension-permission.png" width="582" />
45+
</p>
4346

4447
1. After granting the extension permission, please restart Xcode so the `Github Copilot` menu is available under the Xcode `Editor` menu.
4548
<br>
46-
<br>
47-
<img alt="Screenshot of Xcode Editor GitHub Copilot menu item" src="./Docs/xcode-menu.png" width="703" />
49+
<p align="center">
50+
<img alt="Screenshot of Xcode Editor GitHub Copilot menu item" src="./Docs/xcode-menu.png" width="648" />
51+
</p>
4852

4953
1. To sign into GitHub Copilot, click the `Sign in` button in the settings application. This will open a browser window and copy a code to the clipboard. Paste the code into the GitHub login page and authorize the application.
50-
<br>
51-
<img alt="Screenshot of sign-in popup" src="./Docs/device-code.png" width="372" />
54+
<p align="center">
55+
<img alt="Screenshot of sign-in popup" src="./Docs/device-code.png" width="372" />
56+
</p>
5257

5358
1. To install updates, click `Check for Updates` from the menu item or in the settings application. After installing a new version, Xcode must be restarted to use the new version correctly. New versions can also be installed from `dmg` files downloaded from the releases page. When installing a new version via `dmg`, the application must be run manually the first time to accept the downloaded from the internet warning.
54-
<br>
55-
<image alt="Screenshot of update message" src="./Docs/update-message.png" width="372" />
5659

5760
## License
5861

@@ -67,4 +70,4 @@ forum](https://github.com/orgs/community/discussions/categories/copilot).
6770

6871
## Acknowledgement
6972

70-
Thank you to @intitni for creating the original that this project is based on.
73+
Thank you to @intitni for creating the original that this project is based on.

Server/package-lock.json

+4-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Server/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
"description": "Package for downloading @github/copilot-language-server",
55
"private": true,
66
"dependencies": {
7-
"@github/copilot-language-server": "^1.232.0"
7+
"@github/copilot-language-server": "^1.234.0"
88
}
99
}

Tool/Sources/AXExtension/AXUIElement.swift

+54-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public extension AXUIElement {
2121
var value: String {
2222
(try? copyValue(key: kAXValueAttribute)) ?? ""
2323
}
24-
24+
2525
var intValue: Int? {
2626
(try? copyValue(key: kAXValueAttribute))
2727
}
@@ -187,6 +187,16 @@ public extension AXUIElement {
187187
return nil
188188
}
189189

190+
/// Get children that match the requirement
191+
///
192+
/// - important: If the element has a lot of descendant nodes, it will heavily affect the
193+
/// **performance of Xcode**. Please make use ``AXUIElement\traverse(_:)`` instead.
194+
@available(
195+
*,
196+
deprecated,
197+
renamed: "traverse(_:)",
198+
message: "Please make use ``AXUIElement\traverse(_:)`` instead."
199+
)
190200
func children(where match: (AXUIElement) -> Bool) -> [AXUIElement] {
191201
var all = [AXUIElement]()
192202
for child in children {
@@ -229,6 +239,49 @@ public extension AXUIElement {
229239
}
230240
}
231241

242+
public extension AXUIElement {
243+
enum SearchNextStep {
244+
case skipDescendants
245+
case skipSiblings
246+
case skipDescendantsAndSiblings
247+
case continueSearching
248+
case stopSearching
249+
}
250+
/// Traversing the element tree.
251+
///
252+
/// - important: Traversing the element tree is resource consuming and will affect the
253+
/// **performance of Xcode**. Please make sure to skip as much as possible.
254+
///
255+
/// - todo: Make it not recursive.
256+
func traverse(_ handle: (_ element: AXUIElement, _ level: Int) -> SearchNextStep) {
257+
func _traverse(
258+
element: AXUIElement,
259+
level: Int,
260+
handle: (AXUIElement, Int) -> SearchNextStep
261+
) -> SearchNextStep {
262+
let nextStep = handle(element, level)
263+
switch nextStep {
264+
case .stopSearching: return .stopSearching
265+
case .skipDescendants: return .continueSearching
266+
case .skipDescendantsAndSiblings: return .skipSiblings
267+
case .continueSearching, .skipSiblings:
268+
for child in element.children {
269+
switch _traverse(element: child, level: level + 1, handle: handle) {
270+
case .skipSiblings, .skipDescendantsAndSiblings:
271+
break
272+
case .stopSearching:
273+
return .stopSearching
274+
case .continueSearching, .skipDescendants:
275+
continue
276+
}
277+
}
278+
return nextStep
279+
}
280+
}
281+
_ = _traverse(element: self, level: 0, handle: handle)
282+
}
283+
}
284+
232285
// MARK: - Helper
233286

234287
public extension AXUIElement {

Tool/Sources/SharedUIComponents/SyntaxHighlighting.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,11 @@ public enum CodeHighlighting {
8383
func isEmptyLine(_ line: String) -> Bool {
8484
if line.isEmpty { return true }
8585
guard let regex = try? NSRegularExpression(pattern: #"^\s*\n?$"#) else { return false }
86+
let ns = NSString(string: line)
8687
if regex.firstMatch(
8788
in: line,
8889
options: [],
89-
range: NSMakeRange(0, line.utf16.count)
90+
range: NSMakeRange(0, ns.length)
9091
) != nil {
9192
return true
9293
}

Tool/Sources/XcodeInspector/Apps/XcodeAppInstanceInspector.swift

+54-4
Original file line numberDiff line numberDiff line change
@@ -360,16 +360,21 @@ extension XcodeAppInstanceInspector {
360360

361361
for window in windows {
362362
let workspaceIdentifier = workspaceIdentifier(window)
363+
var traverseCount = 0
363364

364365
let tabs = {
365366
guard let editArea = window.firstChild(where: { $0.description == "editor area" })
366367
else { return Set<String>() }
367368
var allTabs = Set<String>()
368-
let tabBars = editArea.children { $0.description == "tab bar" }
369+
let tabBars = editArea.tabBars
369370
for tabBar in tabBars {
370-
let tabs = tabBar.children { $0.roleDescription == "tab" }
371-
for tab in tabs {
372-
allTabs.insert(tab.title)
371+
tabBar.traverse { element, _ in
372+
traverseCount += 1
373+
if element.roleDescription == "tab" {
374+
allTabs.insert(element.title)
375+
return .skipDescendants
376+
}
377+
return .continueSearching
373378
}
374379
}
375380
return allTabs
@@ -398,3 +403,48 @@ extension XcodeAppInstanceInspector {
398403
}
399404
}
400405

406+
public extension AXUIElement {
407+
var tabBars: [AXUIElement] {
408+
// Searching by traversing with AXUIElement is (Xcode) resource consuming, we should skip
409+
// as much as possible!
410+
411+
guard let editArea: AXUIElement = {
412+
if description == "editor area" { return self }
413+
return firstChild(where: { $0.description == "editor area" })
414+
}() else { return [] }
415+
416+
var tabBars = [AXUIElement]()
417+
editArea.traverse { element, _ in
418+
let description = element.description
419+
if description == "Tab Bar" {
420+
element.traverse { element, _ in
421+
if element.description == "tab bar" {
422+
tabBars.append(element)
423+
return .stopSearching
424+
}
425+
return .continueSearching
426+
}
427+
return .skipDescendantsAndSiblings
428+
}
429+
430+
if element.identifier == "editor context" {
431+
return .skipDescendantsAndSiblings
432+
}
433+
if element.isSourceEditor {
434+
return .skipDescendantsAndSiblings
435+
}
436+
if description == "Code Coverage Ribbon" {
437+
return .skipDescendants
438+
}
439+
if description == "Debug Area" {
440+
return .skipDescendants
441+
}
442+
443+
if description == "debug bar" {
444+
return .skipDescendants
445+
}
446+
return .continueSearching
447+
}
448+
return tabBars
449+
}
450+
}

0 commit comments

Comments
 (0)