Skip to content

Commit

Permalink
Add 7 fully featured languages to CodeEditor.
Browse files Browse the repository at this point in the history
* Supports syntax highlighting, code completion, find
  and replace, text diff, validation, minimap, inline linter
  messaging, bracket matching for C, C++, JSON, Python,
  Rust, Swift, and TOML.
* TODO: Create a (.usda) tree sitter to allow for the above
  to work in a fully featured usd text editor.
  • Loading branch information
furby-tm committed Apr 15, 2024
1 parent e874610 commit bdff506
Show file tree
Hide file tree
Showing 178 changed files with 1,676,704 additions and 89 deletions.
38 changes: 1 addition & 37 deletions Package.resolved
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"originHash" : "e58edd2b86f83181d8f33bbf70fa65b018b4bfb4afa07983ce56817d548e7022",
"originHash" : "c15e8aa8884e5c43573b4c6821e6a2d2a6f33b031aae46b8d3f500da1ae16ba1",
"pins" : [
{
"identity" : "aexml",
Expand All @@ -19,33 +19,6 @@
"revision" : "2218eaa30dbdb39b063e92644fc28ed22e2cb942"
}
},
{
"identity" : "codeeditlanguages",
"kind" : "remoteSourceControl",
"location" : "https://github.com/CodeEditApp/CodeEditLanguages.git",
"state" : {
"revision" : "620b463c88894741e20d4711c9435b33547de5d2",
"version" : "0.1.18"
}
},
{
"identity" : "codeeditsourceeditor",
"kind" : "remoteSourceControl",
"location" : "https://github.com/CodeEditApp/CodeEditSourceEditor",
"state" : {
"revision" : "7360f00bf7ec8e93b4833357bd254bef7e5c943d",
"version" : "0.7.2"
}
},
{
"identity" : "codeedittextview",
"kind" : "remoteSourceControl",
"location" : "https://github.com/CodeEditApp/CodeEditTextView.git",
"state" : {
"revision" : "86b980464bcb67693e2053283c7a99bdc6f358bc",
"version" : "0.7.3"
}
},
{
"identity" : "graphviz",
"kind" : "remoteSourceControl",
Expand Down Expand Up @@ -341,15 +314,6 @@
"version" : "6.0.3"
}
},
{
"identity" : "swiftlintplugin",
"kind" : "remoteSourceControl",
"location" : "https://github.com/lukepistrol/SwiftLintPlugin",
"state" : {
"revision" : "ea6d3ca895b49910f790e98e4b4ca658e0fe490e",
"version" : "0.54.0"
}
},
{
"identity" : "swiftterm",
"kind" : "remoteSourceControl",
Expand Down
72 changes: 67 additions & 5 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ let package = Package(
],
// --- 📦 Package Products. ---
products: [
// --- 🎨 Editors ---
.library(
name: "CosmoEditor",
targets: ["CosmoTextView", "CosmoEditor"]
),
.library(
name: "CosmoLanguages",
targets: ["CosmoLanguagesContainer", "CosmoLanguages"]
),
// --- 🦑 Kraken ---
.library(
name: "KrakenKit",
targets: ["KrakenKit"]
Expand All @@ -39,13 +49,68 @@ let package = Package(
// --- 🦄 Package Dependencies. ---
dependencies: [
.package(url: "https://github.com/wabiverse/SwiftUSD.git", from: "23.11.35"),
.package(url: "https://github.com/CodeEditApp/CodeEditSourceEditor", from: "0.7.2"),
.package(url: "https://github.com/ChimeHQ/SwiftTreeSitter", from: "0.8.0"),
.package(url: "https://github.com/ChimeHQ/TextFormation", from: "0.8.2"),
.package(url: "https://github.com/ChimeHQ/TextStory.git", from: "0.8.0"),
.package(url: "https://github.com/apple/swift-collections", from: "1.1.0"),
.package(url: "https://github.com/furby-tm/swift-bundler", from: "2.0.9"),
.package(url: "https://github.com/stackotter/swift-cross-ui", revision: "f57f7ab")
],

// --- 🎯 Package Targets. ---
targets: [
// --- 🎨 Editors ---
.target(
name: "CosmoLanguagesContainer",
path: "Sources/Editors/Code/CosmoLanguagesContainer",
publicHeadersPath: "include",
cSettings: [
.headerSearchPath("TreeSitterC/include"),
.headerSearchPath("TreeSitterCPP/include"),
.headerSearchPath("TreeSitterJSON/include"),
.headerSearchPath("TreeSitterPython/include"),
.headerSearchPath("TreeSitterRust/include"),
.headerSearchPath("TreeSitterSwift/include"),
.headerSearchPath("TreeSitterTOML/include"),
// TODO: Create a (.usda) tree sitter.
]
),
.target(
name: "CosmoLanguages",
dependencies: [
.target(name: "CosmoLanguagesContainer"),
.product(name: "SwiftTreeSitter", package: "SwiftTreeSitter"),
],
path: "Sources/Editors/Code/CosmoLanguages",
resources: [
.copy("Resources"),
]
),
.testTarget(
name: "CosmoLanguagesTests",
dependencies: [
.target(name: "CosmoLanguages")
],
path: "Tests/Editors/Code/CosmoLanguagesTests"
),
.target(
name: "CosmoTextView",
dependencies: [
.product(name: "TextStory", package: "TextStory"),
.product(name: "Collections", package: "swift-collections"),
],
path: "Sources/Editors/Code/CosmoTextView"
),
.target(
name: "CosmoEditor",
dependencies: [
.target(name: "CosmoLanguages"),
.target(name: "CosmoTextView"),
.product(name: "TextFormation", package: "TextFormation"),
],
path: "Sources/Editors/Code/CosmoEditor"
),
// --- 🦑 Kraken ---
.target(
name: "KrakenKit",
dependencies: [
Expand All @@ -55,7 +120,6 @@ let package = Package(
.interoperabilityMode(.Cxx)
]
),

.target(
name: "KrakenLib",
dependencies: [
Expand All @@ -65,12 +129,11 @@ let package = Package(
.interoperabilityMode(.Cxx)
]
),

.target(
name: "KrakenUI",
dependencies: [
.target(name: "KrakenKit"),
.product(name: "CodeEditSourceEditor", package: "CodeEditSourceEditor"),
.target(name: "CosmoEditor"),
.product(
name: "SwiftCrossUI",
package: "swift-cross-ui",
Expand All @@ -87,7 +150,6 @@ let package = Package(
.interoperabilityMode(.Cxx)
]
),

.executableTarget(
name: "Kraken",
dependencies: [
Expand Down
90 changes: 90 additions & 0 deletions Sources/Editors/Code/CosmoEditor/Controller/CursorPosition.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/* --------------------------------------------------------------
* :: : K R A K E N : ::
* --------------------------------------------------------------
* @wabistudios :: metaverse :: kraken
*
* This program is free software; you can redistribute it, and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Check out
* the GNU General Public License for more details.
*
* You should have received a copy for this software license, the
* GNU General Public License along with this program; or, if not
* write to the Free Software Foundation, Inc., to the address of
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright (C) 2023 Wabi Foundation.
* All Rights Reserved.
* --------------------------------------------------------------
* . x x x . o o o . x x x . : : : . o x o . : : : .
* -------------------------------------------------------------- */

import Foundation

/// # Cursor Position
///
/// Represents the position of a cursor in a document.
/// Provides information about the range of the selection relative to the document, and the line-column information.
///
/// Can be initialized by users without knowledge of either column and line position or range in the document.
/// When initialized by users, certain values may be set to `NSNotFound` or `-1` until they can be filled in by the text
/// controller.
///
public struct CursorPosition: Sendable, Codable, Equatable
{
/// Initialize a cursor position.
///
/// When this initializer is used, ``CursorPosition/range`` will be initialized to `NSNotFound`.
/// The range value, however, be filled when updated by ``CosmoEditor`` via a `Binding`, or when it appears
/// in the``TextViewController/cursorPositions`` array.
///
/// - Parameters:
/// - line: The line of the cursor position, 1-indexed.
/// - column: The column of the cursor position, 1-indexed.
public init(line: Int, column: Int)
{
range = .notFound
self.line = line
self.column = column
}

/// Initialize a cursor position.
///
/// When this initializer is used, both ``CursorPosition/line`` and ``CursorPosition/column`` will be initialized
/// to `-1`. They will, however, be filled when updated by ``CosmoEditor`` via a `Binding`, or when it
/// appears in the ``TextViewController/cursorPositions`` array.
///
/// - Parameter range: The range of the cursor position.
public init(range: NSRange)
{
self.range = range
line = -1
column = -1
}

/// Private initializer.
/// - Parameters:
/// - range: The range of the position.
/// - line: The line of the position.
/// - column: The column of the position.
init(range: NSRange, line: Int, column: Int)
{
self.range = range
self.line = line
self.column = column
}

/// The range of the selection.
public let range: NSRange
/// The line the cursor is located at. 1-indexed.
/// If ``CursorPosition/range`` is not empty, this is the line at the beginning of the selection.
public let line: Int
/// The column the cursor is located at. 1-indexed.
/// If ``CursorPosition/range`` is not empty, this is the column at the beginning of the selection.
public let column: Int
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/* --------------------------------------------------------------
* :: : K R A K E N : ::
* --------------------------------------------------------------
* @wabistudios :: metaverse :: kraken
*
* This program is free software; you can redistribute it, and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Check out
* the GNU General Public License for more details.
*
* You should have received a copy for this software license, the
* GNU General Public License along with this program; or, if not
* write to the Free Software Foundation, Inc., to the address of
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright (C) 2023 Wabi Foundation.
* All Rights Reserved.
* --------------------------------------------------------------
* . x x x . o o o . x x x . : : : . o x o . : : : .
* -------------------------------------------------------------- */

import AppKit
import Foundation

extension TextViewController
{
/// Sets new cursor positions.
/// - Parameter positions: The positions to set. Lines and columns are 1-indexed.
public func setCursorPositions(_ positions: [CursorPosition])
{
if isPostingCursorNotification { return }
var newSelectedRanges: [NSRange] = []
for position in positions
{
let line = position.line
let column = position.column
guard (line > 0 && column > 0) || (position.range != .notFound) else { continue }

if position.range == .notFound
{
if textView.textStorage.length == 0
{
// If the file is blank, automatically place the cursor in the first index.
newSelectedRanges.append(NSRange(location: 0, length: 0))
}
else if let linePosition = textView.layoutManager.textLineForIndex(line - 1)
{
// If this is a valid line, set the new position
let index = linePosition.range.lowerBound + min(linePosition.range.upperBound, column - 1)
newSelectedRanges.append(NSRange(location: index, length: 0))
}
}
else
{
newSelectedRanges.append(position.range)
}
}
textView.selectionManager.setSelectedRanges(newSelectedRanges)
}

/// Update the ``TextViewController/cursorPositions`` variable with new text selections from the text view.
func updateCursorPosition()
{
var positions: [CursorPosition] = []
for selectedRange in textView.selectionManager.textSelections
{
guard let linePosition = textView.layoutManager.textLineForOffset(selectedRange.range.location)
else
{
continue
}
let column = (selectedRange.range.location - linePosition.range.location) + 1
let row = linePosition.index + 1
positions.append(CursorPosition(range: selectedRange.range, line: row, column: column))
}

isPostingCursorNotification = true
cursorPositions = positions.sorted(by: { $0.range.location < $1.range.location })
NotificationCenter.default.post(name: Self.cursorPositionUpdatedNotification, object: nil)
isPostingCursorNotification = false
}
}
Loading

0 comments on commit bdff506

Please sign in to comment.