Skip to content

Commit aa8c223

Browse files
authored
Implement Basic CLI (#17) (#667)
* Implement Basic CLI (#17) * Fix SwiftLint related issues * add option to link shell command from settings * add fallback installation method using osascript
1 parent 8b7a470 commit aa8c223

File tree

9 files changed

+159
-3
lines changed

9 files changed

+159
-3
lines changed

CodeEdit.xcworkspace/contents.xcworkspacedata

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

CodeEdit/AppDelegate.swift

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ final class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
4040
checkForFilesToOpen()
4141

4242
DispatchQueue.main.async {
43+
var needToHandleOpen = true
44+
4345
if NSApp.windows.isEmpty {
4446
if let projects = UserDefaults.standard.array(forKey: AppDelegate.recoverWorkspacesKey) as? [String],
4547
!projects.isEmpty {
@@ -51,9 +53,27 @@ final class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
5153
document?.windowControllers.first?.synchronizeWindowTitleWithDocumentName()
5254
}
5355
}
54-
return
56+
57+
needToHandleOpen = false
58+
}
59+
}
60+
61+
for index in 0..<CommandLine.arguments.count {
62+
if CommandLine.arguments[index] == "--open" && (index + 1) < CommandLine.arguments.count {
63+
let path = CommandLine.arguments[index+1]
64+
let url = URL(fileURLWithPath: path)
65+
66+
CodeEditDocumentController.shared.reopenDocument(for: url,
67+
withContentsOf: url,
68+
display: true) { document, _, _ in
69+
document?.windowControllers.first?.synchronizeWindowTitleWithDocumentName()
70+
}
71+
72+
needToHandleOpen = false
5573
}
74+
}
5675

76+
if needToHandleOpen {
5777
self.handleOpen()
5878
}
5979
}

CodeEdit/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1240,6 +1240,6 @@
12401240
</dict>
12411241
</array>
12421242
<key>GitHash</key>
1243-
<string>e40500adc7005bbdc6cc1581f548070e4a65e9fe</string>
1243+
<string>037eed1d0c60b2023aaf0ad9558b8d851c6f4f29</string>
12441244
</dict>
12451245
</plist>

CodeEditCli/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.swiftpm/

CodeEditCli/Package.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// swift-tools-version:5.5
2+
3+
import PackageDescription
4+
5+
let package = Package(
6+
name: "CodeEditCli",
7+
products: [
8+
.executable(name: "CodeEditCli", targets: ["CodeEditCli"])
9+
],
10+
dependencies: [],
11+
targets: [
12+
.executableTarget(
13+
name: "CodeEditCli"
14+
),
15+
]
16+
)
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//
2+
// CodeEditCli.swift
3+
//
4+
//
5+
// Created by Ben Koska on 14.06.22.
6+
//
7+
8+
import Foundation
9+
10+
func convertToAbsolutePath(_ path: String) -> String {
11+
let nsString = NSString(string: path)
12+
if nsString.isAbsolutePath {
13+
return nsString.standardizingPath
14+
}
15+
16+
return String(
17+
URL(
18+
string: path,
19+
relativeTo: URL(
20+
fileURLWithPath: FileManager.default.currentDirectoryPath
21+
)
22+
)?.pathComponents.joined(separator: "/").dropFirst(1) ?? ""
23+
)
24+
}
25+
26+
func openApp(paths: [String]? = nil) {
27+
let task = Process()
28+
task.launchPath = "/usr/bin/open" // This should be the same on all installations of MacOS
29+
30+
task.arguments = ["-a", "CodeEdit"]
31+
32+
if let paths = paths {
33+
task.arguments?.append("--args")
34+
for path in paths {
35+
task.arguments?.append("--open")
36+
task.arguments?.append(convertToAbsolutePath(path))
37+
}
38+
}
39+
40+
task.launch()
41+
}
42+
43+
if CommandLine.arguments.count < 2 {
44+
openApp()
45+
} else {
46+
openApp(paths: Array(CommandLine.arguments.dropFirst(1)))
47+
}
Binary file not shown.

CodeEditModules/Modules/AppPreferences/src/Sections/GeneralPreferences/GeneralPreferencesView.swift

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public struct GeneralPreferencesView: View {
4949
Group {
5050
openInCodeEditToggle
5151
revealFileOnFocusChangeToggle
52+
shellCommandSection
5253
}
5354
}
5455
}
@@ -208,6 +209,73 @@ private extension GeneralPreferencesView {
208209
.disabled(true)
209210
}
210211

212+
var shellCommandSection: some View {
213+
PreferencesSection("Shell Command", align: .center) {
214+
Button(action: {
215+
do {
216+
let url = Bundle.module.url(forResource: "codeedit", withExtension: nil, subdirectory: "Resources")
217+
let destination = "/usr/local/bin/codeedit"
218+
219+
if FileManager.default.fileExists(atPath: destination) {
220+
try FileManager.default.removeItem(atPath: destination)
221+
}
222+
223+
guard let shellUrl = url?.path else {
224+
print("Failed to get URL to shell command")
225+
return
226+
}
227+
228+
NSWorkspace.shared.requestAuthorization(to: .createSymbolicLink) { auth, error in
229+
guard let auth = auth, error == nil else {
230+
fallbackShellInstallation(commandPath: shellUrl, destinationPath: destination)
231+
return
232+
}
233+
234+
do {
235+
try FileManager(authorization: auth).createSymbolicLink(
236+
atPath: destination, withDestinationPath: shellUrl
237+
)
238+
} catch {
239+
fallbackShellInstallation(commandPath: shellUrl, destinationPath: destination)
240+
}
241+
}
242+
} catch {
243+
print(error)
244+
}
245+
}, label: {
246+
Text("Install 'codeedit' command")
247+
.padding(.horizontal, 10)
248+
})
249+
.buttonStyle(.bordered)
250+
}
251+
}
252+
253+
func fallbackShellInstallation(commandPath: String, destinationPath: String) {
254+
let cmd = [
255+
"osascript",
256+
"-e",
257+
"\"do shell script \\\"mkdir -p /usr/local/bin && ln -sf \'\(commandPath)\' \'\(destinationPath)\'\\\"\"",
258+
"with administrator privileges"
259+
]
260+
261+
let cmdStr = cmd.joined(separator: " ")
262+
263+
let task = Process()
264+
let pipe = Pipe()
265+
266+
task.standardOutput = pipe
267+
task.standardError = pipe
268+
task.arguments = ["-c", cmdStr]
269+
task.executableURL = URL(fileURLWithPath: "/bin/zsh")
270+
task.standardInput = nil
271+
272+
do {
273+
try task.run()
274+
} catch {
275+
print(error)
276+
}
277+
}
278+
211279
var openInCodeEditToggle: some View {
212280
PreferencesSection("Finder Context Menu", hideLabels: false) {
213281
Toggle("Show “Open With CodeEdit” option", isOn: $openInCodeEdit)

CodeEditModules/Package.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,8 @@ let package = Package(
232232
"CodeEditSymbols",
233233
"CodeEditTextView",
234234
],
235-
path: "Modules/AppPreferences/src"
235+
path: "Modules/AppPreferences/src",
236+
resources: [.copy("Resources")]
236237
),
237238
.target(
238239
name: "About",

0 commit comments

Comments
 (0)