Skip to content

Commit ae57197

Browse files
committed
Merge branch 'main' into lsp-install
2 parents 08963a2 + f919bbb commit ae57197

File tree

8 files changed

+149
-67
lines changed

8 files changed

+149
-67
lines changed

CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

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

CodeEdit/Features/Editor/TabBar/Views/EditorTabBarContextMenu.swift

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
// Created by Khan Winter on 6/4/22.
66
//
77

8-
import Foundation
98
import SwiftUI
9+
import Foundation
1010

1111
extension View {
1212
func tabBarContextMenu(item: CEWorkspaceFile, isTemporary: Bool) -> some View {
@@ -149,24 +149,21 @@ struct EditorTabBarContextMenu: ViewModifier {
149149
guard let rootPath = workspace.workspaceFileManager?.folderUrl else {
150150
return
151151
}
152-
// Calculate the relative path
153-
var rootComponents = rootPath.standardizedFileURL.pathComponents
154-
var destinationComponents = item.url.standardizedFileURL.pathComponents
155-
156-
// Remove any same path components
157-
while !rootComponents.isEmpty && !destinationComponents.isEmpty
158-
&& rootComponents.first == destinationComponents.first {
159-
rootComponents.remove(at: 0)
160-
destinationComponents.remove(at: 0)
152+
let destinationComponents = item.url.standardizedFileURL.pathComponents
153+
let baseComponents = rootPath.standardizedFileURL.pathComponents
154+
155+
// Find common prefix length
156+
var prefixCount = 0
157+
while prefixCount < min(destinationComponents.count, baseComponents.count)
158+
&& destinationComponents[prefixCount] == baseComponents[prefixCount] {
159+
prefixCount += 1
161160
}
162-
163-
// Make a "../" for each remaining component in the root URL
164-
var relativePath: String = String(repeating: "../", count: rootComponents.count)
165-
// Add the remaining components for the destination url.
166-
relativePath += destinationComponents.joined(separator: "/")
161+
// Build the relative path
162+
let upPath = String(repeating: "../", count: baseComponents.count - prefixCount)
163+
let downPath = destinationComponents[prefixCount...].joined(separator: "/")
167164

168165
// Copy it to the clipboard
169166
NSPasteboard.general.clearContents()
170-
NSPasteboard.general.setString(relativePath, forType: .string)
167+
NSPasteboard.general.setString(upPath + downPath, forType: .string)
171168
}
172169
}

CodeEdit/Features/Editor/Views/CodeFileView.swift

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ struct CodeFileView: View {
3030
var lineHeightMultiple
3131
@AppSettings(\.textEditing.wrapLinesToEditorWidth)
3232
var wrapLinesToEditorWidth
33+
@AppSettings(\.textEditing.overscroll)
34+
var overscroll
3335
@AppSettings(\.textEditing.font)
3436
var settingsFont
3537
@AppSettings(\.theme.useThemeBackground)
@@ -38,8 +40,8 @@ struct CodeFileView: View {
3840
var matchAppearance
3941
@AppSettings(\.textEditing.letterSpacing)
4042
var letterSpacing
41-
@AppSettings(\.textEditing.bracketHighlight)
42-
var bracketHighlight
43+
@AppSettings(\.textEditing.bracketEmphasis)
44+
var bracketEmphasis
4345
@AppSettings(\.textEditing.useSystemCursor)
4446
var useSystemCursor
4547

@@ -48,6 +50,8 @@ struct CodeFileView: View {
4850

4951
@ObservedObject private var themeModel: ThemeModel = .shared
5052

53+
@State private var treeSitter = TreeSitterClient()
54+
5155
private var cancellables = Set<AnyCancellable>()
5256

5357
private let isEditable: Bool
@@ -97,23 +101,6 @@ struct CodeFileView: View {
97101

98102
@State private var font: NSFont = Settings[\.textEditing].font.current
99103

100-
@State private var bracketPairHighlight: BracketPairHighlight? = {
101-
let theme = ThemeModel.shared.selectedTheme ?? ThemeModel.shared.themes.first!
102-
let color = Settings[\.textEditing].bracketHighlight.useCustomColor
103-
? Settings[\.textEditing].bracketHighlight.color.nsColor
104-
: theme.editor.text.nsColor.withAlphaComponent(0.8)
105-
switch Settings[\.textEditing].bracketHighlight.highlightType {
106-
case .disabled:
107-
return nil
108-
case .flash:
109-
return .flash
110-
case .bordered:
111-
return .bordered(color: color)
112-
case .underline:
113-
return .underline(color: color)
114-
}
115-
}()
116-
117104
@Environment(\.edgeInsets)
118105
private var edgeInsets
119106

@@ -127,12 +114,15 @@ struct CodeFileView: View {
127114
indentOption: (codeFile.indentOption ?? indentOption).textViewOption(),
128115
lineHeight: lineHeightMultiple,
129116
wrapLines: codeFile.wrapLines ?? wrapLinesToEditorWidth,
117+
editorOverscroll: overscroll.overscrollPercentage,
130118
cursorPositions: $cursorPositions,
131119
useThemeBackground: useThemeBackground,
120+
highlightProviders: [treeSitter],
132121
contentInsets: edgeInsets.nsEdgeInsets,
122+
additionalTextInsets: NSEdgeInsets(top: 2, left: 0, bottom: 0, right: 0),
133123
isEditable: isEditable,
134124
letterSpacing: letterSpacing,
135-
bracketPairHighlight: bracketPairHighlight,
125+
bracketPairEmphasis: getBracketPairEmphasis(),
136126
useSystemCursor: useSystemCursor,
137127
undoManager: undoManager,
138128
coordinators: textViewCoordinators
@@ -151,19 +141,18 @@ struct CodeFileView: View {
151141
.onChange(of: settingsFont) { newFontSetting in
152142
font = newFontSetting.current
153143
}
154-
.onChange(of: bracketHighlight) { _ in
155-
bracketPairHighlight = getBracketPairHighlight()
156-
}
157144
}
158145

159-
private func getBracketPairHighlight() -> BracketPairHighlight? {
160-
let color = if Settings[\.textEditing].bracketHighlight.useCustomColor {
161-
Settings[\.textEditing].bracketHighlight.color.nsColor
146+
/// Determines the style of bracket emphasis based on the `bracketEmphasis` setting and the current theme.
147+
/// - Returns: The emphasis style to use for bracket pair emphasis.
148+
private func getBracketPairEmphasis() -> BracketPairEmphasis? {
149+
let color = if Settings[\.textEditing].bracketEmphasis.useCustomColor {
150+
Settings[\.textEditing].bracketEmphasis.color.nsColor
162151
} else {
163152
currentTheme.editor.text.nsColor.withAlphaComponent(0.8)
164153
}
165154

166-
switch Settings[\.textEditing].bracketHighlight.highlightType {
155+
switch Settings[\.textEditing].bracketEmphasis.highlightType {
167156
case .disabled:
168157
return nil
169158
case .flash:

CodeEdit/Features/Editor/Views/EditorAreaView.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ struct EditorAreaView: View {
4646
}
4747

4848
var editorInsetAmount: Double {
49-
let tabBarHeight = shouldShowTabBar ? (EditorTabBarView.height + 1) : 0
50-
let jumpBarHeight = showEditorJumpBar ? (EditorJumpBarView.height + 1) : 0
49+
let tabBarHeight = shouldShowTabBar ? (EditorTabBarView.height) : 0
50+
let jumpBarHeight = showEditorJumpBar ? (EditorJumpBarView.height) : 0
5151
return tabBarHeight + jumpBarHeight
5252
}
5353

CodeEdit/Features/NavigatorArea/ProjectNavigator/OutlineView/ProjectNavigatorMenu.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ final class ProjectNavigatorMenu: NSMenu {
5555
let openExternalEditor = menuItem("Open with External Editor", action: #selector(openWithExternalEditor))
5656
let openAs = menuItem("Open As", action: nil)
5757

58+
let copyPath = menuItem("Copy Path", action: #selector(copyPath))
59+
let copyRelativePath = menuItem("Copy Relative Path", action: #selector(copyRelativePath))
60+
5861
let showFileInspector = menuItem("Show File Inspector", action: nil)
5962

6063
let newFile = menuItem("New File...", action: #selector(newFile))
@@ -91,6 +94,9 @@ final class ProjectNavigatorMenu: NSMenu {
9194
openExternalEditor,
9295
openAs,
9396
NSMenuItem.separator(),
97+
copyPath,
98+
copyRelativePath,
99+
NSMenuItem.separator(),
94100
showFileInspector,
95101
NSMenuItem.separator(),
96102
newFile,

CodeEdit/Features/NavigatorArea/ProjectNavigator/OutlineView/ProjectNavigatorMenuActions.swift

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,42 @@ extension ProjectNavigatorMenu {
222222
}
223223
}
224224

225+
/// Copies the absolute path of the selected files
226+
@objc
227+
func copyPath() {
228+
let paths = selectedItems().map {
229+
$0.url.standardizedFileURL.path
230+
}.sorted().joined(separator: "\n")
231+
NSPasteboard.general.clearContents()
232+
NSPasteboard.general.setString(paths, forType: .string)
233+
}
234+
235+
/// Copies the relative path of the selected files
236+
@objc
237+
func copyRelativePath() {
238+
guard let rootPath = workspace?.workspaceFileManager?.folderUrl else {
239+
return
240+
}
241+
let paths = selectedItems().map {
242+
let destinationComponents = $0.url.standardizedFileURL.pathComponents
243+
let baseComponents = rootPath.standardizedFileURL.pathComponents
244+
245+
// Find common prefix length
246+
var prefixCount = 0
247+
while prefixCount < min(destinationComponents.count, baseComponents.count)
248+
&& destinationComponents[prefixCount] == baseComponents[prefixCount] {
249+
prefixCount += 1
250+
}
251+
// Build the relative path
252+
let upPath = String(repeating: "../", count: baseComponents.count - prefixCount)
253+
let downPath = destinationComponents[prefixCount...].joined(separator: "/")
254+
return upPath + downPath
255+
}.sorted().joined(separator: "\n")
256+
257+
NSPasteboard.general.clearContents()
258+
NSPasteboard.general.setString(paths, forType: .string)
259+
}
260+
225261
private func reloadData() {
226262
sender.outlineView.reloadData()
227263
sender.filteredContentChildren.removeAll()

CodeEdit/Features/Settings/Pages/TextEditingSettings/Models/TextEditingSettings.swift

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,25 @@ extension SettingsData {
1414
struct TextEditingSettings: Codable, Hashable, SearchableSettingsPage {
1515

1616
var searchKeys: [String] {
17-
[
17+
var keys = [
1818
"Prefer Indent Using",
1919
"Tab Width",
2020
"Wrap lines to editor width",
21+
"Editor Overscroll",
2122
"Font",
2223
"Font Size",
2324
"Font Weight",
2425
"Line Height",
2526
"Letter Spacing",
2627
"Autocomplete braces",
2728
"Enable type-over completion",
29+
"Bracket Pair Emphasis",
2830
"Bracket Pair Highlight"
2931
]
30-
.map { NSLocalizedString($0, comment: "") }
32+
if #available(macOS 14.0, *) {
33+
keys.append("System Cursor")
34+
}
35+
return keys.map { NSLocalizedString($0, comment: "") }
3136
}
3237

3338
/// An integer indicating how many spaces a `tab` will appear as visually.
@@ -49,6 +54,9 @@ extension SettingsData {
4954
/// A flag indicating whether to wrap lines to editor width
5055
var wrapLinesToEditorWidth: Bool = true
5156

57+
/// The percentage of overscroll to apply to the text view
58+
var overscroll: OverscrollOption = .medium
59+
5260
/// A multiplier for setting the line height. Defaults to `1.2`
5361
var lineHeightMultiple: Double = 1.2
5462

@@ -57,7 +65,7 @@ extension SettingsData {
5765
var letterSpacing: Double = 1.0
5866

5967
/// The behavior of bracket pair highlights.
60-
var bracketHighlight: BracketPairHighlight = BracketPairHighlight()
68+
var bracketEmphasis: BracketPairEmphasis = BracketPairEmphasis()
6169

6270
/// Use the system cursor for the source editor.
6371
var useSystemCursor: Bool = true
@@ -88,6 +96,10 @@ extension SettingsData {
8896
Bool.self,
8997
forKey: .wrapLinesToEditorWidth
9098
) ?? true
99+
self.overscroll = try container.decodeIfPresent(
100+
OverscrollOption.self,
101+
forKey: .overscroll
102+
) ?? .medium
91103
self.lineHeightMultiple = try container.decodeIfPresent(
92104
Double.self,
93105
forKey: .lineHeightMultiple
@@ -96,10 +108,10 @@ extension SettingsData {
96108
Double.self,
97109
forKey: .letterSpacing
98110
) ?? 1
99-
self.bracketHighlight = try container.decodeIfPresent(
100-
BracketPairHighlight.self,
101-
forKey: .bracketHighlight
102-
) ?? BracketPairHighlight()
111+
self.bracketEmphasis = try container.decodeIfPresent(
112+
BracketPairEmphasis.self,
113+
forKey: .bracketEmphasis
114+
) ?? BracketPairEmphasis()
103115
if #available(macOS 14, *) {
104116
self.useSystemCursor = try container.decodeIfPresent(Bool.self, forKey: .useSystemCursor) ?? true
105117
} else {
@@ -153,7 +165,7 @@ extension SettingsData {
153165
}
154166
}
155167

156-
struct BracketPairHighlight: Codable, Hashable {
168+
struct BracketPairEmphasis: Codable, Hashable {
157169
/// The type of highlight to use
158170
var highlightType: HighlightType = .flash
159171
var useCustomColor: Bool = false
@@ -167,6 +179,22 @@ extension SettingsData {
167179
case underline
168180
}
169181
}
182+
183+
enum OverscrollOption: String, Codable {
184+
case none
185+
case small
186+
case medium
187+
case large
188+
189+
var overscrollPercentage: CGFloat {
190+
switch self {
191+
case .none: return 0
192+
case .small: return 0.25
193+
case .medium: return 0.5
194+
case .large: return 0.75
195+
}
196+
}
197+
}
170198
}
171199

172200
struct EditorFont: Codable, Hashable {

0 commit comments

Comments
 (0)