diff --git a/.github/workflows/docc.yml b/.github/workflows/docc.yml new file mode 100644 index 0000000..5ddd39c --- /dev/null +++ b/.github/workflows/docc.yml @@ -0,0 +1,45 @@ +name: DocC GitHub action +on: + push: + +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Set up Swift environment + uses: swift-actions/setup-swift@v2 + + - name: Setup Git worktree + run: | + git fetch + git worktree add --checkout gh-pages origin/gh-pages + - name: Build docs with SwiftPM using DocC + run: | + swift package --allow-writing-to-directory ./gh-pages/docs \ + generate-documentation --target Chroma \ + --output-path ./gh-pages/docs \ + --disable-indexing \ + --transform-for-static-hosting \ + --include-extended-types \ + --hosting-base-path chroma-shell + + - name: Commit and push generated documentation + run: | + cd gh-pages + git add docs + git config --local user.email "github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + git commit -a -m "Updating Docs for github-pages" + git push origin HEAD:gh-pages + cd .. + git worktree remove gh-pages diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c08053c --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +# Build artifacts +/.build +# Annoying Mac File +.DS_Store +# Swift Package Manger +Package.resolved +/.swiftpm +/gh-pages/docs +# Editor files +/.vscode diff --git a/Package.swift b/Package.swift new file mode 100644 index 0000000..94343ed --- /dev/null +++ b/Package.swift @@ -0,0 +1,35 @@ +// swift-tools-version: 5.10 +import PackageDescription + +let package = Package( + name: "chroma-shell", + products: [ + .library( + name: "Chroma", + targets: ["Chroma"]) + ], + dependencies: [ + // Used for Generating documentation + /* + swift package --allow-writing-to-directory ./gh-pages/docs \ + generate-documentation --target Chroma \ + --output-path ./gh-pages/docs \ + --disable-indexing \ + --transform-for-static-hosting \ + --include-extended-types \ + --hosting-base-path chroma-shell + */ + // For Viewing docs locally + // swift package --disable-sandbox preview-documentation --target Chroma --include-extended-types + .package( + url: "https://github.com/apple/swift-docc-plugin", + from: "1.3.0") + ], + targets: [ + .target( + name: "Chroma"), + .testTarget( + name: "ChromaTests", + dependencies: ["Chroma"]), + ] +) diff --git a/README.md b/README.md new file mode 100644 index 0000000..3e48c7f --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# chroma-shell + +```swift +.package( + url: "https://github.com/zaneenders/chroma-shell.git", + revision: "main"), +``` \ No newline at end of file diff --git a/Sources/Color/Chroma.docc/Chroma.md b/Sources/Color/Chroma.docc/Chroma.md new file mode 100644 index 0000000..3816f99 --- /dev/null +++ b/Sources/Color/Chroma.docc/Chroma.md @@ -0,0 +1,5 @@ +# ``Chroma`` + +A package to add more ``Chroma`` to your Swift terminal life. + + diff --git a/Sources/Color/Color.swift b/Sources/Color/Color.swift new file mode 100644 index 0000000..1530b95 --- /dev/null +++ b/Sources/Color/Color.swift @@ -0,0 +1,106 @@ +public typealias AnsiString = String + +public enum Color { + case basic(Basic) + case bright(Basic) + case int(Int) + + public enum Basic { + case black + case red + case green + case yellow + case blue + case magenta + case cyan + case white + // case reset + } +} + +public func foreground(_ color: Color, _ str: String) -> AnsiString { + // https://www.lihaoyi.com/post/BuildyourownCommandLinewithANSIescapecodes.html + let colorString: String + switch color { + case let .basic(basic): + switch basic { + case .black: + colorString = "\u{001b}[30m" + case .red: + colorString = "\u{001b}[31m" + case .green: + colorString = "\u{001b}[32m" + case .yellow: + colorString = "\u{001b}[33m" + case .blue: + colorString = "\u{001b}[34m" + case .magenta: + colorString = "\u{001b}[35m" + case .cyan: + colorString = "\u{001b}[36m" + case .white: + colorString = "\u{001b}[37m" + } + case let .bright(bright): + switch bright { + case .black: + colorString = "\u{001b}[30;1m" + case .red: + colorString = "\u{001b}[31;1m" + case .green: + colorString = "\u{001b}[32;1m" + case .yellow: + colorString = "\u{001b}[33;1m" + case .blue: + colorString = "\u{001b}[34;1m" + case .magenta: + colorString = "\u{001b}[35;1m" + case .cyan: + colorString = "\u{001b}[36;1m" + case .white: + colorString = "\u{001b}[37;1m" + } + case let .int(i): + colorString = "\u{001b}[38;5;\(i % 256)m" + } + return colorString + str + AnsiCode.reset.rawValue +} + +/// Ansi Codes +/// This is only used as a output translation. +/// [](https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797) +//!!!: Can we turn this into a DSL +enum AnsiCode: String { + + case esc = "\u{001b}[" + case reset = "\u{001b}[0m" + case home = "\u{001b}[H" // moves cursor to home position (0, 0) + case eraseScreen = "\u{001b}[2J" + case eraseSaved = "\u{001b}[3J" + case defaultColor = "\u{001b}[1;39m" + // ESC[{line};{column}H + // ESC[{line};{column}f moves cursor to line #, column # + // ESC[J erase in display (same as ESC[0J) + // ESC[0J erase from cursor until end of screen + // ESC[1J erase from cursor to beginning of screen + // ESC[2J erase entire screen + // ESC[3J erase saved lines + // ESC[K erase in line (same as ESC[0K) + // ESC[0K erase from cursor to end of line + // ESC[1K erase start of line to the cursor + // ESC[2K erase the entire line + + enum Style: String { + case bold = "\u{001b}[1m" + case underline = "\u{001b}[4m" + case reversed = "\u{001b}[7m" + } + + static func foregroundColor(_ value: Int) -> String { + "\u{001b}[38;5;\(value)m" + } + + static func backgroundColor(_ value: Int) -> String { + "\u{001b}[48;5;\(value)m" + } +} diff --git a/Sources/Color/PreMade.swift b/Sources/Color/PreMade.swift new file mode 100644 index 0000000..334cdb8 --- /dev/null +++ b/Sources/Color/PreMade.swift @@ -0,0 +1,35 @@ +public func yellow(_ str: String) -> String { + foreground(.int(226), str) +} + +public func green(_ str: String) -> String { + foreground(.int(40), str) +} + +public func blue(_ str: String) -> String { + foreground(.int(27), str) +} + +public func pink(_ str: String) -> String { + foreground(.int(201), str) +} + +public func red(_ str: String) -> String { + foreground(.int(196), str) +} + +public func orange(_ str: String) -> String { + foreground(.int(202), str) +} + +public func purple(_ str: String) -> String { + foreground(.int(129), str) +} + +public func white(_ str: String) -> String { + foreground(.int(15), str) +} + +public func teal(_ str: String) -> String { + foreground(.int(14), str) +} diff --git a/Tests/ChromaTests/ChromaTests.swift b/Tests/ChromaTests/ChromaTests.swift new file mode 100644 index 0000000..484b658 --- /dev/null +++ b/Tests/ChromaTests/ChromaTests.swift @@ -0,0 +1,10 @@ +import Chroma +import XCTest + +final class ChromaTests: XCTestCase { + func testExample() throws { + XCTAssertEqual( + foreground(Color.basic(.blue), "Hello"), + "\u{001b}[34mHello\u{001b}[0m") + } +}