Skip to content

Commit e70149f

Browse files
committed
Merge branch 'main' into feat/lsp-semantic-highlighter
2 parents 61a52cf + f24981a commit e70149f

File tree

14 files changed

+87
-33
lines changed

14 files changed

+87
-33
lines changed

CodeEdit.xcodeproj/project.pbxproj

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@
344344
661EF7BD2BEE215300C3E577 /* LoadingFileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 661EF7BC2BEE215300C3E577 /* LoadingFileView.swift */; };
345345
664935422C35A5BC00461C35 /* NSTableViewWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 664935412C35A5BC00461C35 /* NSTableViewWrapper.swift */; };
346346
6653EE552C34817900B82DE2 /* QuickSearchResultLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6653EE542C34817900B82DE2 /* QuickSearchResultLabel.swift */; };
347-
669A50512C380C1800304CD8 /* String+escapedWhiteSpaces.swift in Sources */ = {isa = PBXBuildFile; fileRef = 669A50502C380C1800304CD8 /* String+escapedWhiteSpaces.swift */; };
347+
669A50512C380C1800304CD8 /* String+Escaped.swift in Sources */ = {isa = PBXBuildFile; fileRef = 669A50502C380C1800304CD8 /* String+Escaped.swift */; };
348348
669A50532C380C8E00304CD8 /* Collection+subscript_safe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 669A50522C380C8E00304CD8 /* Collection+subscript_safe.swift */; };
349349
669BC4082BED306400D1197C /* AnyFileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 669BC4072BED306400D1197C /* AnyFileView.swift */; };
350350
66AF6CE22BF17CC300D83C9D /* StatusBarViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66AF6CE12BF17CC300D83C9D /* StatusBarViewModel.swift */; };
@@ -1056,7 +1056,7 @@
10561056
661EF7BC2BEE215300C3E577 /* LoadingFileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingFileView.swift; sourceTree = "<group>"; };
10571057
664935412C35A5BC00461C35 /* NSTableViewWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSTableViewWrapper.swift; sourceTree = "<group>"; };
10581058
6653EE542C34817900B82DE2 /* QuickSearchResultLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickSearchResultLabel.swift; sourceTree = "<group>"; };
1059-
669A50502C380C1800304CD8 /* String+escapedWhiteSpaces.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+escapedWhiteSpaces.swift"; sourceTree = "<group>"; };
1059+
669A50502C380C1800304CD8 /* String+Escaped.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Escaped.swift"; sourceTree = "<group>"; };
10601060
669A50522C380C8E00304CD8 /* Collection+subscript_safe.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Collection+subscript_safe.swift"; sourceTree = "<group>"; };
10611061
669BC4072BED306400D1197C /* AnyFileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyFileView.swift; sourceTree = "<group>"; };
10621062
66AF6CE12BF17CC300D83C9D /* StatusBarViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusBarViewModel.swift; sourceTree = "<group>"; };
@@ -2549,7 +2549,7 @@
25492549
children = (
25502550
61538B8F2B111FE800A88846 /* String+AppearancesOfSubstring.swift */,
25512551
61538B922B11201900A88846 /* String+Character.swift */,
2552-
669A50502C380C1800304CD8 /* String+escapedWhiteSpaces.swift */,
2552+
669A50502C380C1800304CD8 /* String+Escaped.swift */,
25532553
85745D622A38F8D900089AAB /* String+HighlightOccurrences.swift */,
25542554
6CED16E32A3E660D000EC962 /* String+Lines.swift */,
25552555
58D01C8E293167DC00C5B6B4 /* String+MD5.swift */,
@@ -4594,7 +4594,7 @@
45944594
B65B10F52B081A0C002852CF /* SourceControlAddExistingRemoteView.swift in Sources */,
45954595
58D01C99293167DC00C5B6B4 /* String+MD5.swift in Sources */,
45964596
20EBB505280C329800F3A5DA /* CommitListItemView.swift in Sources */,
4597-
669A50512C380C1800304CD8 /* String+escapedWhiteSpaces.swift in Sources */,
4597+
669A50512C380C1800304CD8 /* String+Escaped.swift in Sources */,
45984598
5878DAB2291D627C00DD95A3 /* EditorJumpBarView.swift in Sources */,
45994599
664935422C35A5BC00461C35 /* NSTableViewWrapper.swift in Sources */,
46004600
04BC1CDE2AD9B4B000A83EA5 /* EditorFileTabCloseButton.swift in Sources */,
@@ -4831,7 +4831,7 @@
48314831
GENERATE_INFOPLIST_FILE = NO;
48324832
INFOPLIST_FILE = CodeEdit/Info.plist;
48334833
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools";
4834-
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022-2024 CodeEdit";
4834+
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022-2025 CodeEdit";
48354835
INFOPLIST_KEY_NSPrincipalClass = CodeEdit.CodeEditApplication;
48364836
LD_RUNPATH_SEARCH_PATHS = (
48374837
"$(inherited)",
@@ -5023,7 +5023,7 @@
50235023
GENERATE_INFOPLIST_FILE = NO;
50245024
INFOPLIST_FILE = CodeEdit/Info.plist;
50255025
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools";
5026-
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022-2024 CodeEdit";
5026+
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022-2025 CodeEdit";
50275027
INFOPLIST_KEY_NSPrincipalClass = CodeEdit.CodeEditApplication;
50285028
LD_RUNPATH_SEARCH_PATHS = (
50295029
"$(inherited)",
@@ -5283,7 +5283,7 @@
52835283
GENERATE_INFOPLIST_FILE = NO;
52845284
INFOPLIST_FILE = CodeEdit/Info.plist;
52855285
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools";
5286-
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022-2024 CodeEdit";
5286+
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022-2025 CodeEdit";
52875287
INFOPLIST_KEY_NSPrincipalClass = CodeEdit.CodeEditApplication;
52885288
LD_RUNPATH_SEARCH_PATHS = (
52895289
"$(inherited)",
@@ -5544,7 +5544,7 @@
55445544
GENERATE_INFOPLIST_FILE = NO;
55455545
INFOPLIST_FILE = CodeEdit/Info.plist;
55465546
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools";
5547-
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022-2024 CodeEdit";
5547+
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022-2025 CodeEdit";
55485548
INFOPLIST_KEY_NSPrincipalClass = CodeEdit.CodeEditApplication;
55495549
LD_RUNPATH_SEARCH_PATHS = (
55505550
"$(inherited)",
@@ -5584,7 +5584,7 @@
55845584
GENERATE_INFOPLIST_FILE = NO;
55855585
INFOPLIST_FILE = CodeEdit/Info.plist;
55865586
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools";
5587-
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022-2024 CodeEdit";
5587+
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022-2025 CodeEdit";
55885588
INFOPLIST_KEY_NSPrincipalClass = CodeEdit.CodeEditApplication;
55895589
LD_RUNPATH_SEARCH_PATHS = (
55905590
"$(inherited)",

CodeEdit/Features/CEWorkspaceSettings/Models/CETask.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class CETask: ObservableObject, Identifiable, Hashable, Codable {
4242
/// Ensures that the shell navigates to the correct folder, and then executes the specified command.
4343
var fullCommand: String {
4444
// Move into the specified folder if needed
45-
let changeDirectoryCommand = workingDirectory.isEmpty ? "" : "cd \(workingDirectory) && "
45+
let changeDirectoryCommand = workingDirectory.isEmpty ? "" : "cd \(workingDirectory.escapedDirectory()) && "
4646

4747
// Construct the full command
4848
return "\(changeDirectoryCommand)\(command)"

CodeEdit/Features/SourceControl/Client/GitClient+Clone.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ extension GitClient {
4141
remoteUrl: URL,
4242
localPath: URL
4343
) -> AsyncThrowingMapSequence<LiveCommandStream, CloneProgress> {
44-
let command = "clone \(remoteUrl.absoluteString) \(localPath.relativePath.escapedWhiteSpaces()) --progress"
44+
let command = "clone \(remoteUrl.absoluteString) \(localPath.relativePath.escapedDirectory()) --progress"
4545

4646
return self.runLive(command)
4747
.map { line in

CodeEdit/Features/SourceControl/Client/GitClient.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ class GitClient {
7878
}
7979

8080
private func generateCommand(_ command: String) -> String {
81-
"cd \(directoryURL.relativePath.escapedWhiteSpaces());git \(command)"
81+
"cd \(directoryURL.relativePath.escapedDirectory());git \(command)"
8282
}
8383

8484
private func processCommonErrors(_ output: String) throws -> String {

CodeEdit/Features/SourceControl/Client/GitConfigClient.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class GitConfigClient {
3434
if global {
3535
fullCommand += " --global"
3636
} else if let projectURL = projectURL {
37-
fullCommand = "cd \(projectURL.relativePath.escapedWhiteSpaces()); " + fullCommand
37+
fullCommand = "cd \(projectURL.relativePath.escapedDirectory()); " + fullCommand
3838
}
3939

4040
fullCommand += " \(command)"

CodeEdit/Features/Tasks/Models/CEActiveTask.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class CEActiveTask: ObservableObject, Identifiable, Hashable {
4040
// Because: CETask only contains information about the relative path.
4141
let fullCommand: String
4242
if let workspaceURL = workspaceURL {
43-
fullCommand = "cd \(workspaceURL.relativePath) && \(task.fullCommand)"
43+
fullCommand = "cd \(workspaceURL.relativePath.escapedDirectory()) && \(task.fullCommand)"
4444
} else {
4545
fullCommand = task.fullCommand
4646
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//
2+
// String+escapedWhiteSpaces.swift
3+
// CodeEdit
4+
//
5+
// Created by Paul Ebose on 2024/07/05.
6+
//
7+
8+
import Foundation
9+
10+
extension String {
11+
/// Escapes the string so it's an always-valid directory
12+
func escapedDirectory() -> String {
13+
"\"\(self.escapedQuotes())\""
14+
}
15+
16+
/// Returns a new string, replacing all occurrences of ` ` with `\ ` if they aren't already escaped.
17+
func escapedWhiteSpaces() -> String {
18+
escape(replacing: " ")
19+
}
20+
21+
/// Returns a new string, replacing all occurrences of `"` with `\"` if they aren't already escaped.
22+
func escapedQuotes() -> String {
23+
escape(replacing: #"""#)
24+
}
25+
26+
func escape(replacing: Character) -> String {
27+
var string = ""
28+
var lastChar: Character?
29+
30+
for char in self {
31+
defer {
32+
lastChar = char
33+
}
34+
35+
guard char == replacing else {
36+
string.append(char)
37+
continue
38+
}
39+
40+
if let lastChar, lastChar == #"\"# {
41+
string.append(char)
42+
continue
43+
}
44+
45+
string.append(#"\"#)
46+
string.append(char)
47+
}
48+
49+
return string
50+
}
51+
}

CodeEdit/Utils/Extensions/String/String+escapedWhiteSpaces.swift

Lines changed: 0 additions & 14 deletions
This file was deleted.

CodeEditTests/Utils/UnitTests_Extensions.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,4 +179,21 @@ final class CodeEditUtilsExtensionsUnitTests: XCTestCase {
179179
XCTAssertFalse(invalidCase.isValidFilename, "Detected valid case \"\(invalidCase)\", should be invalid.")
180180
}
181181
}
182+
183+
// MARK: - STRING + ESCAPED
184+
185+
func testEscapeQuotes() {
186+
let string = #"this/is/"a path/Hello "world"#
187+
XCTAssertEqual(string.escapedQuotes(), #"this/is/\"a path/Hello \"world"#)
188+
}
189+
190+
func testEscapeQuotesForAlreadyEscapedString() {
191+
let string = #"this/is/"a path/Hello \"world"#
192+
XCTAssertEqual(string.escapedQuotes(), #"this/is/\"a path/Hello \"world"#)
193+
}
194+
195+
func testEscapedDirectory() {
196+
let path = #"/Hello World/ With Spaces/ And " Characters "#
197+
XCTAssertEqual(path.escapedDirectory(), #""/Hello World/ With Spaces/ And \" Characters ""#)
198+
}
182199
}

Configs/Alpha.xcconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@
1010

1111
CE_APPICON_NAME = AppIconAlpha
1212
CE_VERSION_POSTFIX = -alpha
13-
CE_COPYRIGHT = Copyright © 2022-2024 CodeEdit
13+
CE_COPYRIGHT = Copyright © 2022-2025 CodeEdit

0 commit comments

Comments
 (0)