Repository: o2sh/onefetch Branch: main Commit: b150632f05d4 Files: 119 Total size: 370.2 KB Directory structure: gitextract_74i3scx4/ ├── .editorconfig ├── .gitattributes ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.yml │ │ ├── feature_request.yml │ │ └── new_language.yml │ ├── dependabot.yml │ ├── release.yml │ └── workflows/ │ ├── cd.yml │ ├── ci.yml │ ├── msrv-badge.yml │ ├── web-ci.yml │ ├── wiki.yml │ └── windows-installer.iss ├── .gitignore ├── .mailmap ├── .rustfmt.toml ├── .tokeignore ├── .vscode/ │ └── settings.json ├── CHANGELOG.md ├── CONTRIBUTING.md ├── Cargo.toml ├── LICENSE.md ├── Makefile ├── README.md ├── ascii/ │ ├── Cargo.toml │ ├── README.md │ └── src/ │ └── lib.rs ├── benches/ │ └── repo.rs ├── build.rs ├── docs/ │ ├── onefetch.1 │ ├── web/ │ │ ├── .gitignore │ │ ├── .npmrc │ │ ├── .prettierignore │ │ ├── .prettierrc │ │ ├── README.md │ │ ├── eslint.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── app.css │ │ │ ├── app.d.ts │ │ │ ├── app.html │ │ │ ├── lib/ │ │ │ │ └── utils.ts │ │ │ └── routes/ │ │ │ ├── +page.svelte │ │ │ ├── +page.ts │ │ │ └── AsciiPreview.svelte │ │ ├── static/ │ │ │ └── robots.txt │ │ ├── svelte.config.js │ │ ├── tsconfig.json │ │ ├── vercel.json │ │ └── vite.config.ts │ └── wiki/ │ ├── _Footer.md │ ├── _Sidebar.md │ ├── ascii-art.md │ ├── command-line-options.md │ ├── getting-started.md │ ├── home.md │ ├── images-in-the-terminal.md │ └── installation.md ├── image/ │ ├── Cargo.toml │ ├── README.md │ └── src/ │ ├── iterm.rs │ ├── kitty.rs │ ├── lib.rs │ └── sixel.rs ├── languages.yaml ├── manifest/ │ ├── Cargo.toml │ ├── README.md │ ├── src/ │ │ └── lib.rs │ └── tests/ │ ├── cargo.rs │ ├── fixtures/ │ │ ├── cargo/ │ │ │ └── Cargo.toml │ │ └── npm/ │ │ └── package.json │ └── npm.rs ├── resources/ │ └── license.cache.zstd ├── scripts/ │ └── nf-preview.rb ├── snap/ │ └── snapcraft.yaml ├── src/ │ ├── cli.rs │ ├── info/ │ │ ├── authors.rs │ │ ├── churn.rs │ │ ├── commits.rs │ │ ├── contributors.rs │ │ ├── created.rs │ │ ├── dependencies.rs │ │ ├── description.rs │ │ ├── git/ │ │ │ ├── metrics.rs │ │ │ ├── mod.rs │ │ │ └── sig.rs │ │ ├── head.rs │ │ ├── langs/ │ │ │ ├── language.rs │ │ │ ├── language.tera │ │ │ └── mod.rs │ │ ├── last_change.rs │ │ ├── license.rs │ │ ├── loc.rs │ │ ├── mod.rs │ │ ├── pending.rs │ │ ├── project.rs │ │ ├── size.rs │ │ ├── snapshots/ │ │ │ ├── onefetch__info__authors__test__author_info_alignment_with_three_authors.snap │ │ │ ├── onefetch__info__authors__test__author_info_with_one_author.snap │ │ │ └── onefetch__info__authors__test__author_info_with_two_authors.snap │ │ ├── title.rs │ │ ├── url.rs │ │ ├── utils/ │ │ │ ├── info_field.rs │ │ │ ├── mod.rs │ │ │ └── snapshots/ │ │ │ └── onefetch__info__utils__info_field__test__write_styled.snap │ │ └── version.rs │ ├── lib.rs │ ├── main.rs │ └── ui/ │ ├── mod.rs │ ├── printer/ │ │ ├── factory.rs │ │ └── mod.rs │ └── text_colors.rs └── tests/ ├── fixtures/ │ ├── make_bare_repo.sh │ ├── make_partial_repo.sh │ ├── make_pre_epoch_repo.sh │ ├── make_repo.sh │ ├── make_repo_without_code.sh │ └── make_repo_without_remote.sh ├── repo.rs └── snapshots/ └── repo__repo.snap ================================================ FILE CONTENTS ================================================ ================================================ FILE: .editorconfig ================================================ root = true [*] indent_style = space indent_size = 4 end_of_line = LF charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true [*.{yml,yaml,md}] indent_size = 2 [{Makefile,.SRCINFO}] indent_style = tab [*.json] indent_style = space indent_size = 2 [*.rb] indent_style = space indent_size = 2 ================================================ FILE: .gitattributes ================================================ docs/web/** linguist-documentation **.snap linguist-language=Plain-Text ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.yml ================================================ name: Bug report 🐛 description: Create a bug report to help us improve labels: ["bug"] body: - type: markdown attributes: value: Thanks for contributing by creating an issue! ❤️ - type: checkboxes attributes: label: Duplicates description: | Please [search the history](https://github.com/o2sh/onefetch/issues) to see if an issue already exists for the same problem. 📌 If your issue refers to an incorrect language detection, please have a look [here](https://github.com/o2sh/onefetch/issues/26). options: - label: I have searched the existing issues required: true - type: textarea attributes: label: Current behavior 😯 description: Describe what happens instead of the expected behavior. - type: textarea attributes: label: Expected behavior 🤔 description: Describe what should happen. - type: textarea attributes: label: Steps to reproduce 🕹 description: Describe how we can reproduce this bug. placeholder: | 1. 2. 3. - type: textarea attributes: label: Additional context/Screenshots 🔦 description: Add any other context about the problem here. If applicable, add screenshots to help explain. - type: textarea attributes: label: Possible Solution 💡 description: Only if you have suggestions on a fix for the bug. ================================================ FILE: .github/ISSUE_TEMPLATE/feature_request.yml ================================================ name: Feature request 💄 description: Suggest an improvement labels: ["enhancement"] body: - type: markdown attributes: value: Thanks for contributing by creating an issue! ❤️ - type: textarea attributes: label: Summary 💡 description: Describe how it should work. - type: textarea attributes: label: Motivation 🔦 description: > What are you trying to accomplish? How has the lack of this feature affected you? ================================================ FILE: .github/ISSUE_TEMPLATE/new_language.yml ================================================ name: New Language Request 📢 description: Request for a new language to be supported labels: ["enhancement, good first issue"] body: - type: markdown attributes: value: Thanks for contributing by creating an issue! ❤️ - type: textarea attributes: label: Language Name 🖊 description: Provide the name of the language and any additional details that we should know. - type: textarea attributes: label: Logo 📷 description: Is there a logo that can be used as a source of inspiration for the ASCII art? - type: checkboxes attributes: label: Upstream support ✅ description: | Onefetch relies on [tokei](https://github.com/XAMPPRocky/tokei) for language detection. options: - label: Does tokei already support the language in question? required: true ================================================ FILE: .github/dependabot.yml ================================================ version: 2 updates: - package-ecosystem: cargo directory: "/" groups: clap: patterns: - "clap" - "clap_*" gix: patterns: - "gix" - "gix-*" schedule: interval: "weekly" open-pull-requests-limit: 10 - package-ecosystem: "github-actions" directory: "/" schedule: interval: "weekly" - package-ecosystem: npm directory: /docs/web groups: site: patterns: - "*" schedule: interval: monthly ================================================ FILE: .github/release.yml ================================================ changelog: exclude: labels: - ignore-for-release categories: - title: New Features labels: - feat - title: Bug Fixes labels: - fix - title: Chores labels: - chore - refactor - doc - title: Dependencies labels: - dependencies - title: Other Changes labels: - "*" ================================================ FILE: .github/workflows/cd.yml ================================================ name: CD on: release: types: [published] env: CARGO_TERM_COLOR: always jobs: deploy: strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - name: Checkout uses: actions/checkout@v6 - name: Setup Rust uses: actions-rust-lang/setup-rust-toolchain@v1 - name: Build Release run: make build - name: Package release for Mac if: matrix.os == 'macos-latest' run: make release-mac - name: Package release for Linux if: matrix.os == 'ubuntu-latest' run: make release-linux - name: Package release for Windows if: matrix.os == 'windows-latest' run: make release-win - name: Publish to GitHub uses: softprops/action-gh-release@v2 with: tag_name: ${{ github.event.release.tag_name }} files: | ./release/*.tar.gz ./release/*.zip ./onefetch-setup.exe env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Publish to Homebrew uses: mislav/bump-homebrew-formula-action@v3 if: matrix.os == 'macos-latest' env: COMMITTER_TOKEN: ${{ secrets.BREW_TOKEN }} with: formula-name: onefetch - name: Publish to WinGet uses: vedantmgoyal9/winget-releaser@main if: matrix.os == 'windows-latest' with: identifier: o2sh.onefetch installers-regex: '\.exe$' version: ${{ github.event.release.tag_name }} token: ${{ secrets.WINGET_TOKEN }} crates: name: Publish to crates.io runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v6 - name: Setup Rust uses: actions-rust-lang/setup-rust-toolchain@v1 - name: Publish to crates.io (ascii) env: CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} run: cargo publish -p onefetch-ascii - name: Publish to crates.io (image) env: CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} run: cargo publish -p onefetch-image - name: Publish to crates.io (manifest) env: CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} run: cargo publish -p onefetch-manifest - name: Publish to crates.io env: CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} run: cargo publish ================================================ FILE: .github/workflows/ci.yml ================================================ name: CI on: push: branches: ["*"] paths-ignore: - "docs/**" - "**.md" - "docs/web/**" pull_request: branches: [main] paths-ignore: - "docs/**" - "**.md" - "docs/web/**" env: CARGO_TERM_COLOR: always jobs: CI: strategy: matrix: os: [ubuntu-latest, windows-latest, macOS-latest] runs-on: ${{ matrix.os }} steps: - name: Checkout uses: actions/checkout@v6 - name: Setup Rust uses: actions-rust-lang/setup-rust-toolchain@v1 - name: Build run: cargo build --features=fail-on-deprecated - name: Run tests run: cargo test ================================================ FILE: .github/workflows/msrv-badge.yml ================================================ name: MSRV Badge on: schedule: # Once a week at midnight UTC - cron: "0 0 * * 0" workflow_dispatch: jobs: make-badge: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v6 with: ref: ${{ github.event.pull_request.head.ref }} token: ${{ secrets.BADGE_TOKEN }} - name: Get Minimum Supported Rust Version uses: spenserblack/actions-msrv@v0.4 id: get-msrv timeout-minutes: 60 - name: Create Badge run: curl https://img.shields.io/badge/rustc-${{ steps.get-msrv.outputs.msrv }}%2B-blue > ./assets/msrv-badge.svg - name: Commit Badge continue-on-error: true run: | git status git pull --ff-only git add ./assets/msrv-badge.svg git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" git commit -m "Update msrv badge [Skip CI]" git push ================================================ FILE: .github/workflows/web-ci.yml ================================================ name: Web UI CI on: push: branches: ["main"] paths: - "docs/web/**" pull_request: branches: [main] paths: - "docs/web/**" jobs: check: name: Check Code Quality runs-on: ubuntu-latest defaults: run: working-directory: docs/web steps: - name: Checkout uses: actions/checkout@v6 - name: Setup Node uses: actions/setup-node@v6 with: node-version: 20 cache: npm cache-dependency-path: docs/web/package-lock.json - name: Install Dependencies run: npm ci - name: Svelte Check run: npm run check:svelte -- --fail-on-warnings - name: ESLint run: npm run check:lint - name: Prettier run: npm run check:prettier ================================================ FILE: .github/workflows/wiki.yml ================================================ name: Publish Wiki on: push: branches: [main] paths: - "docs/wiki/**" workflow_dispatch: concurrency: group: wiki cancel-in-progress: true permissions: contents: write jobs: wiki: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - uses: spenserblack/actions-wiki@v0.3.0 with: path: docs/wiki ================================================ FILE: .github/workflows/windows-installer.iss ================================================ ; Script generated by the Inno Setup Script Wizard. ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! #define MyAppName "onefetch" ;#define MyAppVersion "1.0" #define MyAppPublisher "Ossama Hjaji" #define MyAppURL "https://github.com/o2sh/onefetch" #define MyAppExeName "onefetch.exe" [Setup] ; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications. ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) AppId={{BB44DE71-B34D-4707-AE9D-5FF3FA632283} AppName={#MyAppName} AppVersion={#MyAppVersion} ;AppVerName={#MyAppName} {#MyAppVersion} AppPublisher={#MyAppPublisher} AppPublisherURL={#MyAppURL} AppSupportURL={#MyAppURL} AppUpdatesURL={#MyAppURL} DefaultDirName={autopf}\{#MyAppName} DisableDirPage=yes DisableProgramGroupPage=yes ; Uncomment the following line to run in non administrative install mode (install for current user only.) ;PrivilegesRequired=lowest OutputDir=..\.. OutputBaseFilename=onefetch-setup SetupIconFile=..\..\assets\onefetch.ico UninstallDisplayIcon={app}\{#MyAppExeName} Compression=lzma SolidCompression=yes WizardStyle=modern ChangesEnvironment=true [Languages] Name: "english"; MessagesFile: "compiler:Default.isl" [Files] Source: "..\..\target\release\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion ; NOTE: Don't use "Flags: ignoreversion" on any shared system files [Icons] Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}" [Code] { https://stackoverflow.com/a/46609047/149111 } const EnvironmentKey = 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment'; procedure EnvAddPath(instlPath: string); var Paths: string; begin { Retrieve current path (use empty string if entry not exists) } if not RegQueryStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, 'Path', Paths) then Paths := ''; if Paths = '' then Paths := instlPath + ';' else begin { Skip if string already found in path } if Pos(';' + Uppercase(instlPath) + ';', ';' + Uppercase(Paths) + ';') > 0 then exit; if Pos(';' + Uppercase(instlPath) + '\;', ';' + Uppercase(Paths) + ';') > 0 then exit; { Append App Install Path to the end of the path variable } if Paths[length(Paths)] <> ';' then Paths := Paths + ';'; Paths := Paths + instlPath + ';'; end; { Overwrite (or create if missing) path environment variable } if RegWriteStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, 'Path', Paths) then Log(Format('The [%s] added to PATH: [%s]', [instlPath, Paths])) else Log(Format('Error while adding the [%s] to PATH: [%s]', [instlPath, Paths])); end; procedure EnvRemovePath(instlPath: string); var Paths: string; P, Offset, DelimLen: Integer; begin { Skip if registry entry not exists } if not RegQueryStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, 'Path', Paths) then exit; { Skip if string not found in path } DelimLen := 1; { Length(';') } P := Pos(';' + Uppercase(instlPath) + ';', ';' + Uppercase(Paths) + ';'); if P = 0 then begin { perhaps instlPath lives in Paths, but terminated by '\;' } DelimLen := 2; { Length('\;') } P := Pos(';' + Uppercase(instlPath) + '\;', ';' + Uppercase(Paths) + ';'); if P = 0 then exit; end; { Decide where to start string subset in Delete() operation. } if P = 1 then Offset := 0 else Offset := 1; { Update path variable } Delete(Paths, P - Offset, Length(instlPath) + DelimLen); { Overwrite path environment variable } if RegWriteStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, 'Path', Paths) then Log(Format('The [%s] removed from PATH: [%s]', [instlPath, Paths])) else Log(Format('Error while removing the [%s] from PATH: [%s]', [instlPath, Paths])); end; procedure CurStepChanged(CurStep: TSetupStep); begin if CurStep = ssPostInstall then EnvAddPath(ExpandConstant('{app}')); end; procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep); begin if CurUninstallStep = usPostUninstall then EnvRemovePath(ExpandConstant('{app}')); end; ================================================ FILE: .gitignore ================================================ /target **/*.rs.bk /stage /parts /prime .gitignore.swp .DS_Store result **/generated-* **/.idea ================================================ FILE: .mailmap ================================================ Ossama Hjaji Komeil Parseh Eduardo Broto ================================================ FILE: .rustfmt.toml ================================================ # See also https://rust-lang.github.io/rustfmt for more settings. edition = "2024" newline_style = "Unix" ================================================ FILE: .tokeignore ================================================ docs/web ================================================ FILE: .vscode/settings.json ================================================ { "search.exclude": { "**/node_modules": false, "**/target": true } } ================================================ FILE: CHANGELOG.md ================================================ # Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## 2.27.1 (2025-3-19) ### Bug Fixes - Fix CD pipeline by @o2sh in 497d4c011ede6acba4b3ca4c1e62f9aecaf20528 ## 2.27.0 (2025-3-19) ### New Features - add language support for Nushell by @o2sh in https://github.com/o2sh/onefetch/pull/1687 - add language support for Slint by @opmr0 in https://github.com/o2sh/onefetch/pull/1710 ### Bug Fixes - fix npm manifest parsing by @o2sh in https://github.com/o2sh/onefetch/pull/1693 - always show ascii-language when provided by CLI by @o2sh in https://github.com/o2sh/onefetch/pull/1713 - ascii_colors should match ascii-language colors when provided by CLI when no language detected bcfca6ba6f4fb05b723b64c5a2d6b315d7c74e71 ### Chores - simplify logic for commit graph traversal, reduce parallelization by @o2sh in https://github.com/o2sh/onefetch/pull/1682 ### onefetch.dev - Add Copy button with toaster to Ascii preview by @o2sh in https://github.com/o2sh/onefetch/pull/1679 ## 2.26.1 (2025-12-21) ### Bug Fixes - Fix CD pipeline by @o2sh in becddb963ce78f25f2a1f88921b34f9a61e08cc9 ## 2.26.0 (2025-12-21) ### New Features - Add colors to --help by @starsep in https://github.com/o2sh/onefetch/pull/1633 ### Chores - No unsafe by @Sk7Str1p3 in https://github.com/o2sh/onefetch/pull/1646 - bump cargo edition to 2024 by @o2sh in a3062f48db4eb2ff43cf8965f33f60b9454b4908 - increase default color resolution for sixel by @o2sh in 73300b60e38920aced8cfee376ad1051a1706f76 ### Bug Fixes - skip get_main_language call if no language detected by @o2sh in 10603ae2e6259c93595f5e5e7ff35b1d312541af ## 2.25.0 (2025-07-06) ### New Features - add language support for Text by @Kajiih in https://github.com/o2sh/onefetch/pull/1579 - support repos "without source code" by @o2sh in https://github.com/o2sh/onefetch/pull/1580 ### Chores - improve error handling by @Mahdiglm in https://github.com/o2sh/onefetch/pull/1560 ### Bug Fixes - remove extra line break by @o2sh in 886d942c510864612c1ad58a64a9c91b1193b9e9 ## 2.24.0 (2025-04-12) ### New Features - add language support for Lean by @foxyseta in https://github.com/o2sh/onefetch/pull/1509 - add language support for Typst by @foxyseta in https://github.com/o2sh/onefetch/pull/1508 - add language support for Razor by @SrS2225a in https://github.com/o2sh/onefetch/pull/1521 ### Chores - more idiomatic way to fetch HEAD refs by @o2sh in https://github.com/o2sh/onefetch/pull/1515 - more idiomatic way to fetch repository remote URL by @o2sh in https://github.com/o2sh/onefetch/pull/1516 - update holyc language logo by @o2sh in https://github.com/o2sh/onefetch/pull/1543 - update wiki powershell-snippet by @FallenDeity in https://github.com/o2sh/onefetch/pull/1542 - add nix local setup @Sk7Str1p3 in https://github.com/o2sh/onefetch/pull/1549 ## 2.23.1 (2025-01-01) ### Bug Fixes - Fix version in man page ## 2.23.0 (2025-01-01) ### New Features - add language support for OpenSCAD by @kenchou in https://github.com/o2sh/onefetch/pull/1502 - add language support for Modelica by @dietmarw in https://github.com/o2sh/onefetch/pull/1262 - add language support for ATS by @pykenny in https://github.com/o2sh/onefetch/pull/523 - add language support for CUDA by @jtmr05 in https://github.com/o2sh/onefetch/pull/940 - add missing nerd fonts icons for some languages by @ankddev in https://github.com/o2sh/onefetch/pull/1491 ### Chores - add Italian translation of README by @tlazzarin in https://github.com/o2sh/onefetch/pull/1435 - add Polish translation of README by @adamperkowski in https://github.com/o2sh/onefetch/pull/1444 - add Czech translation of READEME by @Amereyeu in https://github.com/o2sh/onefetch/pull/1439 - update russian README by @ankddev in https://github.com/o2sh/onefetch/pull/1478 - [onefetch.dev] migrate to Svelte v5 by @o2sh in https://github.com/o2sh/onefetch/pull/1455 - add script to preview/validate Nerd Fonts by @spenserblack in https://github.com/o2sh/onefetch/pull/1492 - add Powershell snippet to run onefetch automatically by @kiapanahi in https://github.com/o2sh/onefetch/pull/1453 ## 2.22.0 (2024-09-20) ### New Features - Add support for nerd font glyphs in languages info by @Localghost385 in https://github.com/o2sh/onefetch/pull/1395 - [onefetch.dev] Add nerdfont iconts to the preview by @Localghost385 in https://github.com/o2sh/onefetch/pull/1411 - Automate publishing crates to crates.io by @musicinmybrain in https://github.com/o2sh/onefetch/pull/1364 ### Bug Fixes - Show future commit dates without panicking by @MalteT in https://github.com/o2sh/onefetch/pull/1389 ### Chores - Re-generate the man page with --no-info by @musicinmybrain in https://github.com/o2sh/onefetch/pull/1376 - Drop unused shebangs from repo test fixture scripts by @musicinmybrain in https://github.com/o2sh/onefetch/pull/1375 ## 2.21.0 (2024-05-08) ### New Features - Add CLI option to force URL format to HTTP instead of SSH by @0spotter0 in https://github.com/o2sh/onefetch/pull/1314 - Add CLI flag to hide token from repository URL by @o2sh in https://github.com/o2sh/onefetch/pull/1319 - Make Lua logo more readable on dark terminal by @o2sh in https://github.com/o2sh/onefetch/pull/1337 ### Bug Fixes - Fix deadlock in Churn computation by @Nettifani in https://github.com/o2sh/onefetch/pull/1316 - Exclude bot commits from churn when `--no-bots` option is used by @o2sh in https://github.com/o2sh/onefetch/pull/1335 ### Chores - [onefetch.dev] switch to dark theme by @o2sh in https://github.com/o2sh/onefetch/pull/1297 - RUSTSEC-2024-0320: remove yaml-rust dependency by @Suyun114 in https://github.com/o2sh/onefetch/pull/1309 - Refactor `--no-bots` CLI option by @o2sh in https://github.com/o2sh/onefetch/pull/1340 ## 2.20.0 (2024-03-17) This version marks the completion of the transition from [`git2`](https://crates.io/crates/git2) to [`gitoxide`](https://crates.io/crates/gix). No more dependency to git2, onefetch is now fully oxidized! ### New Features - Add svg language support by @Localghost385 in https://github.com/o2sh/onefetch/pull/1266 - lang: Adding Oz programming language by @luxluth in https://github.com/o2sh/onefetch/pull/1280 ### Chores - website: Filter entries by language type in onefetch.dev by @o2sh in https://github.com/o2sh/onefetch/pull/1227 - Use GitHub's alert syntax by @spenserblack in https://github.com/o2sh/onefetch/pull/1234 - Add german translation of `README.md` by @rdwz in https://github.com/o2sh/onefetch/pull/1236 - Use `gitoxide` to get pending changes by @Byron in https://github.com/o2sh/onefetch/pull/1285 ## 2.19.0 (2023-11-29) ### New Features - exclude files from churn by @o2sh in https://github.com/o2sh/onefetch/pull/1120 - add odin support by @spsandwichman in https://github.com/o2sh/onefetch/pull/1064 - New language: Arduino by @Sh4rk-Byte in https://github.com/o2sh/onefetch/pull/1176 - Right align authorship percentages by @lukehsiao in https://github.com/o2sh/onefetch/pull/1207 - Add Agda to languages.yaml by @Zoltan-Balazs in https://github.com/o2sh/onefetch/pull/1216 ### Bug Fixes - add a test for negative dates and see how onefetch handles it by @Byron in https://github.com/o2sh/onefetch/pull/1100 ### Chores - Group clap dependency updates by @spenserblack in https://github.com/o2sh/onefetch/pull/1101 - Group all NPM dependency updates by @spenserblack in https://github.com/o2sh/onefetch/pull/1110 - Added Turkish Translations by @4Chaffenel in https://github.com/o2sh/onefetch/pull/1135 - use workspace inheritance by @o2sh in https://github.com/o2sh/onefetch/pull/1142 - docs(contributing): Add syntax highlighting to YAML block by @spenserblack in https://github.com/o2sh/onefetch/pull/1172 - add release.yml file by @o2sh in https://github.com/o2sh/onefetch/pull/1177 - replace action-rs by @o2sh in https://github.com/o2sh/onefetch/pull/1191 - Resolve clippy warnings by @spenserblack in https://github.com/o2sh/onefetch/pull/1201 - Refactor and test info field styling by @spenserblack in https://github.com/o2sh/onefetch/pull/1214 - Refactoring git metrics module by @o2sh in https://github.com/o2sh/onefetch/pull/1217 ### Dependencies - upgrade to `gix` 0.53.1 by @Byron in https://github.com/o2sh/onefetch/pull/1166 ## 2.18.1 (2023-06-25) ### Bug Fixes - don't fail when computing diff on partial clones (#1093) @Byron @o2sh ### Features - fetch banner info from github (#1094) @spenserblack @o2sh ## 2.18.0 (2023-06-20) ### Features - add new info line called "Churn" which displays the files with the most modifications (commits) (#1071) @o2sh @Byron - add Hlsl support (#1082) @progDes007 ### Other - add info builder pattern ### Chore - performance: optimize case where repo has a commit-graph for massive performance gains (#1081) @Byron - docs: add a cmd.exe version of the cd snippet (#1048) @mataha - refacto: use the builder pattern to instantiate the `Info` struct (#1047) @o2sh @spenserblack - improve bot regex (#1086) @o2sh @spenserblack ## 2.17.1 (2023-04-28) ### Other - Improve code coverage of src/info/mod.rs (#1011) @changhc - Improve code coverage of src/ui/mod.rs (#1012) @changhc - Added fish git repository greeter script to wiki (#1021) @TheSast - upgrade gitoxide to v0.44 (and incorporate #1023):x (#1024) @Byron @spenserblack ## 2.17.0 (2023-04-09) ### Other - Disable line wrap (#983) @o2sh - Add Pascal support (#989) @rchastain - Add Coldfusion support (#971) @theemanofsteele - Remove github token from url field (#996) @jim4067 - Changed Hashbang (#979) @gautamprikshit1 - Prevent conflicts in wiki action 39fe441 @spenserblack - Fix typos (#992) @hezhizhen - Group CLI options in sections (#995) @o2sh - replace --show-logo with --no-art (#1002) @o2sh - Set snapshot language to plain text (#1003) @spenserblack - Better error message when human_time panics (#1010) @o2sh ### New Features - remove github token from url field ## 2.16.0 (2023-02-24) ### Other - Add GLSL language support #490 (#824) @sangsatori - Fix Markdown / Jupyter markup not getting counted (#937) @spenserblack - upgrade gix to 0.36.1 to avoid breakage. (#965) @Byron - Fix path to language template (#939) @spenserblack - Create the Arabic README file (Arabic translation) (#950) @anas-elgarhy - Refactoring of info/langs/mod.rs (#948) @o2sh - Remove country flags #928 @o2sh - Upgrade git-repository 0.30 to gix 0.36 (#963) @Byron ## 2.15.1 (2023-01-19) ### Other - Fix CD Github action @o2sh ## 2.15.0 (2023-01-19) ### Other - Add --number-separator CLI flag #892 @o2sh - Add Makefile language support #867 @ozwaldorf - Vercel: add section links #922 @ozwaldorf - Add gitpod.io configuration #881 @spenserblack - Use human_panic #887 @o2sh - Read license from manifest first #769 @o2sh - Install cargo-insta in dev containers #909 @spenserblack - Info struct to holds a Vec #911 @o2sh - Add benchmark #912 @o2sh - GH action to synchronize wiki with .github/wiki #926 @spenserblack @o2sh - Clean up greeter and fix repository detection mechanism in wiki #927 @quazar-omega - Turn AsciiArt.rs into its own crate #934 @o2sh - Use ISO time for snapshot tests #908 @spenserblack - Parse multi-byte unicode chars correctly + docs #936 @ozwaldorf ## 2.14.2 (2022-11-27) ### Other - Include assets in crate a2f508a @o2sh - Fix clap deps for onefetch-image crate 8cca7af - Add description field to onefetch-image and onefetch-manifest crate 2888186 @o2sh ## 2.14.1 (2022-11-27) ### Other - Fix CD 5085c5b @o2sh ## 2.14.0 (2022-11-27) ### Other - Add description info line #851 @o2sh - Add CLI flag to set the maximum number of languages to be shown 8159b34 @o2sh - Add VisualBasic language support #867 @antonizyla - Add manifest crate #851 @o2sh @spenserblack - Move image_backends into its own crate 9ce17c1 @o2sh - Add devcontainer/codespace config #857 @spenserblack - Switch to Swatinem/rust-cache for caching 7592eb2 @o2sh - Add README translation for Korean #869 @abiriadev - add icon to windows exe 584574f @o2sh - Fix typo in help message for -e (--exclude) #861 @skogseth ## 2.13.2 (2022-10-30) ### Other - [fix] Repo without remote should not fail #841 @o2sh - [chore] Add integration tests with snapshot testing for Info struct #827 @atluft - [chore] Refactor test expressions #831 @saguywalker ## 2.13.1 (2022-10-22) ### Other - [ci/cd] fix Snapcraft release - [misc] fix Cargo.lock ## 2.13.0 (2022-10-21) `onefetch` is now typically more than twice as fast when executing. This was achieved by reducing allocations and switching to `gitoxide` for the most taxing tasks. A new web interface [onefetch.dev](https://onefetch.dev) was developed where users can visualize an ASCII preview for all the programming languages currently supported by onefetch. Like the binary, the data is parsed from the `Languages.yaml` file. ### Other - [chore] reducing allocations and switching to gitoxide from libgit2 #635 @Byron - [docs] add README translation for Spanish #631 @JakeRoggenbuck @practicatto - [docs] add Changelog generated using cargo-smart-release #637 @Byron - [cli] add --completion option #657 @spenserblack - [language] update PHP colors #664 @DenverCoder1 - [misc] switch to actions/stale #666 @spenserblack @o2sh - [misc] add github issue forms #667 @spenserblack @o2sh - [ci/cd] generate Windows installer from CD #668 @o2sh - [ci/cd] create WinGet workflow for auto publishing #673 @russellbanks - [language] update logo: shell #677 @fux0c1ety - [docs] adding french documentation support #693 @Kaderovski - [chore] extract language definitions into data file #699 @spenserblack - [ci/cd] add codecov + tarpaulin in ci @o2sh - [misc] create Vercel app for onefetch with ASCII preview #701 @spenserblack - [docs] update the README in Russian #736 @AndreyKozhev - [chore] turn InfoField into a trait (big refactoring) #755 @o2sh - [language] Improve JSX ASCII logo #784 @alessandroasm - [language] Improve TSX ASCII logo #785 @alessandroasm - [language] added support for verilog #789 @atluft - [language] improve ruby logo #786 @atluft - [language] added support for xsl #798 @atluft - [language] added support for systemverilog #797 @atluft - [test] add unit tests to src/info/info_field.rs #810 @alessandroasm - [ci/cd] automate publish to crates.io #800 @spenserblack - [language] added support for ABNF #811 @atluft - [test] add unit tests src/info/repo/commits.rs #813 @alessandroasm - [test] add unit tests src/info/repo/contributors.rs #814 @alessandroasm - [language] added support for ABAP #821@atluft - [test] testing get_git_username using git-testtools for #812 @atluft - [language] improve bash logo @o2sh - [language] improve assembly logo @o2sh - [test] add unit tests for author.rs #829 @gallottino @Oniryu95 ### Fixes - Commits replaced with `git replace` are now followed. This can be turned off by setting the `GIT_NO_REPLACE_OBJECTS` environment variable. - Shallow clones are now detected and displayed as such. Previously it might have appeared that the commit count is the real even though it was truncated due to the shallow-ness of the repository. If a repository is shallow, `(shallow)` will appear after the commit count. ### Refactor - git2 repository can now be owned by the `Repo` type Previously this wasn't possible as commits would be kept in `Repo` which would cause self-referential borrow check issues unless the git2 repository was kept outside. - completely separate `Commits` and `Repo` structure - put all commit-traversal related initialization into own struct ================================================ FILE: CONTRIBUTING.md ================================================ ### Getting started Follow the instructions for [installing onefetch from source](https://github.com/o2sh/onefetch/wiki/Installation#build-from-source). ### Adding support for a new language Adding support for a new Language consists in adding a new entry to [language.yaml](./languages.yaml) and filling it in with the right data. **Example**: ```yaml CSharp: # required, this will be the name of the enum variant for the language as specified by tokei (link 1) type: programming # required, can be programming, data, markup, or prose as specified by linguist (link 2) # required, this is the logo. If it's not within 25x40 bounds, you will get a compiler error. Use `{i}` to color the ascii with `i` the color index. ascii: | {0} ++++++ {0} ++++++++++++ {0} ++++++++++++++++++++ {0} ++++++++++++++++++++++++++ {0} ++++++++++++++++++++++++++++++++ {0} +++++++++++++{3}************{0}+++++++++++++ {0}+++++++++++{3}******************{0}++++++++{2};;; {0}+++++++++{3}**********************{0}++{2};;;;;;; {0}++++++++{3}*********{0}++++++{3}******{2};;;;;;;;;;; {0}+++++++{3}********{0}++++++++++{3}**{2};;;{3}**{2};;;{3}**{2};;; {0}+++++++{3}*******{0}+++++++++{2};;;;;;{3}*********{2}:: {0}+++++++{3}******{0}+++++++{2};;;;;;;;;;{3}**{2};;;{3}**{2};;; {0}+++++++{3}*******{0}+++{1}:::::{2};;;;;;;{3}*********{2};; {0}+++++++{3}********{1}::::::::::{3}**{2};;;{3}**{2};;;{3}**{2};;; {0}++++++++{3}*********{1}::::::{3}******{2};;;;;;;;;;; {0}++++++{1}:::{3}**********************{1}::{2};;;;;;; {0}+++{1}::::::::{3}******************{1}::::::::{2};;; {1} :::::::::::::{3}************{1}::::::::::::: {1} :::::::::::::::::::::::::::::::: {1} :::::::::::::::::::::::::: {1} :::::::::::::::::::: {1} :::::::::::: {1} :::::: colors: ansi: # required, a list of the ANSI colors used to colorize the logo - blue - magenta - magenta - white hex: # optional, alternative to basic colors for terminals that support true colour. - "#9B4F97" - "#67217A" - "#803788" - "#FFFFFF" chip: "#178600" # required, this is used for the language breakdown bar, its value can be found in linguist (link 2). icon: '\u{E648}' # optional, the UTF-16 code point of the nerd font icon if supported (link 3). serialization: c# # required only if the Enum name `CSharp` doesn't match the display name `C#` ``` - link 1: https://github.com/XAMPPRocky/tokei#supported-languages - link 2: https://github.com/github/linguist/blob/master/lib/linguist/languages.yml - link 3: https://www.nerdfonts.com/cheat-sheet

Special Thanks to

- Every onefetch user, who contributed to the project by writing issues or PRs. - [@spenserblack](https://github.com/spenserblack) and [@Byron](https://github.com/Byron) for maintaining this project. - Everyone I forgot to mention here, but also influenced onefetch and helped it grow.

:heart::heart:

Made with [contributors-img](https://contrib.rocks). ================================================ FILE: Cargo.toml ================================================ [workspace.package] authors = ["o2sh "] edition = "2024" license = "MIT" version = "2.27.1" repository = "https://github.com/o2sh/onefetch" [workspace] members = ["ascii", "image", "manifest"] [package] authors.workspace = true edition.workspace = true version.workspace = true license.workspace = true repository.workspace = true categories = ["command-line-utilities"] description = "Command-line Git information tool" exclude = ["docs/web/*"] keywords = ["git", "cli", "terminal"] name = "onefetch" homepage = "https://onefetch.dev" rust-version = "1.88.0" [dependencies] anyhow = "1.0.101" askalono = "0.5.0" byte-unit = "5.2.0" clap = { version = "4.5.57", features = ["derive"] } clap_complete = "4.5.65" gix = { version = "0.80.0", default-features = false, features = [ "max-performance-safe", "blob-diff", "mailmap", "index", "status", ] } gix-features = "0.46.0" globset = "0.4.18" human-panic = "2.0.6" image = { version = "0.25.10", default-features = false, features = [ "color_quant", "jpeg", "png", "webp", ] } num-format = "0.4.4" onefetch-ascii = { path = "ascii", version = "2.27.1" } onefetch-image = { path = "image", version = "2.27.1" } onefetch-manifest = { path = "manifest", version = "2.27.1" } owo-colors = "4.3.0" regex = "1.12.2" serde = "1.0.228" serde_json = "1.0.149" serde_yaml = "0.9.34" strum = { version = "0.28.0", features = ["derive"] } time = { version = "0.3.47", features = ["formatting"] } time-humanize = { version = "0.1.3", features = ["time"] } tokei = "14.0.0" typetag = "0.2.21" [dev-dependencies] criterion = "0.8.2" gix-testtools = "0.18.0" insta = { version = "1.46.3", features = ["json", "redactions"] } rstest = "0.26.1" [[bench]] name = "repo" harness = false [build-dependencies] lazy_static = "1.5.0" regex = "1.12.2" serde_json = "1.0.149" serde_yaml = "0.9.34" tera = { version = "1.20.1", default-features = false } [target.'cfg(windows)'.build-dependencies] winres = "0.1.12" [target.'cfg(windows)'.dependencies] enable-ansi-support = "0.3.1" [features] fail-on-deprecated = [] ================================================ FILE: LICENSE.md ================================================ MIT License Copyright (c) 2018 Ossama Hjaji Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: Makefile ================================================ install: cargo install --path "." --features=fail-on-deprecated build: cargo build --release --features=fail-on-deprecated uninstall: cargo uninstall onefetch clean: cargo clean release-mac: strip target/release/onefetch mkdir -p release tar -C ./target/release/ -czvf ./release/onefetch-mac.tar.gz ./onefetch release-win: TAG_NAME = $$(git describe --abbrev=0 --tags) release-win: mkdir -p release tar -C ./target/release/ -czvf ./release/onefetch-win.tar.gz ./onefetch.exe iscc.exe -DMyAppVersion=${TAG_NAME} ./.github/workflows/windows-installer.iss release-linux: strip target/release/onefetch mkdir -p release tar -C ./target/release/ -czvf ./release/onefetch-linux.tar.gz ./onefetch ================================================ FILE: README.md ================================================
# Onefetch - Command-line Git information tool

Onefetch logo

[![Crates.io Version](https://img.shields.io/crates/v/onefetch)](https://crates.io/crates/onefetch) [![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/o2sh/onefetch/ci.yml)](https://github.com/o2sh/onefetch/actions/workflows/ci.yml) [![help wanted](https://img.shields.io/github/issues/o2sh/onefetch/help%20wanted?color=green)](https://github.com/o2sh/onefetch/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) ![MSRV](assets/msrv-badge.svg)

Homepage | Installation | Documentation

--- Onefetch is a command-line Git information tool that displays project information and code statistics for a local Git repository directly in your terminal. The tool works completely offline with a focus on performance and customizability. ||| |---|---| | ![Screenshot 1](assets/screenshot-1.png) | ![Screenshot 2](assets/screenshot-2.png) | ## Installation Onefetch is available on Linux, macOS, and Windows platforms. Binaries for Linux, Windows, and macOS are available on the [release page](https://github.com/o2sh/onefetch/releases). ### Linux - Ubuntu ``` wget https://github.com/o2sh/onefetch/releases/latest/download/onefetch_amd64.deb && sudo dpkg -i ./onefetch_amd64.deb && rm onefetch_amd64.deb ``` - Arch Linux ``` pacman -S onefetch ``` - openSUSE ``` zypper install onefetch ``` ### macOS ``` brew install onefetch ``` ### Windows ``` winget install onefetch ``` ## Usage ``` onefetch /path/of/your/repo ``` Or ``` cd /path/of/your/repo onefetch ``` ## Customization Onefetch can be customized via [command-line arguments](https://github.com/o2sh/onefetch/wiki/command-line-options) to display exactly what you want, the way you want it: adjust the text styling, disable info lines, ignore files and directories, output in multiple formats (JSON, YAML), etc. ## Contributing Currently, onefetch supports more than [100 different programming languages](https://onefetch.dev); if your language of choice isn't supported, open an issue and support will be added. Contributions are very welcome! See [CONTRIBUTING](CONTRIBUTING.md) for more info. ================================================ FILE: ascii/Cargo.toml ================================================ [package] authors.workspace = true edition.workspace = true version.workspace = true license.workspace = true repository.workspace = true name = "onefetch-ascii" description = "Display colorized ascii art to the terminal" [dependencies] owo-colors = "4.3.0" ================================================ FILE: ascii/README.md ================================================ # ascii [![crates.io](https://img.shields.io/crates/v/onefetch-ascii)](https://crates.io/crates/onefetch-ascii) [![docs.rs](https://img.shields.io/docsrs/onefetch-ascii)](https://docs.rs/onefetch-ascii) Provides the primary interface to display ascii art to the terminal. More info [here](https://github.com/o2sh/onefetch/wiki/ascii-art). _This crate is designed as part of the [onefetch](https://github.com/o2sh/onefetch) project._ ================================================ FILE: ascii/src/lib.rs ================================================ //! # onefetch-ascii //! //! Provides the ascii template interface for [onefetch](https://github.com/o2sh/onefetch). //! //! ```rust,no_run //! use onefetch_ascii::AsciiArt; //! use owo_colors::{DynColors, AnsiColors}; //! //! const ASCII: &str = r#" //! {2} .:--::////::--.` //! {1} `/yNMMNho{2}////////////:. //! {1} `+NMMMMMMMMmy{2}/////////////:` //! {0} `-:::{1}ohNMMMMMMMNy{2}/////////////:` //! {0} .::::::::{1}odMMMMMMMNy{2}/////////////- //! {0} -:::::::::::{1}/hMMMMMMMmo{2}////////////- //! {0} .::::::::::::::{1}oMMMMMMMMh{2}////////////- //! {0}`:::::::::::::{1}/dMMMMMMMMMMNo{2}///////////` //! {0}-::::::::::::{1}sMMMMMMmMMMMMMMy{2}//////////- //! {0}-::::::::::{1}/dMMMMMMs{0}:{1}+NMMMMMMd{2}/////////: //! {0}-:::::::::{1}+NMMMMMm/{0}:::{1}/dMMMMMMm+{2}///////: //! {0}-::::::::{1}sMMMMMMh{0}:::::::{1}dMMMMMMm+{2}//////- //! {0}`:::::::{1}sMMMMMMy{0}:::::::::{1}dMMMMMMm+{2}/////` //! {0} .:::::{1}sMMMMMMs{0}:::::::::::{1}mMMMMMMd{2}////- //! {0} -:::{1}sMMMMMMy{0}::::::::::::{1}/NMMMMMMh{2}//- //! {0} .:{1}+MMMMMMd{0}::::::::::::::{1}oMMMMMMMo{2}- //! {1} `yMMMMMN/{0}:::::::::::::::{1}hMMMMMh. //! {1} -yMMMo{0}::::::::::::::::{1}/MMMy- //! {1} `/s{0}::::::::::::::::::{1}o/` //! {0} ``.---::::---..` //! "#; //! //! let colors = vec![ //! DynColors::Ansi(AnsiColors::Blue), //! DynColors::Ansi(AnsiColors::Default), //! DynColors::Ansi(AnsiColors::BrightBlue) //! ]; //! //! let art = AsciiArt::new(ASCII, colors.as_slice(), true); //! //! for line in art { //! println!("{line}") //! } //! ``` //! use owo_colors::{AnsiColors, DynColors, OwoColorize, Style}; use std::fmt::Write; /// Renders an ascii template with the given colors truncated to the correct width. pub struct AsciiArt<'a> { content: Box>, colors: &'a [DynColors], bold: bool, start: usize, end: usize, } impl<'a> AsciiArt<'a> { pub fn new(input: &'a str, colors: &'a [DynColors], bold: bool) -> AsciiArt<'a> { let mut lines: Vec<_> = input.lines().skip_while(|line| line.is_empty()).collect(); while let Some(line) = lines.last() { if Tokens(line).is_empty() { lines.pop(); } else { break; } } let (start, end) = get_min_start_max_end(&lines); AsciiArt { content: Box::new(lines.into_iter()), colors, bold, start, end, } } pub fn width(&self) -> usize { assert!(self.end >= self.start); self.end - self.start } } fn get_min_start_max_end(lines: &[&str]) -> (usize, usize) { lines .iter() .map(|line| { let line_start = Tokens(line).leading_spaces(); let line_end = Tokens(line).true_length(); (line_start, line_end) }) .fold((usize::MAX, 0), |(acc_s, acc_e), (line_s, line_e)| { (acc_s.min(line_s), acc_e.max(line_e)) }) } /// Produces a series of lines which have been automatically truncated to the /// correct width impl Iterator for AsciiArt<'_> { type Item = String; fn next(&mut self) -> Option { self.content .next() .map(|line| Tokens(line).render(self.colors, self.start, self.end, self.bold)) } } #[derive(Clone, Debug, PartialEq, Eq)] enum Token { Color(u32), Char(char), Space, } impl std::fmt::Display for Token { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match *self { Token::Color(c) => write!(f, "{{{c}}}"), Token::Char(c) => write!(f, "{c}"), Token::Space => write!(f, " "), } } } impl Token { fn is_solid(&self) -> bool { matches!(*self, Token::Char(_)) } fn is_space(&self) -> bool { matches!(*self, Token::Space) } fn has_zero_width(&self) -> bool { matches!(*self, Token::Color(_)) } } /// An iterator over tokens found within the *.ascii format. #[derive(Clone, Debug)] struct Tokens<'a>(&'a str); impl Iterator for Tokens<'_> { type Item = Token; fn next(&mut self) -> Option { let (s, tok) = color_token(self.0) .or_else(|| space_token(self.0)) .or_else(|| char_token(self.0))?; self.0 = s; Some(tok) } } impl<'a> Tokens<'a> { fn is_empty(&mut self) -> bool { for token in self { if token.is_solid() { return false; } } true } fn true_length(&mut self) -> usize { let mut last_non_space = 0; let mut last = 0; for token in self { if token.has_zero_width() { continue; } last += 1; if !token.is_space() { last_non_space = last; } } last_non_space } fn leading_spaces(&mut self) -> usize { self.take_while(|token| !token.is_solid()) .filter(Token::is_space) .count() } fn truncate(self, mut start: usize, end: usize) -> impl 'a + Iterator { assert!(start <= end); let mut width = end - start; self.filter(move |token| { if start > 0 && !token.has_zero_width() { start -= 1; return false; } true }) .take_while(move |token| { if width == 0 { return false; } if !token.has_zero_width() { width -= 1; } true }) } /// render a truncated line of tokens. fn render(self, colors: &[DynColors], start: usize, end: usize, bold: bool) -> String { assert!(start <= end); let mut width = end - start; let mut colored_segment = String::new(); let mut whole_string = String::new(); let mut color = &DynColors::Ansi(AnsiColors::Default); self.truncate(start, end).for_each(|token| match token { Token::Char(chr) => { width = width.saturating_sub(1); colored_segment.push(chr); } Token::Color(col) => { add_styled_segment(&mut whole_string, &colored_segment, *color, bold); colored_segment = String::new(); color = colors .get(col as usize) .unwrap_or(&DynColors::Ansi(AnsiColors::Default)); } Token::Space => { width = width.saturating_sub(1); colored_segment.push(' '); } }); add_styled_segment(&mut whole_string, &colored_segment, *color, bold); (0..width).for_each(|_| whole_string.push(' ')); whole_string } } // Utility functions fn succeed_when(predicate: impl FnOnce(I) -> bool) -> impl FnOnce(I) -> Option<()> { |input| { if predicate(input) { Some(()) } else { None } } } fn add_styled_segment(base: &mut String, segment: &str, color: DynColors, bold: bool) { let mut style = Style::new().color(color); if bold { style = style.bold(); } let formatted_segment = segment.style(style); let _ = write!(base, "{formatted_segment}"); } // Basic combinators type ParseResult<'a, R> = Option<(&'a str, R)>; fn token<'a, R>(s: &'a str, predicate: impl FnOnce(char) -> Option) -> ParseResult<'a, R> { let mut chars = s.chars(); let token = chars.next()?; let result = predicate(token)?; Some((chars.as_str(), result)) } // Parsers /// Parses a color indicator of the format `{n}` where `n` is a digit. fn color_token<'a>(s: &'a str) -> ParseResult<'a, Token> { let (s, ()) = token(s, succeed_when(|c| c == '{'))?; let (s, color_index) = token(s, |c| c.to_digit(10))?; let (s, ()) = token(s, succeed_when(|c| c == '}'))?; Some((s, Token::Color(color_index))) } /// Parses a space. fn space_token<'a>(s: &'a str) -> ParseResult<'a, Token> { token(s, succeed_when(|c| c == ' ')).map(|(s, ())| (s, Token::Space)) } /// Parses any arbitrary character. This cannot fail. fn char_token<'a>(s: &'a str) -> ParseResult<'a, Token> { token(s, |c| Some(Token::Char(c))) } #[cfg(test)] mod test { use super::*; #[test] fn test_get_min_start_max_end() { let lines = [ " xxx", " xxx", " oo", " o", " xx", ]; assert_eq!(get_min_start_max_end(&lines), (3, 29)); } #[test] fn space_parses() { assert_eq!(space_token(" "), Some(("", Token::Space))); assert_eq!(space_token(" hello"), Some(("hello", Token::Space))); assert_eq!(space_token(" "), Some((" ", Token::Space))); assert_eq!(space_token(" {1}{2}"), Some(("{1}{2}", Token::Space))); } #[test] fn color_indicator_parses() { assert_eq!(color_token("{1}"), Some(("", Token::Color(1)))); assert_eq!(color_token("{9} "), Some((" ", Token::Color(9)))); } #[test] fn leading_spaces_counts_correctly() { assert_eq!(Tokens("").leading_spaces(), 0); assert_eq!(Tokens(" ").leading_spaces(), 5); assert_eq!(Tokens(" a;lksjf;a").leading_spaces(), 5); assert_eq!(Tokens(" {1} {5} {9} a").leading_spaces(), 6); } #[test] fn render() { let colors_shim = Vec::new(); assert_eq!( Tokens("").render(&colors_shim, 0, 0, true), "\u{1b}[39;1m\u{1b}[0m" ); assert_eq!( Tokens(" ").render(&colors_shim, 0, 0, true), "\u{1b}[39;1m\u{1b}[0m" ); assert_eq!( Tokens(" ").render(&colors_shim, 0, 5, true), "\u{1b}[39;1m \u{1b}[0m" ); assert_eq!( Tokens(" ").render(&colors_shim, 1, 5, true), "\u{1b}[39;1m \u{1b}[0m" ); assert_eq!( Tokens(" ").render(&colors_shim, 3, 5, true), "\u{1b}[39;1m \u{1b}[0m" ); assert_eq!( Tokens(" ").render(&colors_shim, 0, 4, true), "\u{1b}[39;1m \u{1b}[0m" ); assert_eq!( Tokens(" ").render(&colors_shim, 0, 3, true), "\u{1b}[39;1m \u{1b}[0m" ); // https://github.com/o2sh/onefetch/issues/935 assert_eq!( Tokens("███").render(Vec::new().as_slice(), 0, 3, true), "\u{1b}[39;1m███\u{1b}[0m" ); assert_eq!( Tokens(" {1} {5} {9} a").render(&colors_shim, 4, 10, true), "\u{1b}[39;1m\u{1b}[0m\u{1b}[39;1m\u{1b}[0m\u{1b}[39;1m \u{1b}[0m\u{1b}[39;1m a\u{1b}[0m " ); // Tests for bold disabled assert_eq!( Tokens(" ").render(&colors_shim, 0, 0, false), "\u{1b}[39m\u{1b}[0m" ); assert_eq!( Tokens(" ").render(&colors_shim, 0, 5, false), "\u{1b}[39m \u{1b}[0m" ); } #[test] fn truncate() { assert_eq!( Tokens("").truncate(0, 0).collect::>(), Tokens("").collect::>() ); assert_eq!( Tokens(" ").truncate(0, 0).collect::>(), Tokens("").collect::>() ); assert_eq!( Tokens(" ").truncate(0, 5).collect::>(), Tokens(" ").collect::>() ); assert_eq!( Tokens(" ").truncate(1, 5).collect::>(), Tokens(" ").collect::>() ); assert_eq!( Tokens(" ").truncate(3, 5).collect::>(), Tokens(" ").collect::>() ); assert_eq!( Tokens(" ").truncate(0, 4).collect::>(), Tokens(" ").collect::>() ); assert_eq!( Tokens(" ").truncate(0, 3).collect::>(), Tokens(" ").collect::>() ); assert_eq!( Tokens(" {1} {5} {9} a") .truncate(4, 10) .collect::>(), Tokens("{1}{5} {9} a").collect::>() ); } } ================================================ FILE: benches/repo.rs ================================================ use criterion::{Criterion, criterion_group, criterion_main}; use gix::{ThreadSafeRepository, open}; use onefetch::{cli::CliOptions, info::build_info}; use std::hint::black_box; fn bench_repo_info(c: &mut Criterion) { let name = "make_repo.sh".to_string(); let repo_path = gix_testtools::scripted_fixture_read_only(name).unwrap(); let repo = ThreadSafeRepository::open_opts(repo_path, open::Options::isolated()).unwrap(); let config: CliOptions = CliOptions { input: repo.path().to_path_buf(), ..Default::default() }; c.bench_function("get repo information", |b| { b.iter(|| { let result = black_box(build_info(&config)); assert!(result.is_ok()); }); }); } criterion_group!(benches, bench_repo_info); criterion_main!(benches); ================================================ FILE: build.rs ================================================ use regex::Regex; use std::collections::HashMap; use std::env; use std::error::Error; use std::fs::{self, File}; use std::path::Path; use std::sync::LazyLock; use tera::{Context, Tera}; fn main() -> Result<(), Box> { #[cfg(windows)] { let mut res = winres::WindowsResource::new(); res.set_icon("assets/onefetch.ico"); res.compile()?; } let out_dir = env::var("OUT_DIR").expect("No OUT_DIR variable."); let mut tera = Tera::default(); tera.register_filter("strip_color_tokens", strip_color_tokens_filter); tera.register_filter("hex_to_rgb", hex_to_rgb_filter); let lang_data: serde_json::Value = serde_yaml::from_reader(File::open("languages.yaml")?)?; let output_path = Path::new(&out_dir).join("language.rs"); let rust_code = tera.render_str( &std::fs::read_to_string("src/info/langs/language.tera")?, &Context::from_value(serde_json::json!({ "languages": lang_data, }))?, )?; fs::write(output_path, rust_code)?; Ok(()) } /// Strips out `{n}` from the given string. fn strip_color_tokens_filter( value: &tera::Value, _args: &HashMap, ) -> tera::Result { static COLOR_INDEX_REGEX: LazyLock = LazyLock::new(|| Regex::new(r"\{\d+\}").unwrap()); let tera::Value::String(s) = value else { return Err(tera::Error::msg("expected string")); }; Ok(tera::Value::String( COLOR_INDEX_REGEX.replace_all(s, "").to_string(), )) } fn hex_to_rgb_filter( value: &tera::Value, _args: &HashMap, ) -> tera::Result { let tera::Value::String(hex_string) = value else { return Err(tera::Error::msg("expected string")); }; let Some(hex_string) = hex_string.strip_prefix('#') else { return Err(tera::Error::msg("expected hex string starting with `#`")); }; if hex_string.len() != 6 { return Err(tera::Error::msg("expected a 6 digit hex string")); } let Ok(channel_bytes) = u32::from_str_radix(hex_string, 16) else { return Err(tera::Error::msg("expected a valid hex string")); }; let r = (channel_bytes >> 16) & 0xFF; let g = (channel_bytes >> 8) & 0xFF; let b = channel_bytes & 0xFF; Ok(serde_json::json!({ "r": r, "g": g, "b": b, })) } ================================================ FILE: docs/onefetch.1 ================================================ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. .TH ONEFETCH "1" "March 2026" "onefetch 2.27.1" "User Commands" .SH NAME onefetch \- Command-line Git information tool .SH SYNOPSIS .B onefetch [\fI\,OPTIONS\/\fR] [\fI\,INPUT\/\fR] .SH DESCRIPTION Command\-line Git information tool .SS "Arguments:" .IP [INPUT] .IP Run as if onefetch was started in instead of the current working directory .SH OPTIONS .HP \fB\-h\fR, \fB\-\-help\fR .IP Print help (see a summary with '\-h') .HP \fB\-V\fR, \fB\-\-version\fR .IP Print version .SS "INFO:" .HP \fB\-d\fR, \fB\-\-disabled\-fields\fR ... .IP Allows you to disable FIELD(s) from appearing in the output .HP \fB\-\-no\-title\fR .IP Hides the title .HP \fB\-\-number\-of\-authors\fR .IP Maximum NUM of authors to be shown .IP [default: 3] .HP \fB\-\-number\-of\-languages\fR .IP Maximum NUM of languages to be shown .IP [default: 6] .HP \fB\-\-number\-of\-file\-churns\fR .IP Maximum NUM of file churns to be shown .IP [default: 3] .HP \fB\-\-churn\-pool\-size\fR .IP Minimum NUM of commits from HEAD used to compute the churn summary .IP By default, the actual value is non\-deterministic due to time\-based computation and will be displayed under the info title "Churn (NUM)" .HP \fB\-e\fR, \fB\-\-exclude\fR ... .IP Ignore all files & directories matching EXCLUDE .HP \fB\-\-no\-bots[=\fR] .IP Exclude [bot] commits. Use to override the default pattern .HP \fB\-\-no\-merges\fR .IP Ignores merge commits .HP \fB\-E\fR, \fB\-\-email\fR .IP Show the email address of each author .HP \fB\-\-http\-url\fR .IP Display repository URL as HTTP .HP \fB\-\-hide\-token\fR .IP Hide token in repository URL .HP \fB\-\-include\-hidden\fR .IP Count hidden files and directories .HP \fB\-T\fR, \fB\-\-type\fR ... .IP Filters output by language type .IP [default: programming markup] [possible values: programming, markup, prose, data] .SS "TEXT FORMATTING:" .HP \fB\-t\fR, \fB\-\-text\-colors\fR ... .IP Changes the text colors (X X X...) .IP Goes in order of title, ~, underline, subtitle, colon, and info .IP For example: .IP \&'\-\-text\-colors 9 10 11 12 13 14' .HP \fB\-z\fR, \fB\-\-iso\-time\fR .IP Use ISO 8601 formatted timestamps .HP \fB\-\-number\-separator\fR .IP Which thousands SEPARATOR to use .IP [default: plain] [possible values: plain, comma, space, underscore] .HP \fB\-\-no\-bold\fR .IP Turns off bold formatting .SS "ASCII:" .HP \fB\-\-ascii\-input\fR .IP Takes a non\-empty STRING as input to replace the ASCII logo .IP It is possible to pass a generated STRING by command substitution .IP For example: .IP \&'\-\-ascii\-input "$(fortune | cowsay \fB\-W\fR 25)"' .HP \fB\-c\fR, \fB\-\-ascii\-colors\fR ... .IP Colors (X X X...) to print the ascii art .HP \fB\-a\fR, \fB\-\-ascii\-language\fR .IP Which LANGUAGE's ascii art to print .HP \fB\-\-true\-color\fR .IP Specify when to use true color .IP If set to auto: true color will be enabled if supported by the terminal .IP [default: auto] [possible values: auto, never, always] .SS "IMAGE:" .HP \fB\-i\fR, \fB\-\-image\fR .IP Path to the IMAGE file .HP \fB\-\-image\-protocol\fR .IP Which image PROTOCOL to use .IP [possible values: kitty, sixel, iterm] .HP \fB\-\-color\-resolution\fR .IP VALUE of color resolution to use with SIXEL backend .IP [default: 64] [possible values: 16, 32, 64, 128, 256] .SS "VISUALS:" .HP \fB\-\-no\-color\-palette\fR .IP Hides the color palette .HP \fB\-\-no\-art\fR .IP Hides the ascii art or image if provided .HP \fB\-\-nerd\-fonts\fR .IP Use Nerd Font icons .IP Replaces language chips with Nerd Font icons .SS "DEVELOPER:" .HP \fB\-o\fR, \fB\-\-output\fR .IP Outputs Onefetch in a specific format .IP [possible values: json, yaml] .HP \fB\-\-generate\fR .IP If provided, outputs the completion file for given SHELL .IP [possible values: bash, elvish, fish, powershell, zsh] .SS "OTHER:" .HP \fB\-l\fR, \fB\-\-languages\fR .IP Prints out supported languages .HP \fB\-p\fR, \fB\-\-package\-managers\fR .IP Prints out supported package managers ================================================ FILE: docs/web/.gitignore ================================================ node_modules # Output .output .vercel /.svelte-kit /build # OS .DS_Store Thumbs.db # Env .env .env.* !.env.example !.env.test # Vite vite.config.js.timestamp-* vite.config.ts.timestamp-* ================================================ FILE: docs/web/.npmrc ================================================ engine-strict=true ================================================ FILE: docs/web/.prettierignore ================================================ # Package Managers package-lock.json pnpm-lock.yaml yarn.lock ================================================ FILE: docs/web/.prettierrc ================================================ { "useTabs": false, "tabWidth": 2, "semi": true, "singleQuote": true, "trailingComma": "none", "bracketSameLine": true, "singleAttributePerLine": false, "quoteProps": "consistent", "plugins": ["prettier-plugin-svelte"], "overrides": [ { "files": "*.svelte", "options": { "parser": "svelte" } } ] } ================================================ FILE: docs/web/README.md ================================================ # Onefetch Web ## Development ```bash # setup ## install dependencies npm i # run server with hot reloading npm start ``` ================================================ FILE: docs/web/eslint.config.js ================================================ import prettier from 'eslint-config-prettier'; import svelte from 'eslint-plugin-svelte'; import globals from 'globals'; import ts from 'typescript-eslint'; export default ts.config( ...ts.configs.recommended, ...svelte.configs['flat/recommended'], prettier, ...svelte.configs['flat/prettier'], { languageOptions: { globals: { ...globals.browser, ...globals.node } } }, { files: ['**/*.svelte'], languageOptions: { parserOptions: { parser: ts.parser } } }, { ignores: ['build/', '.svelte-kit/', 'dist/'] } ); ================================================ FILE: docs/web/package.json ================================================ { "name": "onefetch-web", "version": "0.0.1", "type": "module", "scripts": { "start": "vite", "prebuild": "svelte-kit sync", "build": "vite build", "format": "prettier -w .", "preview": "vite preview", "check": "npm run check:svelte && npm run check:prettier && npm run check:lint", "check:svelte": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:prettier": "prettier --check **/*.{ts,js,svelte,css,html,json}", "check:lint": "eslint" }, "devDependencies": { "@rollup/plugin-yaml": "^4.1.2", "@sveltejs/adapter-auto": "^7.0.1", "@sveltejs/kit": "^2.55.0", "@sveltejs/vite-plugin-svelte": "^7.0.0", "@types/eslint": "^9.6.0", "eslint": "^10.0.3", "eslint-config-prettier": "^10.1.8", "eslint-plugin-svelte": "^3.15.2", "globals": "^17.4.0", "prettier": "^3.8.1", "prettier-plugin-svelte": "^3.5.1", "svelte": "^5.53.12", "svelte-check": "^4.4.5", "typescript": "^5.9.3", "typescript-eslint": "^8.57.1", "vite": "^8.0.0" }, "dependencies": { "svelte-hot-french-toast": "^4.0.0" } } ================================================ FILE: docs/web/src/app.css ================================================ /* $color-text: #dedce5; */ /* Sakura.css v1.5.1 * ================ * Minimal css theme. * Project: https://github.com/oxalorg/sakura/ */ /* Body */ html { font-size: 62.5%; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif; } body { font-size: 1.8rem; line-height: 1.618; max-width: 38em; margin: auto; color: #c9c9c9; background-color: #222222; padding: 30px 13px 13px; } @media (max-width: 684px) { body { font-size: 1.53rem; } } @media (max-width: 382px) { body { font-size: 1.35rem; } } h1, h2, h3, h4, h5, h6 { line-height: 1.1; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif; font-weight: 700; margin-top: 3rem; margin-bottom: 1.5rem; overflow-wrap: break-word; word-wrap: break-word; -ms-word-break: break-all; word-break: break-word; } h1 { font-size: 2.35em; } h2 { font-size: 2em; } h3 { font-size: 1.75em; } h4 { font-size: 1.5em; } h5 { font-size: 1.25em; } h6 { font-size: 1em; } p { margin-top: 0px; margin-bottom: 2.5rem; } small, sub, sup { font-size: 75%; } hr { border-color: #ffffff; } a { text-decoration: none; color: #ffffff; } a:visited { color: #e6e6e6; } a:hover { color: #c9c9c9; border-bottom: 2px solid #c9c9c9; } ul { padding-left: 1.4em; margin-top: 0px; margin-bottom: 2.5rem; } li { margin-bottom: 0.4em; } blockquote { margin-left: 0px; margin-right: 0px; padding-left: 1em; padding-top: 0.8em; padding-bottom: 0.8em; padding-right: 0.8em; border-left: 5px solid #ffffff; margin-bottom: 2.5rem; background-color: #4a4a4a; } blockquote p { margin-bottom: 0; } img, video { height: auto; max-width: 100%; margin-top: 0px; margin-bottom: 2.5rem; } /* Pre and Code */ pre { background-color: #4a4a4a; display: block; padding: 1em; overflow-x: auto; margin-top: 0px; margin-bottom: 2.5rem; font-size: 0.9em; } code, kbd, samp { font-size: 0.9em; padding: 0 0.5em; background-color: #4a4a4a; white-space: pre-wrap; } pre > code { padding: 0; background-color: transparent; white-space: pre; font-size: 1em; } /* Tables */ table { text-align: justify; width: 100%; border-collapse: collapse; margin-bottom: 2rem; } td, th { padding: 0.5em; border-bottom: 1px solid #4a4a4a; } /* Buttons, forms and input */ input, textarea { border: 1px solid #c9c9c9; } input:focus, textarea:focus { border: 1px solid #ffffff; } textarea { width: 100%; } .button, button, input[type='submit'], input[type='reset'], input[type='button'], input[type='file']::file-selector-button { display: inline-block; padding: 5px 10px; text-align: center; text-decoration: none; white-space: nowrap; background-color: #ffffff; color: #222222; border-radius: 1px; border: 1px solid #ffffff; cursor: pointer; box-sizing: border-box; } .button:hover, button:hover, input[type='submit']:hover, input[type='reset']:hover, input[type='button']:hover, input[type='file']::file-selector-button:hover { background-color: #c9c9c9; color: #222222; outline: 0; } .button[disabled], button[disabled], input[type='submit'][disabled], input[type='reset'][disabled], input[type='button'][disabled], input[type='file'][disabled] { cursor: default; opacity: 0.5; } .button:focus-visible, button:focus-visible, input[type='submit']:focus-visible, input[type='reset']:focus-visible, input[type='button']:focus-visible, input[type='file']:focus-visible { outline-style: solid; outline-width: 2px; } textarea, select, input { color: #c9c9c9; padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */ margin-bottom: 10px; background-color: #4a4a4a; border: 1px solid #4a4a4a; border-radius: 4px; box-shadow: none; box-sizing: border-box; } textarea:focus, select:focus, input:focus { border: 1px solid #ffffff; outline: 0; } input[type='checkbox']:focus { outline: 1px dotted #ffffff; } label, legend, fieldset { display: block; margin-bottom: 0.5rem; font-weight: 600; } ================================================ FILE: docs/web/src/app.d.ts ================================================ declare module '*/languages.yaml' { export interface LanguageColors { ansi: string[]; hex?: string[]; chip: string; } export interface Language { name: string; type: string; ascii: string; colors: LanguageColors; icon: string; } export type Languages = Record; export type Language = Language; } ================================================ FILE: docs/web/src/app.html ================================================ %sveltekit.head%
%sveltekit.body%
================================================ FILE: docs/web/src/lib/utils.ts ================================================ export function mapToDefaultTerminalFgColor( color: string, dark: boolean ): string { return color === 'white' && !dark ? 'black' : color; } ================================================ FILE: docs/web/src/routes/+page.svelte ================================================
{#if tagName && htmlUrl} {/if}

Onefetch

github | wiki | built with ❤ by @spenserblack and @o2sh

This page displays an ASCII preview for all the programming languages supported by onefetch. Like the binary, the data is sourced from the Languages.yaml file, and the layout aims to replicate how the logo would appear inside a terminal.

Suggestions and PRs are welcome at github.com/o2sh/onefetch

Languages ({$filteredLanguages.length})

{#each languageTypes as type (type)} {/each}
Note: By default, onefetch will only recognize programming and markup types. Use the --type flag to configure.
{#each $filteredLanguages as language (language.name)} {/each}
================================================ FILE: docs/web/src/routes/+page.ts ================================================ // since there's no dynamic data here, we can prerender // it so that it gets served as a static asset in production export const prerender = true; ================================================ FILE: docs/web/src/routes/AsciiPreview.svelte ================================================

{chipIcon}

{name}

{@html html}
================================================ FILE: docs/web/static/robots.txt ================================================ # https://www.robotstxt.org/robotstxt.html User-agent: * Disallow: ================================================ FILE: docs/web/svelte.config.js ================================================ import adapter from '@sveltejs/adapter-auto'; import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; /** @type {import('@sveltejs/kit').Config} */ const config = { // Consult https://svelte.dev/docs/kit/integrations // for more information about preprocessors preprocess: vitePreprocess(), kit: { // adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list. // If your environment is not supported, or you settled on a specific environment, switch out the adapter. // See https://svelte.dev/docs/kit/adapters for more information about adapters. adapter: adapter() } }; export default config; ================================================ FILE: docs/web/tsconfig.json ================================================ { "extends": "./.svelte-kit/tsconfig.json", "compilerOptions": { "allowJs": true, "checkJs": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "resolveJsonModule": true, "skipLibCheck": true, "sourceMap": true, "strict": true, "moduleResolution": "bundler" } // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files // // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes // from the referenced tsconfig.json - TypeScript does not merge them in } ================================================ FILE: docs/web/vercel.json ================================================ { "github": { "silent": true } } ================================================ FILE: docs/web/vite.config.ts ================================================ import { sveltekit } from '@sveltejs/kit/vite'; import { defineConfig } from 'vite'; import yaml from '@rollup/plugin-yaml'; export default defineConfig({ plugins: [sveltekit(), yaml()], server: { fs: { // Allow serving files from one level up to the project root allow: ['..'] } } }); ================================================ FILE: docs/wiki/_Footer.md ================================================ - 📰 [Wiki Home](https://github.com/o2sh/onefetch/wiki) - 🛖 [Project Home](https://github.com/o2sh/onefetch) ================================================ FILE: docs/wiki/_Sidebar.md ================================================ - **[Home](https://github.com/o2sh/onefetch/wiki)** - **General** - [Installation](https://github.com/o2sh/onefetch/wiki/installation) - [Getting started](https://github.com/o2sh/onefetch/wiki/getting-started) - **Options** - [Command-line options](https://github.com/o2sh/onefetch/wiki/command-line-options) - **Images** - [Images in the terminal](https://github.com/o2sh/onefetch/wiki/images-in-the-terminal) - **Ascii** - [Ascii art](https://github.com/o2sh/onefetch/wiki/ascii-art) ================================================ FILE: docs/wiki/ascii-art.md ================================================ This is the format onefetch uses for its ASCII art files. #### Here's an example: ``` {2} .:--::////::--.` {1} `/yNMMNho{2}////////////:. {1} `+NMMMMMMMMmy{2}/////////////:` {0} `-:::{1}ohNMMMMMMMNy{2}/////////////:` {0} .::::::::{1}odMMMMMMMNy{2}/////////////- {0} -:::::::::::{1}/hMMMMMMMmo{2}////////////- {0} .::::::::::::::{1}oMMMMMMMMh{2}////////////- {0}`:::::::::::::{1}/dMMMMMMMMMMNo{2}///////////` {0}-::::::::::::{1}sMMMMMMmMMMMMMMy{2}//////////- {0}-::::::::::{1}/dMMMMMMs{0}:{1}+NMMMMMMd{2}/////////: {0}-:::::::::{1}+NMMMMMm/{0}:::{1}/dMMMMMMm+{2}///////: {0}-::::::::{1}sMMMMMMh{0}:::::::{1}dMMMMMMm+{2}//////- {0}`:::::::{1}sMMMMMMy{0}:::::::::{1}dMMMMMMm+{2}/////` {0} .:::::{1}sMMMMMMs{0}:::::::::::{1}mMMMMMMd{2}////- {0} -:::{1}sMMMMMMy{0}::::::::::::{1}/NMMMMMMh{2}//- {0} .:{1}+MMMMMMd{0}::::::::::::::{1}oMMMMMMMo{2}- {1} `yMMMMMN/{0}:::::::::::::::{1}hMMMMMh. {1} -yMMMo{0}::::::::::::::::{1}/MMMy- {1} `/s{0}::::::::::::::::::{1}o/` {0} ``.---::::---..` ``` #### Features: - You can use `{0}` to `{X}`to color the ascii, with X > 0. - You can pass the flag `-c, --ascii-colors 2 5 ...` to set your own colors. - Look at the color palette to know the color order ![](https://i.imgur.com/NFT4WL4.png) ================================================ FILE: docs/wiki/command-line-options.md ================================================ ```man Usage: onefetch.exe [OPTIONS] [INPUT] Arguments: [INPUT] Run as if onefetch was started in instead of the current working directory Options: -h, --help Print help (see a summary with '-h') -V, --version Print version INFO: -d, --disabled-fields ... Allows you to disable FIELD(s) from appearing in the output --no-title Hides the title --number-of-authors Maximum NUM of authors to be shown [default: 3] --number-of-languages Maximum NUM of languages to be shown [default: 6] --number-of-file-churns Maximum NUM of file churns to be shown [default: 3] --churn-pool-size Minimum NUM of commits from HEAD used to compute the churn summary By default, the actual value is non-deterministic due to time-based computation and will be displayed under the info title "Churn (NUM)" -e, --exclude ... Ignore all files & directories matching EXCLUDE --no-bots[=] Exclude [bot] commits. Use to override the default pattern --no-merges Ignores merge commits -E, --email Show the email address of each author --http-url Display repository URL as HTTP --hide-token Hide token in repository URL --include-hidden Count hidden files and directories -T, --type ... Filters output by language type [default: programming markup] [possible values: programming, markup, prose, data] TEXT FORMATTING: -t, --text-colors ... Changes the text colors (X X X...) Goes in order of title, ~, underline, subtitle, colon, and info For example: '--text-colors 9 10 11 12 13 14' -z, --iso-time Use ISO 8601 formatted timestamps --number-separator Which thousands SEPARATOR to use [default: plain] [possible values: plain, comma, space, underscore] --no-bold Turns off bold formatting ASCII: --ascii-input Takes a non-empty STRING as input to replace the ASCII logo It is possible to pass a generated STRING by command substitution For example: '--ascii-input "$(fortune | cowsay -W 25)"' -c, --ascii-colors ... Colors (X X X...) to print the ascii art -a, --ascii-language Which LANGUAGE's ascii art to print --true-color Specify when to use true color If set to auto: true color will be enabled if supported by the terminal [default: auto] [possible values: auto, never, always] IMAGE: -i, --image Path to the IMAGE file --image-protocol Which image PROTOCOL to use [possible values: kitty, sixel, iterm] --color-resolution VALUE of color resolution to use with SIXEL backend [default: 16] [possible values: 16, 32, 64, 128, 256] VISUALS: --no-color-palette Hides the color palette --no-art Hides the ascii art or image if provided --nerd-fonts Use Nerd Font icons Replaces language chips with Nerd Font icons DEVELOPER: -o, --output Outputs Onefetch in a specific format [possible values: json, yaml] --generate If provided, outputs the completion file for given SHELL [possible values: bash, elvish, fish, powershell, zsh] OTHER: -l, --languages Prints out supported languages -p, --package-managers Prints out supported package managers ``` ================================================ FILE: docs/wiki/getting-started.md ================================================ Onefetch is installed, then what? ### Usage ```sh > onefetch /path/of/your/repo ``` Or ```sh > cd /path/of/your/repo > onefetch ``` ### Misc By [**@spenserblack**](https://github.com/spenserblack) ```sh # Runs `onefetch -a Assembly`, `onefetch -a C`, etc. onefetch -l | tr "[:upper:] " "[:lower:]-" | while read line; do echo "$line"; onefetch -a $line; done; ``` ### Automatic repo detection and running If you want to automate the detection and running of `onefetch` every time you `cd` into a repository you can leverage one of the methods below: #### 1. Bash / Zsh By [**@quazar-omega**](https://github.com/quazar-omega) A script to put in your `.bashrc` - or `.zshrc` - to run onefetch whenever you open a shell into a repository or `cd` into a repository, making sure that it's different from the last one you were in: ```sh # git repository greeter last_repository= check_directory_for_new_repository() { current_repository=$(git rev-parse --show-toplevel 2> /dev/null) if [ "$current_repository" ] && \ [ "$current_repository" != "$last_repository" ]; then onefetch fi last_repository=$current_repository } cd() { builtin cd "$@" check_directory_for_new_repository } # optional, greet also when opening shell directly in repository directory # adds time to startup check_directory_for_new_repository ``` #### 2. Fish By [**@TheSast**](https://github.com/TheSast) A fish adaptation of the previous script, run it once in your shell to save it: ```fish function cd -w='cd' builtin cd $argv || return check_directory_for_new_repository end function check_directory_for_new_repository set current_repository (git rev-parse --show-toplevel 2> /dev/null) if [ "$current_repository" ] && \ [ "$current_repository" != "$last_repository" ] onefetch end set -gx last_repository $current_repository end funcsave cd funcsave check_directory_for_new_repository ``` #### 3. CMD By [**@mataha**](https://github.com/mataha) An adaptation of the above snippet suited for Windows's `cmd.exe`, specifically for inclusion in AutoRun scripts or DOSKEY macrofiles: ```bat @set LAST_REPOSITORY= @doskey cd = ( ^ for %%^^^^ in ("") do @for /f "delims=" %%i in (^^""$*%%~^^"^") do @( ^ if "%%~i"=="" ( ^ if defined USERPROFILE ( ^ if /i not "%%CD%%"=="%%USERPROFILE%%" ( ^ chdir /d "%%USERPROFILE%%" ^&^& set "OLDPWD=%%CD%%" ^ ) ^ ) else (call) ^ ) else if "%%~i"=="-" ( ^ if defined OLDPWD ( ^ if /i not "%%CD%%"=="%%OLDPWD%%" ( ^ chdir /d "%%OLDPWD%%" ^&^& set "OLDPWD=%%CD%%" ^ ) ^ ) else (call) ^ ) else ( ^ if defined CD ( ^ if /i not "%%CD%%"=="%%~fi" ( ^ chdir /d %%~fi ^&^& set "OLDPWD=%%CD%%" ^ ) ^ ) else (call) ^ ) ^ ) ^ ) ^&^& for /f "delims=" %%r in ('git rev-parse --show-toplevel 2^^^>nul') do @( ^ if not "%%~r"=="%%LAST_REPOSITORY%%" ( ^ onefetch ^ ) ^& set "LAST_REPOSITORY=%%~r" ^ ) ``` #### 4. Powershell By [**@kiapanahi**](https://github.com/kiapanahi) An adaptation of the above snippet suited for `Powershell`. Put this script in the `$PROFILE`. ```pwsh # git repository greeter # Set the console output encoding to UTF-8, so that special characters are displayed correctly when piping to Write-Host [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 $global:lastRepository = $null function Check-DirectoryForNewRepository { $currentRepository = git rev-parse --show-toplevel 2>$null if ($currentRepository -and ($currentRepository -ne $global:lastRepository)) { onefetch | Write-Host } $global:lastRepository = $currentRepository } function Set-Location { Microsoft.PowerShell.Management\Set-Location @args Check-DirectoryForNewRepository } # Optional: Check the repository also when opening a shell directly in a repository directory # Uncomment the following line if desired #Check-DirectoryForNewRepository ``` ### Git alias By [**@mbrehin**](https://github.com/mbrehin) You can also add git alias to run onefetch during your git workflows ```sh # Add Git alias for onefetch. git config --global alias.project-summary '!which onefetch && onefetch' ``` ================================================ FILE: docs/wiki/home.md ================================================ Welcome to the onefetch's wiki! - **[Home](https://github.com/o2sh/onefetch/wiki)** - **General** - [Installation](https://github.com/o2sh/onefetch/wiki/installation) - [Getting started](https://github.com/o2sh/onefetch/wiki/getting-started) - **Options** - [Command-line options](https://github.com/o2sh/onefetch/wiki/command-line-options) - **Images** - [Images in the terminal](https://github.com/o2sh/onefetch/wiki/images-in-the-terminal) - **Ascii** - [Ascii art](https://github.com/o2sh/onefetch/wiki/ascii-art) ================================================ FILE: docs/wiki/images-in-the-terminal.md ================================================ Onefetch supports displaying images using [`kitty`](https://sw.kovidgoyal.net/kitty/graphics-protocol.html), [`Sixel`](https://en.wikipedia.org/wiki/Sixel) and [`iTerm`](https://www.iterm2.com/documentation-images.html) protocols.

When running `onefetch --image ./My-picture.jpg`, the program looks for the first `Image Protocol` supported by the terminal and use it to display the requested image instead of the Ascii logo. If you decide to go manual, and want to force the use of a specific image protocol: `onefetch --image ./My-picture.jpg --image-protocol sixel|kitty|iterm` ### Sixel The Sixel protocol is handled by multiple terminal emulators such as iterm2, [`xterm`](https://invisible-island.net/xterm/) (enabled via flag `-ti 340`), [`mlterm`](https://wiki.ubuntu.com/Mlterm) and [`WezTerm`](https://github.com/wez/wezterm) which are actively maintained. You can increase the color resolution using the `--color-resolution` flag. ### Kitty The kitty terminal graphics protocol used on the terminal of the same name allows the program running in the terminal, to render graphics to the screen of the terminal emulator. ### ITerm The iTerm inline image protocol supported by iTerm2 (also WezTerm) allows to display images within the terminal. ================================================ FILE: docs/wiki/installation.md ================================================ This wiki page will guide you through getting onefetch working on your system. [![Packaging status](https://repology.org/badge/vertical-allrepos/onefetch.svg)](https://repology.org/project/onefetch/versions) # Table of Contents - [Universal Install](#universal-install) - [Build from source](#build-from-source) - [Cargo](#cargo) - [OS/Distro Packages](#osdistro-packages) - [Alpine Linux](#alpine-linux) - [Arch](#arch) - [Fedora](#fedora) - [FreeBSD](#freebsd) - [Funtoo](#funtoo) - [macOS](#macos) - [Homebrew](#homebrew) - [MacPorts](#macports) - [NetBSD](#netbsd) - [NixOS](#nixos) - [openSUSE](#openSUSE-Leap-or-Tumbleweed) - [Ubuntu](#ubuntu) - [Void Linux](#void-linux) - [Windows](#windows) - [Winget](#Winget) - [Scoop](#scoop) - [Chocolatey](#chocolatey) # Universal Install If your architecture is supported by the pre-built binaries, you can download them from the [releases page](https://github.com/o2sh/onefetch/releases/latest). ## Build from source First, install rust toolchain with [rustup](https://rustup.rs/): ```shell curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh ``` > [!IMPORTANT] > Ensure [CMake](https://cmake.org/download/) is installed. ``` git clone https://github.com/o2sh/onefetch cd onefetch make install ``` ## Cargo First, install rust toolchain with [rustup](https://rustup.rs/): ```shell curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh ``` > [!IMPORTANT] > Ensure [CMake](https://cmake.org/download/) is installed. ``` cargo install onefetch ``` This method will build the binary from source. To update, run ``` cargo install onefetch --force ``` # OS/Distro Packages ## Alpine Linux 1. Update repositories - `apk update` 2. Install the package - `apk add onefetch` ## Arch Onefetch is available in the official repos. - Install the package - `pacman -S onefetch` ## Fedora Install it from the COPR ``` sudo dnf copr enable varlad/onefetch sudo dnf install onefetch ``` ## FreeBSD Install it from the official repositories - `pkg install onefetch` ## Funtoo Funtoo has an autogenerated onefetch package in the official kits: - `emerge app-misc/onefetch` ## MacOS ### HomeBrew Install `onefetch` with Homebrew ``` brew install onefetch ``` To update, run ``` brew upgrade onefetch ``` ### MacPorts Install `onefetch` with MacPorts ``` sudo port selfupdate sudo port install onefetch ``` To update run, ``` sudo port upgrade onefetch ``` ## NetBSD Install it from the official repositories. - `pkg_add onefetch` ## NixOS Install it from the official repositories - `nix-env -i onefetch` ## openSUSE Leap or Tumbleweed Install it from the official repositories. - `zypper install onefetch` ## Ubuntu Use debian package from release ``` wget https://github.com/o2sh/onefetch/releases/latest/download/onefetch_amd64.deb && sudo dpkg -i ./onefetch_amd64.deb ``` Use Snap ``` snap install onefetch ``` or ``` sudo add-apt-repository ppa:o2sh/onefetch sudo apt-get update sudo apt-get install onefetch ``` ## Void Linux Install it from the official repositories - `sudo xbps-install -S onefetch` ## Windows ### Winget You can install onefetch using [winget](https://docs.microsoft.com/en-us/windows/package-manager/winget/) ``` winget install onefetch ``` ### Scoop For [Scoop](https://scoop.sh/) users, onefetch is available from the "Extras" bucket ``` scoop bucket add extras scoop install onefetch ``` ### Chocolatey If you prefer to use [Chocolatey](https://chocolatey.org/) to manage software, it can be installed like so ``` choco install onefetch ``` ================================================ FILE: image/Cargo.toml ================================================ [package] authors.workspace = true edition.workspace = true version.workspace = true license.workspace = true repository.workspace = true name = "onefetch-image" description = "Display images in the terminal" [dependencies] anyhow = "1.0.101" clap = { version = "4.5.57", features = ["derive"] } image = { version = "0.25.10", default-features = false, features = [ "color_quant", "jpeg", "png", "webp", ] } [target.'cfg(not(windows))'.dependencies] color_quant = "1.1.0" base64 = "0.22.1" rustix = { version = "1.1.4", features = ["termios", "event"] } ================================================ FILE: image/README.md ================================================ # image [![crates.io](https://img.shields.io/crates/v/onefetch-image)](https://crates.io/crates/onefetch-image) [![docs.rs](https://img.shields.io/docsrs/onefetch-image)](https://docs.rs/onefetch-image) Provides the primary interface to display images to the terminal. Protocols supported: - Sixel - Kitty - Iterm _This crate is designed as part of the [onefetch](https://github.com/o2sh/onefetch) project._ ================================================ FILE: image/src/iterm.rs ================================================ use anyhow::Result; use base64::{Engine, engine}; use image::{DynamicImage, imageops::FilterType}; use rustix::termios::tcgetwinsize; use std::env; use std::io::Cursor; pub struct ITermBackend; impl ITermBackend { pub fn supported() -> bool { let term_program = env::var("TERM_PROGRAM").unwrap_or_else(|_| "".to_string()); term_program == "iTerm.app" } } impl super::ImageBackend for ITermBackend { fn add_image( &self, lines: Vec, image: &DynamicImage, _colors: usize, ) -> Result { let tty_size = tcgetwinsize(std::io::stdin())?; let width_ratio = f64::from(tty_size.ws_col) / f64::from(tty_size.ws_xpixel); let height_ratio = f64::from(tty_size.ws_row) / f64::from(tty_size.ws_ypixel); // resize image to fit the text height with the Lanczos3 algorithm let image = image.resize( u32::MAX, (lines.len() as f64 / height_ratio) as u32, FilterType::Lanczos3, ); let _image_columns = width_ratio * f64::from(image.width()); let image_rows = height_ratio * f64::from(image.height()); let mut bytes: Vec = Vec::new(); image.write_to(&mut Cursor::new(&mut bytes), image::ImageFormat::Png)?; let encoded_image = engine::general_purpose::STANDARD.encode(bytes); let mut image_data = Vec::::new(); image_data.extend(b"\x1B]1337;File=inline=1:"); image_data.extend(encoded_image.bytes()); image_data.extend(b"\x07"); image_data.extend(format!("\x1B[{}A", image_rows as u32 - 1).as_bytes()); // move cursor to start of image let mut i = 0; for line in &lines { image_data.extend(format!("\x1B[s{line}\x1B[u\x1B[1B").as_bytes()); i += 1; } image_data .extend(format!("\n\x1B[{}B", lines.len().max(image_rows as usize) - i).as_bytes()); // move cursor to end of image Ok(String::from_utf8(image_data)?) } } ================================================ FILE: image/src/kitty.rs ================================================ use anyhow::{Context as _, Result}; use base64::{Engine, engine}; use image::{DynamicImage, imageops::FilterType}; use rustix::event::{PollFd, PollFlags, Timespec, poll}; use rustix::io::read; use rustix::termios::{LocalModes, OptionalActions, tcgetattr, tcgetwinsize, tcsetattr}; use std::io::{Write, stdout}; use std::os::fd::AsFd as _; use std::time::Instant; pub struct KittyBackend; impl KittyBackend { pub fn supported() -> Result { let stdin = std::io::stdin(); // save terminal attributes and disable canonical input processing mode let old_attributes = { let old = tcgetattr(&stdin).context("Failed to recieve terminal attibutes")?; let mut new = old.clone(); new.local_modes &= !LocalModes::ICANON; new.local_modes &= !LocalModes::ECHO; tcsetattr(&stdin, OptionalActions::Now, &new) .context("Failed to update terminal attributes")?; old }; // generate red rgba test image let mut test_image = Vec::::with_capacity(32 * 32 * 4); test_image.extend(std::iter::repeat_n([255, 0, 0, 255].iter(), 32 * 32).flatten()); // print the test image with the action set to query print!( "\x1B_Gi=1,f=32,s=32,v=32,a=q;{}\x1B\\", engine::general_purpose::STANDARD.encode(&test_image) ); stdout().flush()?; let start_time = Instant::now(); let stdin_fd = stdin.as_fd(); let mut stdin_pollfd = [PollFd::new(&stdin_fd, PollFlags::IN)]; let allowed_bytes = [0x1B, b'_', b'G', b'\\']; let mut buf = Vec::::new(); loop { // check for timeout while polling to avoid blocking the main thread while poll(&mut stdin_pollfd, Some(&Timespec::default()))? < 1 { if start_time.elapsed().as_millis() > 50 { tcsetattr(&stdin, OptionalActions::Now, &old_attributes) .context("Failed to update terminal attributes")?; return Ok(false); } } let mut byte = [0]; read(&stdin, &mut byte)?; if allowed_bytes.contains(&byte[0]) { buf.push(byte[0]); } if buf.starts_with(&[0x1B, b'_', b'G']) && buf.ends_with(&[0x1B, b'\\']) { tcsetattr(&stdin, OptionalActions::Now, &old_attributes) .context("Failed to update terminal attributes")?; return Ok(true); } } } } impl super::ImageBackend for KittyBackend { fn add_image( &self, lines: Vec, image: &DynamicImage, _colors: usize, ) -> Result { let tty_size = tcgetwinsize(std::io::stdin())?; let width_ratio = f64::from(tty_size.ws_col) / f64::from(tty_size.ws_xpixel); let height_ratio = f64::from(tty_size.ws_row) / f64::from(tty_size.ws_ypixel); // resize image to fit the text height with the Lanczos3 algorithm let image = image.resize( u32::MAX, (lines.len() as f64 / height_ratio) as u32, FilterType::Lanczos3, ); let _image_columns = width_ratio * f64::from(image.width()); let image_rows = height_ratio * f64::from(image.height()); // convert the image to rgba samples let rgba_image = image.to_rgba8(); let flat_samples = rgba_image.as_flat_samples(); let raw_image = flat_samples .image_slice() .expect("Conversion from image to rgba samples failed"); assert_eq!( image.width() as usize * image.height() as usize * 4, raw_image.len() ); let encoded_image = engine::general_purpose::STANDARD.encode(raw_image); // image data is base64 encoded let mut image_data = Vec::::new(); for chunk in encoded_image.as_bytes().chunks(4096) { // send a 4096 byte chunk of base64 encoded rgba image data image_data.extend( format!( "\x1B_Gf=32,s={},v={},m=1,a=T;", image.width(), image.height() ) .as_bytes(), ); image_data.extend(chunk); image_data.extend(b"\x1B\\"); } image_data.extend(b"\x1B_Gm=0;\x1B\\"); // write empty last chunk image_data.extend(format!("\x1B[{}A", image_rows as u32 - 1).as_bytes()); // move cursor to start of image let mut i = 0; for line in &lines { image_data.extend(format!("\x1B[s{line}\x1B[u\x1B[1B").as_bytes()); i += 1; } image_data .extend(format!("\n\x1B[{}B", lines.len().max(image_rows as usize) - i).as_bytes()); // move cursor to end of image Ok(String::from_utf8(image_data)?) } } ================================================ FILE: image/src/lib.rs ================================================ use anyhow::Result; use image::DynamicImage; #[derive(clap::ValueEnum, Clone, PartialEq, Eq, Debug)] pub enum ImageProtocol { Kitty, Sixel, Iterm, } #[cfg(not(windows))] pub mod iterm; #[cfg(not(windows))] pub mod kitty; #[cfg(not(windows))] pub mod sixel; pub trait ImageBackend { fn add_image(&self, lines: Vec, image: &DynamicImage, colors: usize) -> Result; } pub fn get_best_backend() -> Result>> { #[cfg(not(windows))] if sixel::SixelBackend::supported()? { Ok(Some(Box::new(sixel::SixelBackend))) } else if kitty::KittyBackend::supported()? { Ok(Some(Box::new(kitty::KittyBackend))) } else if iterm::ITermBackend::supported() { Ok(Some(Box::new(iterm::ITermBackend))) } else { Ok(None) } #[cfg(windows)] Ok(None) } #[allow(unused_variables)] pub fn get_image_backend(image_protocol: ImageProtocol) -> Option> { #[cfg(not(windows))] let backend = Some(match image_protocol { ImageProtocol::Kitty => Box::new(kitty::KittyBackend) as Box, ImageProtocol::Iterm => Box::new(iterm::ITermBackend) as Box, ImageProtocol::Sixel => Box::new(sixel::SixelBackend) as Box, }); #[cfg(windows)] let backend = None; backend } ================================================ FILE: image/src/sixel.rs ================================================ use anyhow::{Context as _, Result}; use color_quant::NeuQuant; use image::{ DynamicImage, GenericImageView, ImageBuffer, Pixel, Rgb, imageops::{FilterType, colorops}, }; use rustix::event::{PollFd, PollFlags, Timespec, poll}; use rustix::io::read; use rustix::termios::{LocalModes, OptionalActions, tcgetattr, tcgetwinsize, tcsetattr}; use std::io::{Write, stdout}; use std::os::fd::AsFd; use std::time::Instant; pub struct SixelBackend; impl SixelBackend { pub fn supported() -> Result { let stdin = std::io::stdin(); // save terminal attributes and disable canonical input processing mode let old_attributes = { let old = tcgetattr(&stdin).context("Failed to recieve terminal attibutes")?; let mut new = old.clone(); new.local_modes &= !LocalModes::ICANON; new.local_modes &= !LocalModes::ECHO; tcsetattr(&stdin, OptionalActions::Now, &new) .context("Failed to update terminal attributes")?; old }; // ask for the primary device attribute string print!("\x1B[c"); stdout().flush()?; let start_time = Instant::now(); let stdin_fd = stdin.as_fd(); let mut stdin_pollfd = [PollFd::new(&stdin_fd, PollFlags::IN)]; let mut buf = Vec::::new(); loop { // check for timeout while polling to avoid blocking the main thread while poll(&mut stdin_pollfd, Some(&Timespec::default()))? < 1 { if start_time.elapsed().as_millis() > 50 { tcsetattr(stdin, OptionalActions::Now, &old_attributes) .context("Failed to update terminal attributes")?; return Ok(false); } } let mut byte = [0]; read(&stdin, &mut byte)?; buf.push(byte[0]); if buf.starts_with(&[0x1B, b'[', b'?']) && buf.ends_with(b"c") { for attribute in buf[3..(buf.len() - 1)].split(|x| *x == b';') { if attribute == [b'4'] { tcsetattr(stdin, OptionalActions::Now, &old_attributes) .context("Failed to update terminal attributes")?; return Ok(true); } } } } } } impl super::ImageBackend for SixelBackend { #[allow(clippy::map_entry)] fn add_image(&self, lines: Vec, image: &DynamicImage, colors: usize) -> Result { let tty_size = tcgetwinsize(std::io::stdin())?; let cw = tty_size.ws_xpixel / tty_size.ws_col; let lh = tty_size.ws_ypixel / tty_size.ws_row; let width_ratio = 1.0 / cw as f64; let height_ratio = 1.0 / lh as f64; // resize image to fit the text height with the Lanczos3 algorithm let image = image.resize( u32::MAX, (lines.len() as f64 / height_ratio) as u32, FilterType::Lanczos3, ); let image_columns = width_ratio * image.width() as f64; let image_rows = height_ratio * image.height() as f64; let rgba_image = image.to_rgba8(); // convert the image to rgba samples let flat_samples = rgba_image.as_flat_samples(); let mut rgba_image = rgba_image.clone(); // reduce the amount of colors using dithering let pixels = flat_samples .image_slice() .context("Error while slicing the image")?; colorops::dither(&mut rgba_image, &NeuQuant::new(10, colors, pixels)); let rgb_image = ImageBuffer::from_fn(rgba_image.width(), rgba_image.height(), |x, y| { let rgba_pixel = rgba_image.get_pixel(x, y); let mut rgb_pixel = rgba_pixel.to_rgb(); for subpixel in &mut rgb_pixel.0 { *subpixel = (*subpixel as f32 / 255.0 * rgba_pixel[3] as f32) as u8; } rgb_pixel }); let mut image_data = Vec::::new(); image_data.extend(b"\x1BPq"); // start sixel data image_data.extend(format!("\"1;1;{};{}", image.width(), image.height()).as_bytes()); let mut colors = std::collections::HashMap::, u8>::new(); // subtract 1 -> divide -> add 1 to round up the integer division for i in 0..((rgb_image.height() - 1) / 6 + 1) { let sixel_row = rgb_image.view( 0, i * 6, rgb_image.width(), std::cmp::min(6, rgb_image.height() - i * 6), ); for (_, _, pixel) in sixel_row.pixels() { if !colors.contains_key(&pixel) { // sixel uses percentages for rgb values let color_multiplier = 100.0 / 255.0; image_data.extend( format!( "#{};2;{};{};{}", colors.len(), (pixel[0] as f32 * color_multiplier) as u32, (pixel[1] as f32 * color_multiplier) as u32, (pixel[2] as f32 * color_multiplier) as u32 ) .as_bytes(), ); colors.insert(pixel, colors.len() as u8); } } for (color, color_index) in &colors { let mut sixel_samples = vec![0; sixel_row.width() as usize]; sixel_samples.resize(sixel_row.width() as usize, 0); for (x, y, pixel) in sixel_row.pixels() { if color == &pixel { sixel_samples[x as usize] |= 1 << y; } } image_data.extend(format!("#{color_index}").bytes()); image_data.extend(sixel_samples.iter().map(|x| x + 0x3F)); image_data.push(b'$'); } image_data.push(b'-'); } image_data.extend(b"\x1B\\"); image_data.extend(format!("\x1B[{}A", image_rows as u32 - 1).as_bytes()); // move cursor to top-left corner image_data.extend(format!("\x1B[{}C", image_columns as u32 + 1).as_bytes()); // move cursor to top-right corner of image let mut i = 0; for line in &lines { image_data.extend(format!("\x1B[s{line}\x1B[u\x1B[1B").as_bytes()); i += 1; } image_data .extend(format!("\n\x1B[{}B", lines.len().max(image_rows as usize) - i).as_bytes()); // move cursor to end of image Ok(String::from_utf8(image_data)?) } } ================================================ FILE: languages.yaml ================================================ Abap: type: programming ascii: | {0}xxxxxxxxxxxxxxxxxxxx {0}xx{1}###{0}xxx{1}##{0}xx{1}####{0}xxx{1} ## #### ## #### {0}x{1}#{0}xxxxx{1}#{0}xx{1}#{0}x{1}#{0}xxx{1}#{0}x{1} # # # # # # # # {0}xx{1}###{0}xx{1}####{0}x{1}####{0}x{1} #### #### #### #### {0}xxxxx{1}#{0}x{1}#{0}xx{1}#{0}x{1}#{0}xxx{1} # # # # # # # {0}x{1}####{0}xx{1}#{0}xx{1}#{0}x{1}#{0}xx{1} # # #### # # # {0}xxxxxxxxxxxxxx colors: ansi: - blue - white hex: - "#1B387D" - "#EEEEEE" chip: "#E8274B" ABNF: type: data ascii: | {0} ______ {0} | | {0} | /\ | {0}>>---+-->| /--\ |-->+--->> {0} | |______| | {0} | ______ | {0} | | __ | | {0} | | |__) | | {0} +-->| |__) |-->+ {0} | |______| | {0} | ______ | {0} | | | | {0} | | |\ | | | {0} +-->| | \| |-->+ {0} | |______| | {0} | ______ | {0} | | ___ | | {0} | | |___ | | {0} +-->| | |-->+ {0} |______| colors: ansi: - white hex: - "#888888" chip: "#555e25" Ada: type: programming ascii: | {0} * {0} * {0} * ** {0} * ***** {0} ** ****** {0} ** ###******** {0} *** -******#'###********* {0} ***** #### ********* {0} ****************************{1}XXX{0}** {0} ** ******************{1}XXXX{2}o{1}X{0}*{1}X{2}o{1}XXX{0}* {0} **** ***************{1}XXXX{2}ooooo{1}XX{0}* {0} *******************{1}XXXX{2}ooooo{1}X {0} *******************{1}XXX{2}ooo{1}X {0} ************************{1}XX{0}* {0} ************* ****** {0} /| | **** {0} /-|(|(| ******** {0} ************ {0}Time-tested, safe ************* {0}and secure *********** {0} ***** colors: ansi: - white - cyan - blue hex: - "#FFFFFF" - "#0018C9" - "#0C0A7C" chip: "#02F88C" icon: '\u{E6B5}' Agda: type: programming ascii: | {0} / / / / / {0} / / / / / / {0} / o o / / / {0}/____ / / {0} | | {0} | | {0} ; ; {0} \ / {0} '. .' {0} '-._____.-' colors: ansi: - white chip: "#315665" Arduino: type: programming ascii: | {0} ,=======. ,=======. {0} // \\ // \\ {0} // \\// # \\ {0} || ### // ### || {0} \\ //\\ # // {0} \\ // \\ // {0} `=======' `=======' {0} _ _ _ {0} /\ |_) | \ | | | |\ | / \ {0}/--\ | \ |_/ |_| | | \| \_/ colors: ansi: - cyan chip: "#F34B7D" icon: '\u{F34B}' Assembly: type: programming ascii: | {0} __________________________ {0} / \ {1}==={0}| {1}.-. {0}|{1}=== {0} | {1}( ) {0}| {1}==={0}| {1}'-' {0}|{1}=== {0} | | {1}==={0}| {2} _____ ___ ____ {0}|{1}=== {0} | {2}(____ |/___) \ {0}| {1}==={0}| {2}/ ___ |___ | | | | {0}|{1}=== {0} | {2}\_____(___/|_|_|_| {0}| {1}==={0}| |{1}=== {0} | | {1}==={0}| {1}.-. {0}|{1}=== {0} | {1}( ) {0}| {1}==={0}| {1}'-' {0}|{1}=== {0} \__________________________/ colors: ansi: - white - yellow - green chip: "#6E4C13" icon: '\u{E6AB}' Ats: type: programming ascii: | {0} ############ {0} #################### {0} ########################## {0} ############################## {0} #####{1}LLLL{0}#####{2}atsatsatsatsatsatsa{0}# {0} ####{1}LLLLLLL{0}####{2}TSATSATSATSATSATSAT{0}## {0} ####{1}LLL{0}##{1}LLL{0}############{2}SAT{0}########### {0} ###{1}LLL{0}####{1}LLL{0}###{2}satsatsaTSAtsatsats{0}### {0}###########{1}LLLL{0}##{2}ATSATSATSATSATSATSA{0}#### {0}##########{1}LLLLL{0}##{2}TS{0}######{2}ATS{0}######{2}AT{0}#### {0}#########{1}LLLLLL{0}##{2}SA{0}######{2}TSA{0}######{2}TS{0}#### {0} #######{1}LLL{0}##{1}LLL{0}#{2}ATsatsatSATsatsatSA{0}### {0} ######{1}LLL{0}###{1}LLL{0}#{2}TSATSATSATSATSATSAT{0}### {0} ####{1}LLL{0}####{1}LLL{0}###################### {0} ##{1}LLL{0}######{1}LLLLLLLLLLLLLLLLLLL{0}#### {0} {1}LLL{0}#######{1}LLLLLLLLLLLLLLLLLL{0}## {0} ########################## {0} #################### {0} ############ colors: ansi: - yellow - red - blue hex: - "#FFFF00" - "#FF0000" - "#0000FF" chip: "#1AC620" AutoHotKey: type: programming ascii: | {1} .----------------. {1}| .--------------. | {1}| | {0} ____ ____ {1} | | {1}| | {0}|_ || _|{1} | | {1}| | {0} | |__| | {1} | | {1}| | {0} | __ | {1} | | {1}| | {0} _| | | |_ {1} | | {1}| | {0}|____||____|{1} | | {1}| | | | {1}| '--------------' | {1} '----------------' colors: ansi: - white - green hex: - "#FFFFFF" - "#119810" chip: "#6594B9" Bash: type: programming ascii: | {0} _._ {0} _.-' '-._ {0} _.-' '-._ {0} _.-' '-._ {0}| _,-| {0}| _,-'+++| {0}| _,-'+++++++| {0}| ,-'+++++++++++| {0}| |++++ ++++++++| {0}| |+++ +++++++| {0}| |++ +++++++++| {0}| |++++ +++{1}**{0}++| {0}| |++ ++{1}**{0}++++| {0}'-,_ |+++ ++++++_,-' {0} '-,_ |++++++_,-' {0} '-,_ |++_,-' {0} '-|-' colors: ansi: - white - green chip: "#89E051" icon: '\u{EBCA}' C: type: programming ascii: | {0} ++++++ {0} ++++++++++++ {0} ++++++++++++++++++++ {0} ++++++++++++++++++++++++++ {0} ++++++++++++++++++++++++++++++++ {0} +++++++++++++{3}************{0}+++++++++++++ {0}+++++++++++{3}******************{0}++++++++{2};;; {0}+++++++++{3}**********************{0}++{2};;;;;;; {0}++++++++{3}*********{0}++++++{3}******{2};;;;;;;;;;; {0}+++++++{3}********{0}++++++++++{3}**{2};;;;;;;;;;;;; {0}+++++++{3}*******{0}+++++++++{2};;;;;;;;;;;;;;;;; {0}+++++++{3}******{0}+++++++{2};;;;;;;;;;;;;;;;;;;; {0}+++++++{3}*******{0}+++{1}:::::{2};;;;;;;;;;;;;;;;;; {0}+++++++{3}********{1}::::::::::{3}**{2};;;;;;;;;;;;; {0}++++++++{3}*********{1}::::::{3}******{2};;;;;;;;;;; {0}++++++{1}:::{3}**********************{1}::{2};;;;;;; {0}+++{1}::::::::{3}******************{1}::::::::{2};;; {1} :::::::::::::{3}************{1}::::::::::::: {1} :::::::::::::::::::::::::::::::: {1} :::::::::::::::::::::::::: {1} :::::::::::::::::::: {1} :::::::::::: {1} :::::: colors: ansi: - cyan - blue - blue - white hex: - "#649AD2" - "#004283" - "#00599D" - "#FFFFFF" chip: "#555555" icon: '\u{E61E}' Ceylon: type: programming ascii: | {1} @@ {1} @@ {3} @@@@@@@{1}@@@@@@@@@@@@@@ @@ {0} @@@{3}@@@@@@@@@@{1}@@@@@@ /@@@@@@@@ @@@ {0} @@@@@@{3}@@@@@@@@@@{1}@@@@ (@@@@ @@@@@ @@{2}@@ {0} @@@@@@@@{3}@@@@@@@@@@@{1}@@@ \@@@@@@@@@@@@{2}@@@ {0}@@@@@@@@@@@{3}@@@@@@@@@@@{1}@@@@@@@@@@@@@{2}@@@@ {0}|/ @@@@@@@@@@{3}@@@@@@@@@@@@{1}@ {0} @@@@@@@@@@@@{3}@@@@@@@@@@ {0} @@@@@@@@@@@@@@{3}@@@@@@@ {4}@@ {0} @@@@@@@ @@@@@@@ {4}@@@ {0} @@@@@@ {4}@@ {0}@@@@@ {4}@@@@ {0} @@@@ {4}@@@ {0}@@@@@ {4}@@@@@ colors: ansi: - yellow - yellow - yellow - yellow - yellow hex: - "#C27E10" - "#DDA12E" - "#D1911F" - "#CC8B18" - "#AB7008" chip: "#DFA535" icon: '\u{E78B}' Clojure: type: programming ascii: | {0} ,,,,, {0} .-/+ooooooooo+/:-` {0} ./ooooooooooooooooooo+:. {0} -+oooooooooooooooooooooooo+- {0} ,+ooooooooo+/:---::/+ooooooooo+. {0} `-/oosoooooo: {1} .,,oooo/' {0}:\\\\\, `\oooooooo: {1} :,ooooo- :///: {0}:\\\\\\, -oooooooo- {1} :oooooo: ://///: {0}:\\\\\\\, :oooooo+ {1}.ooooooo :///////: {0}:\\\\\\\, ooooooo. {1}:oooooo+ ://////: {0}:\\\\\\, +oooooo: {1}-ooooooo` :////: :: {0}:\\\\\, 'ooooooo- {1}`ooooooo: ://: ://: {0}:\\\, /oooooo: {1} -ooooooo: :: :////: {0}:\: :ooooo,: {1} :ooooooo+. ://////: {0}.+oooo,,. {1} :oooooooo+-` {1} .+ooooooooo+/::::://oooooooooo+' {1} -+oooooooooooooooooooooooo+- {1} .:ooooooooooooooooooo+:. {1} `-:/ooooooooo+/:.` {1} `````` colors: ansi: - cyan - green hex: - "#8BADF6" - "#8DD545" chip: "#DB5855" icon: '\u{E768}' CMake: type: programming ascii: | {0} ;e{2}` {0} ;QD{2}?` {0} ;B#R{2}1r` {0} ;WRMK{2}S|r` {0} :O9KOK{2}S\\*` {0} :keXPk6{2}Zc7v|` {0} :ajyoaZe{3}m{2}JJ{]\` {0} :]z1x}f9{3}@@{2}yujSoc` {0} "7\/LvU{3}Q@@@{2}XoZemXv` {0} ,\**v{1}oo{3}qMBBB{2}kmXEkU9z` {0} ,\*}{1}Sx\||?|cFf{2}okqOdHDx` {0} ,L]{1}jc\\\||?*>rr^^|zo{2}$MN]` {0}-v{1}7????*>>rrr^^^;;;;;;^\{2}F^` colors: ansi: - blue - green - red - black chip: "#DA3434" icon: '\u{E794}' CoffeeScript: type: programming ascii: | {0} ##### ###### {0} ### ### ### {0} /A\ ###### ##### /A\ {0} \AAAAA\ /AAAAA/ {0} \AAAAAAAAAAAAAAAAAAAAA/ {0} \AA\ /AA/ {0} |\AAAAAAAAAAAAAAAAAAAAAAAAAAA/| {0} /\\llAAAAAAAAAAAAAAAAAAAAAAAll// {0} /#A\\llAAAAAAAAAAAAAAAAAAAAAll// {0}|#A \\llAAAAAAAAAAAAAAAAAAll// {0} \#A \\llAAAAAAAAAAAAAAll// {0} \#A \\llAAAAAAAAAAAAll// {0} \#A> ||lAAAAAAAAAAl|| {0} \;AAAAAAAAAA;/ colors: ansi: - red chip: "#244776" icon: '\u{E751}' ColdFusion: type: programming ascii: | {0}CfCfCfCfCfCfCfCfCfCfCfCfCfCfCfCfCfCf {0}Cf{1}@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@{0}Cf {0}Cf{1}@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@{0}Cf {0}Cf{1}@@@@@@@@@@@@@@@@@@@@@@{0}CfCfCfCf{1}@@{0}Cf {0}Cf{1}@@@@@{0}CfCfCfCfCf{1}@@@@{0}CfCfCfCfCf{1}@@@{0}Cf {0}Cf{1}@@@@{0}CfCfCfCfCf{1}@@@@{0}CfCf{1}@@@@@@@@@@{0}Cf {0}Cf{1}@@@{0}CfCf{1}@@@@@@@@@@{0}CfCf{1}@@@@@@@@@@@{0}Cf {0}Cf{1}@@{0}CfCf{1}@@@@@@@@{0}CfCfCfCfCfCf{1}@@@@@@{0}Cf {0}Cf{1}@@{0}CfCf{1}@@@@@@@@@@@{0}CfCf{1}@@@@@@@@@@@{0}Cf {0}Cf{1}@@{0}CfCf{1}@@@@@@@@@@@{0}CfCf{1}@@@@@@@@@@@{0}Cf {0}Cf{1}@@@{0}CfCf{1}@@@@@@@@@@{0}CfCf{1}@@@@@@@@@@@{0}Cf {0}Cf{1}@@@@{0}CfCfCfCfCf{1}@@@{0}CfCf{1}@@@@@@@@@@@{0}Cf {0}Cf{1}@@@@@{0}CfCfCfCfCf{1}@@{0}CfCf{1}@@@@@@@@@@@{0}Cf {0}Cf{1}@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@{0}Cf {0}Cf{1}@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@{0}Cf {0}CfCfCfCfCfCfCfCfCfCfCfCfCfCfCfCfCfCf colors: ansi: - white - blue hex: - "#E5F3FC" - "#274550" chip: "#ed2cd6" icon: '\u{E645}' Coq: type: programming ascii: | {0} :::::::: {0} ::::::::::: {0} ::::::::::: {0} :::::{1}___{0}::: {1} ______ {0}: {1} ____ _________ {1} ___ ___________ {1} ___ ____________ {1} _________________ {1} ___________________ {1}______________ ______ {1} ___________ ___ {1} ______ {1} ____ {1} ______ {1} ________ {1} ________ colors: ansi: - yellow - white hex: - "#BF8C5E" - "#D5BE99" chip: "#D0B68C" Cpp: type: programming ascii: | {0} ++++++ {0} ++++++++++++ {0} ++++++++++++++++++++ {0} ++++++++++++++++++++++++++ {0} ++++++++++++++++++++++++++++++++ {0} +++++++++++++{3}************{0}+++++++++++++ {0}+++++++++++{3}******************{0}++++++++{2};;; {0}+++++++++{3}**********************{0}++{2};;;;;;; {0}++++++++{3}*********{0}++++++{3}******{2};;;;;;;;;;; {0}+++++++{3}********{0}++++++++++{3}**{2};;;;;;;;;;;;; {0}+++++++{3}*******{0}+++++++++{2};;;;;;{3}**{2};;;;{3}**{2};;; {0}+++++++{3}******{0}+++++++{2};;;;;;;;{3}****{2};;{3}****{2};; {0}+++++++{3}*******{0}+++{1}:::::{2};;;;;;;{3}**{2};;;;{3}**{2};;; {0}+++++++{3}********{1}::::::::::{3}**{2};;;;;;;;;;;;; {0}++++++++{3}*********{1}::::::{3}******{2};;;;;;;;;;; {0}++++++{1}:::{3}**********************{1}::{2};;;;;;; {0}+++{1}::::::::{3}******************{1}::::::::{2};;; {1} :::::::::::::{3}************{1}::::::::::::: {1} :::::::::::::::::::::::::::::::: {1} :::::::::::::::::::::::::: {1} :::::::::::::::::::: {1} :::::::::::: {1} :::::: colors: ansi: - cyan - blue - blue - white hex: - "#649AD2" - "#004283" - "#00599D" - "#FFFFFF" chip: "#F34B7D" icon: '\u{E61D}' serialization: c++ Crystal: type: programming ascii: | {0} ,loc;'.. {0} ,xNMMMWNXK0kdl,.. {0} ,xNMMMMMMMMMMMMMKOxoc;. {0} ,xNMMMMMMMMMMMMMMMMMMMMWX: {0} ,xNMMMMMMMMMMWNNWMMMMMMMMMMk. {0} ,xNMMMMMWX0kdlc;:lOMMMMMMMMMMNc {0},xXK{1}..mmmMMMMMMMM'{0}0MMMMMMMMMMMMMO. {0}0o;{1}MMMMMMMMMMMMMm{0}.MMMMMMMMMMMMMMWl {0}0O:.{1}MMMMMMMMMMMM'{0}cMMMMMMMMMMMMMMM0' {0}oWWO:.{1}MMMMMMMMMm{0}.OMMMMMMMMMMMMMMMWo {0}'0MMWO:.{1}MMMMMMM'{0}lWMMMMMMMMMMMMMMMMK, {0} lWMMMWO:.{1}MMMMm{0}'0MMMMMMMMMMMMMMMMMWd {0} .OMMMMMW0c.{1}MM'{0}oWMMMMMMMMMMMMMMMMMWk. {0} cNMMMMMMW0c{1}'{0},KMMMMMMMMMMMMMMMMW0c. {0} .kMMMMMMMMW00WMMMMMMMMMMMMMMW0c. {0} cNMMMMMMMMMMMMMMMMMMMMMMMW0c. {0} .xWMMMMMMMMMMMMMMMMMMMMW0:. {0} .';coxOKNWMMMMMMMMMMWO:. {0} ..,:ldk0KXWMM:. {0} ...';c: colors: ansi: - white - black chip: "#000100" icon: '\u{E62F}' CSharp: type: programming ascii: | {0} ++++++ {0} ++++++++++++ {0} ++++++++++++++++++++ {0} ++++++++++++++++++++++++++ {0} ++++++++++++++++++++++++++++++++ {0} +++++++++++++{3}************{0}+++++++++++++ {0}+++++++++++{3}******************{0}++++++++{2};;; {0}+++++++++{3}**********************{0}++{2};;;;;;; {0}++++++++{3}*********{0}++++++{3}******{2};;;;;;;;;;; {0}+++++++{3}********{0}++++++++++{3}**{2};;;{3}**{2};;;{3}**{2};;; {0}+++++++{3}*******{0}+++++++++{2};;;;;;{3}*********{2};; {0}+++++++{3}******{0}+++++++{2};;;;;;;;;;{3}**{2};;;{3}**{2};;; {0}+++++++{3}*******{0}+++{1}:::::{2};;;;;;;{3}*********{2};; {0}+++++++{3}********{1}::::::::::{3}**{2};;;{3}**{2};;;{3}**{2};;; {0}++++++++{3}*********{1}::::::{3}******{2};;;;;;;;;;; {0}++++++{1}:::{3}**********************{1}::{2};;;;;;; {0}+++{1}::::::::{3}******************{1}::::::::{2};;; {1} :::::::::::::{3}************{1}::::::::::::: {1} :::::::::::::::::::::::::::::::: {1} :::::::::::::::::::::::::: {1} :::::::::::::::::::: {1} :::::::::::: {1} :::::: colors: ansi: - blue - magenta - magenta - white hex: - "#9B4F97" - "#67217A" - "#803788" - "#FFFFFF" chip: "#178600" icon: '\u{E648}' serialization: c# Css: type: markup ascii: | {1} #### #### #### {1} ## ## ## ## {1} ## #### #### {1} ## ## ## ## {1} #### #### #### {0}((((((((((((((((((((((((((((((((((( {0}(((((((((((((((((/////////////((((( {0}(((((((((((((((((/////////////((((( {0}((((((( ///((((( {0} (((((( ///(((( {0} (((((((((((((((( /////(((( {0} ((((((((((( //////////(((( {0} ((((((( ///(((( {0} (((((( ///((( {0} (((((((((((((((////// ///((( {0} ((((((( ((((////// ///((( {0} ((((((( ///((( {0} ((((((( /////(( {0} ((((((((((((((/////////////(( {0} ((((((((((((((//////((((((((( {0} ((((((((((((((( colors: ansi: - blue - white chip: "#563D7C" icon: '\u{E749}' Cuda: type: programming ascii: | {0} 88888888888888888888888 {0} 8888 8888888888888888 {0} 888888 8888 888888888888 {0} 88888 88888888 8888888888 {0} 8888 8888 8888 88888888 {0}8888 8888 888 8888 8888888 {0}8888 8888 8888 8888 88888888 {0} 8888 8888 888888888 88888 888 {0} 88888 888 8888888 88888 8 {0} 8888 8888 88888 8 {0} 88888 8888888 8888 {0} 888888 888888 88888888 {0} 8888 8888888888888 {0} 88888888888888888888888 colors: ansi: - green hex: - "#76B900" chip: "#73B303" D: type: programming ascii: | {0} DDD {0}DDDDDDDDDDDDDDDDDDDDDD DDDDD {0}DDDDDDDDDDDDDDDDDDDDDDDD DDD {0}DDDDDDDDDDDDDDDDDDDDDDDDDD DDDDD {0}DDDDDD DDDDDDD DDDDDDDDD {0}DDDDDD DDDDDDDDDDDDDDDDD {0}DDDDDD DDDDDDDDDDDDDDDD {0}DDDDDD DDDDDDDDDDDDDD {0}DDDDDD DDDDDDDDDDD {0}DDDDDD DDDDDDD {0}DDDDDD DDDDDDD {0}DDDDDD DDDDDDD {0}DDDDDDDDDDDDDDDDDDDDDDDDDDD {0}DDDDDDDDDDDDDDDDDDDDDDDDD {0}DDDDDDDDDDDDDDDDDDDDDD colors: ansi: - red chip: "#BA595E" icon: '\u{E7AF}' Dart: type: programming ascii: | {0}# {0} ## {0} ### {0} ###### ### {0} ######### ####### {0} ########### ######{2}O{0}##{2}========- {0} ##################### {0} ################## {0} ###############{1}+++++ {0}###################{1}+++++++ {0} ##########{1}+++++++ {0} ##{1}+++++++ {0} ###{1}+++ {0} ##### {0} ####### {0} ######### {0} ####### {0} ##### colors: ansi: - blue - cyan - blue hex: - "#00A3E7" - "#42DFCD" - "#01597D" chip: "#00B4AB" icon: '\u{E64C}' Dockerfile: type: programming ascii: | {2} ## {0} . {2} ## ## ## {0} == {2} ## ## ## ## ##{0} === {0} /"""""""""""""""""\___/ === {1}~~~ {0}{{1}~~ ~~~~ ~~~ ~~~~ ~~~ ~ {0}/ ===-{1} ~~~ {0} \{1}______ o{0} __/ {1} \ \ {0} __/ {1} \____\{0}_______/ colors: ansi: - cyan - white - cyan chip: "#384D54" icon: '\u{F308}' Elisp: type: programming ascii: | {0} ':r\iv7i|r:' {0} :LFaZZZaaaoooo2t\: {0} ^]aZZZZaaw9DN{1}Q@Q{0}gojjv; {0} ,vaZZZaX69KOHRW#{1}@@@{0}Ouuuu/, {0} _[ZZaaa{1}Q@@@@QBNMRD{0}dEuuufFFl, {0}.7aaaooo{1}wB@@#{0}h2jjuuuufFF]]]]|- {0}:yooooSSS2S${1}gQ@Q{0}8hjfFF]]]][tz" {0};oooSS2ed#{1}Q@@@@@Q{0}N{0}Do]]][[ttt[: {0}:uSS2mQ{1}@@@@Q{0}deuF]]]][[ttt[[[z~ {0}-/yjjO{1}@@@@Q{0}uFF]]][[tttt[[]]]?` {0} ,vuuue&{1}Q@@@QQ#NNggg{0}&D9u[]i' {0} '/ffFF]]jek99OR{1}#Q@@Q{0}Hj]]|' {0} `;c]]][uaXUKO$wo]]]]L:` {0} `,>i1tt[[]]]]ti>,` {0} `.~;^>??>^;,-` colors: ansi: - magenta - white chip: "#C065DB" icon: '\u{E632}' serialization: emacs-lisp Elixir: type: programming ascii: | {0} x {0} WNX {0} Odc:x {0} 0ddko,oX {0} kokNWOllOW {0} KdoKWMMNKxl0W {0} 0odXMMMMMMNxoON {0} 0lxNMMMMMMMMW0dd0N {0} 0oxNMMMMMMMMMMMNOodKW {0} xodXMMMMMMMMMMMMMMXxokN {0}xol0MMMMMMMMMMMMMMMMW0odX {0}xoxWMMMMMMMMMMMMMMMMMMKodN {0}0lOMMMMMMMMMMMMMMMMMMMWOlO {0}OlOMWKXMMMMMMMMMMMMMMMMKlxW {0}KlxWXodNMMMMMMMMMMMMMMM0lkW {0}xxoKWOlkNMMMMMMMMMMMMMWkl0 {0} XooKN0ddkKNWWWMMMMMMWOlkW {0} XxokXN0kxxkkKMMMMN0doON {0} WKxdxk0KKKKXK0OxddkXW {0} WNKOxxxxxxxxkOXW {0} WWWWWWW colors: ansi: - magenta chip: "#6E4A7E" icon: '\u{E62D}' Elm: type: programming ascii: | {0} {1}ElmElmElmElm {3}ElmElmElmElmElm {0}El {1}mElmElmElmEl {3}mElmElmElmElm {0}Elm {1}ElmElmElmElmE {3}lmElmElmElm {0}ElmEl {1}mElmElmElmElm {3}ElmElmElm {0}ElmElmE {3}mElmElm {0}ElmElmElm {2}ElmElmElmEl {3}lmElm {0}ElmElmElmEl {2}mElmElm {1}Elm {3}Elm {0}ElmElmElmElmE {2}lmE {1}lmElmEl {3}m {0}ElmElmElmElmElm {1}mElmElmElmE {0}ElmElmElmElmElmE {1}mElmElmElm {0}ElmElmElmElmEl {3}mE {1}lmElmE {2}lm {0}ElmElmElmElm {3}ElmElm {1}El {2}mElm {0}ElmElmElmE {3}lmElmElmEl {2}ElmElm {0}ElmElmEl {3}mElmElmElmElmE {2}lmElm {0}ElmElm {3}ElmElmElmElmElmElm {2}Elm {0}ElmE {3}lmElmElmElmElmElmElmEl {2}m {0}El {3}mElmElmElmElmElmElmElmElmE {0} {3}ElmElmElmElmElmElmElmElmElmElm colors: ansi: - blue - green - yellow - cyan chip: "#60B5CC" icon: '\u{E62C}' Emojicode: type: programming ascii: | {0}~~ {0} ~~ {0} ~~ {0} ~~{2} '''''''' {0} ~~~{2} '''''''''''' {0} {1}````````{2}'''''''''''''' {1} `````````{2}'''''''''''''' {1} `````````{2}'''''''''''''{3}~~~~~~~- {1} `````````{2}'''''''''''{3}~~~~~~~~~~~ {1} ``````````{2}''{1}````````{3}~~~~~~~~~~~~ {1} ``````````````````````{3}~~~~~~~~~~~ {1} ```````````````````````{3}~~~~~~~~~~ {1} ``{3}~~~~~{1}```````````````{3}~~~~~~~~~~ {3} -~~~~~~~{1}```````````````{3}~~~~~~~~~ {3} ~~~~~~~~~{1}``````````````````````` {3} ~~~~~~~~~~{1}```````````````````````` {3} ~~~~~~~~~~~~{1}````````````````````````` {3} ~~~~~~~~~~~~~~{1}``````{2}```````````````` {3} ~~~~~~~~~~~~~~{2}'''''''{1}``````````````` {3} ~~~~~~~~~~~~{2}''''''''{1}``````````````` {3} ~~~~~~~~{2}'''''''''''{1}`````````````` {2} {2}'''''''''''{1}```````````` {2} {2}'''''''' {1}```````` colors: ansi: - green - magenta - magenta - magenta hex: - "#77B255" - "#9266CC" - "#AA8DD8" - "#744EAA" chip: "#60B5CC" icon: '\u{f1044}' Erlang: type: programming ascii: | {0} EEEEEEEEEEEEE EEEEEEEEEEEE {0} EEEEEEEEEEEE EEEEEEEEEEEE {0} EEEEEEEEEEEE EEEEEEEEEEE {0} EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE {0}EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE {0}EEEEEEEEEEEEE {0}EEEEEEEEEEEEE {0}EEEEEEEEEEEEE {0} EEEEEEEEEEEEE E {0} EEEEEEEEEEEEE EEEEE {0} EEEEEEEEEEEEE EEEEEEEEE {0} EEEEEEEEEEEEEE EEEEEEEEEE colors: ansi: - red chip: "#B83998" icon: '\u{E7B1}' Fish: type: programming ascii: | {0} ___ {0} ___======____=-{1}-{0}-=) {0}/T \_{1}--={0}==) {0}[ \ ({1}0{0}) \~ \_{1}-={0}=) {0} \ / )J~~ \{1}-={0}) {0} \\___/ )JJ~{1}~~{0} \) {0} \_____/JJJ~~{1}~~{0} \ {0} / \ {1}, \{0}J~~~{1}~~{0} \ {0} (-{1}\){0}\=|{1}\\\{0}~~{1}~~{0} L_{1}_ {0} (\\) ({1}\{0}\\)_ {1}\==__ {0} \V \\\) ===_____ {1}\\\\{0}\\ {0} \V) \_) \\{1}\\JJ\{0}J\) {0} /J{1}\J{0}T\JJJJ) {0} (JJJ| \UUU) {0} (UU) colors: ansi: - red - yellow chip: "#4AAE47" icon: '\u{EE41}' Forth: type: programming ascii: | {0}:::::::::::::::::::::::::::::::::::::::: {0}:::::::::::::::::::::::::::::::::::::::: {0}:::::::::::::::::::::::::::::::::::::::: {0}:::::::::::::::::::::::::::::::::::::::: {0}:::::: :::::::: :::::: {0}:::::: :::::::: :::::: {0}:::::: :::::::: :::::: {0}:::::: :::::::: :::::: {0}:::::::::::::::::::::::::::::::::::::::: {0}:::::::::::::::::::::::::::::::::::::::: {0}:::::::::::::::::::::::::::::::::::::::: {0}:::::: :::::::: :::::: {0}:::::: :::::::: :::::: {0}:::::: :::::::: :::::: {0}:::::: :::::::: ::::::: {0}:::::::::::::::::::::::::: ::::::::: {0}:::::::::::::::::::::::: ::::::::::: {0}:::::::::::::::::::::::::::::::::::::::: {0}:::::::::::::::::::::::::::::::::::::::: {0}:::::::::::::::::::::::::::::::::::::::: colors: ansi: - red chip: "#341708" icon: '\u{229E}' FortranLegacy: type: programming ascii: | {4} _ {1}__ __ {4} _|_ {1} / / {0} o{4}|{1} / / {0} /\ {0} / \ {0} | | {0} |{2}NASA{0}| {0} | | {0} | | {0} | | {0} ' ' {0} | | {0} | | {0} |______| {3} /-`'-`.\ {3} ; / . \'\. {3} '/''( .'\.'' {3}'.'.;.;' ;'.;' colors: ansi: - white - green - cyan - yellow - red chip: "#4D41B1" icon: '\u{f121a}' serialization: fortran FortranModern: type: programming ascii: | {4} _{1} _ _ {4} _|_{1}(_|/ \ {0} o{4}| {1} _|\_/ {0} /\ {0} / \ {0} | | {0} |{2}NASA{0}| {0} | | {0} | | {0} | | {0} ' ' {0} | | {0} | | {0} |______| {3} /-`'-`.\ {3} ; / . \'\. {3} '/''( .'\.'' {3}'.'.;.;' ;'.;' colors: ansi: - white - green - cyan - yellow - red chip: "#4D41B1" icon: '\u{f121a}' FSharp: type: programming ascii: | {0} / {1}(( {0} /// {1}(((( {0} ///// {1}(((((( {0} /////// {1}(((((((( {0} ///////// {1}(((((((((( {0} ////////// {1} (((((((((( {0} ////////// / {1} (((((((((( {0} ////////// /// {1} (((((((((( {0} ////////// ///// {1} (((((((((( {0}///////// ////// {1} (((((((((( {0} ///////// //// {1} (((((((((( {0} ///////// // {1} (((((((((( {0} ///////// {1} (((((((((( {0} ///////// {1} (((((((((( {0} //////// {1}((((((((( {0} ////// {1}((((((( {0} //// {1}((((( {0} // {1}((( colors: ansi: - cyan - cyan chip: "#B845FC" icon: '\u{E7A7}' serialization: f# GdScript: type: programming ascii: | {0} _.aMb dMe._ {0} 'H8888b, ,d8888H' {0} . .:88888d8888888888:. . {0} .d8b.dM888888888888888888Mb.d8b. {0}d88888888888888888888888888888888b {0}'V888888888888888888888888888888V' {0} 88888888888888888888888888888888 {0} 8888P' {1}__{0} "V88888888V" {1}__{0} 'V8888 {0} 8888" {1}dMMb {0}'888{1}''{0}888' {1}d88b {0}"8888 {0} 8888b {1}:HH: {0}/888{1} {0}888\ {1}:HH: {0}d8888 {0} 8888be._.ad8888{1}..{0}8888be._.ad8888 {0} WW8888888888888888888888888888WW {0} {1}#######{0}YW88/{1}########{0}\88WY{1}####### {0} MWbzxe{1}##{0}8MW;{1}##{0}8888{1}##{0};8MW{1}##{0}aezdWM {0} 'Y8888b.{1}#####{0}/8888\{1}#####{0}.d8888Y' {0} "V8888888888888888888888888V" {0} '^YV8888888888888888888VP^' {0} '"^^VY888888888VY^^' colors: ansi: - cyan - white hex: - "#458DC0" - "#FFFFFF" chip: "#355570" icon: '\u{E65F}' Glsl: type: programming ascii: | {0} ,,@@@@@@@@@@@@@@@@@.. {0} ,@@@@@@@@@@@@@@@@@@@@@@@. {0} ,@@@@@@@@@@@@@@@@@@@@@@@@@@@. {0} ,@@@@@@@@' `@@@@@@@. {0} ,@@@@@@@@' `@@@@. {0},@@@@@@@' `@@. {0}@@@@@@@' {1}_____ _ _____ _ {0}`@ {0}@@@@@@ {1}/:::::||:| /:::::||:| {0}@@@@@@ {1}|:| __ |:| |:(___ |:| {0}@@@@@@ {1}|:| |::||:| \::::\ |:| {0}@@@@@@ {1}|:|__|:||:|____ ____):||:|____ {0}@@@@@@ {1}\:::::||::::::||:::::/ |::::::| {0}@@@@@@@. ,@ {0}`@@@@@@@. ,@@' {0} `@@@@@@@@. ,@@@@' {0} `@@@@@@@@. ,@@@@@@@' {0} `@@@@@@@@@@@@@@@@@@@@@@@@@@@' {0} `@@@@@@@@@@@@@@@@@@@@@@@' {0} ``@@@@@@@@@@@@@@@@@'' colors: ansi: - blue - magenta hex: - "#5487a6" - "#bc258e" chip: "#5686a5" Go: type: programming ascii: | {0} --==============-- {0} .-==-.===oooo=oooooo=ooooo===--===- {0} .== =o={1}oGGGGGG{0}o=oo=o{1}GGGGGGG{0}G=o= oo- {0} -o= oo={1}G .=GGGGG{0}o=o={1}= .=GGGGG{0}=ooo o=- {0} .-=oo={1}o==oGGGGG{0}=oo={1}oooGGGGGo{0}=oooo. {0} -ooooo{1}=oooooo{0}={2}. .{0}={1}=ooo=={0}oooooo- {0} -ooooooooooo{2}====_===={0}ooooooooooo= {0} -oooooooooooo{2}=={1}#{0}.{1}#{2}=={0}ooooooooooooo {0} -ooooooooooooo={1}#{0}.{1}#{0}=oooooooooooooo {0} .oooooooooooooooooooooooooooooooo. {0} oooooooooooooooooooooooooooooooo. {2} ..{0}oooooooooooooooooooooooooooooooo{2}.. {2}-=o-{0}=ooooooooooooooooooooooooooooooo{2}-oo. {2}.=- {0}oooooooooooooooooooooooooooooooo{2}-.- {0} .oooooooooooooooooooooooooooooooo- {0} -oooooooooooooooooooooooooooooooo- {0} -oooooooooooooooooooooooooooooooo- {0} -oooooooooooooooooooooooooooooooo- {0} .oooooooooooooooooooooooooooooooo {0} =oooooooooooooooooooooooooooooo- {0} .=oooooooooooooooooooooooooooo- {0} -=oooooooooooooooooooooooo=. {2} =oo{0}====oooooooooooooooo==-{2}oo=- {2} .-==- {0}.--=======--- {2}.==- colors: ansi: - cyan - white - yellow hex: - "#74CDDD" - "#FFFFFF" - "#F6D2A2" chip: "#00ADD8" icon: '\u{E627}' Graphql: type: data ascii: | {0} {}{}{} {0} {}{}{}{} {0} {}{}{}{} {0} {} {}{}{} {} {0} {}{}{} {} {} {} {} {}{}{} {0}{}{}{}{} {} {} {}{}{}{} {0}{}{}{}{} {} {} {}{}{}{} {0} {}{}{} {} {} {}{}{} {0} {} {} {} {} {0} {} {} {} {} {0} {} {} {} {} {0} {} {} {} {} {0} {} {} {} {} {0} {}{}{} {}{}{} {0}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} {0}{}{}{}{} {}{}{}{} {0} {}{}{} {} {} {}{}{} {0} {} {}{}{} {} {0} {}{}{}{} {0} {}{}{}{} {0} {}{}{} colors: ansi: - magenta chip: "#E10098" icon: '\u{e662}' Groovy: type: programming ascii: | {0} * {0} *** {0} ***** {0} ******* {0} ********* {0} *********** {0} ************* {0}*****************{1}@@@@@{0}***************** {0} *************{1}@{0}******{1}@{0}************** {0} ***********{1}@{0}**{1}@@{0}***{1}@{0}************* {0} *********{1}@{0}***{1}@@{0}**{1}@{0}**{1}@{0}********** {0} *******{1}@{0}****{1}@@{0}***{1}@@@{0}******* {0} *******{1}@{0}******{1}@@{0}**{1}@@{0}***** {0} *******{1}@@@@@@{0}**{1}@@@@{0}**** {0} ************{1}@@@@@@{0}*** {0} ******{1}@@@@@@@@@@@{0}**** {0} ********{1}@@@@@@@@{0}******* {0} **********{1}@@{0}************* {0} *************************** {0} *********** *********** {0} ********* ********* {0} ***** ***** {0} * * colors: ansi: - cyan - white chip: "#4298B8" icon: '\u{E775}' Haskell: type: programming ascii: | {0}yyyyyy{1} xxxxxx {0} yyyyyy{1} xxxxxx {0} yyyyyy{1} xxxxxx {0} yyyyyy{1} xxxxxx {0} yyyyyy{1} xxxxxx{2} yyyyyyyyyy {0} yyyyyy{1} xxxxxx{2} yyyyyyyyy {0} yyyyyy{1} xxxxxx {0} yyyyyy{1} xxxxxxxx{2} yyyyyyy {0} yyyyyy{1} xxxxxxxxxx{2} yyyyyy {0} yyyyyy{1} xxxxxxxxxxxx {0} yyyyyy{1} xxxxxx xxxxxx {0} yyyyyy{1} xxxxxx xxxxxx {0}yyyyyy{1} xxxxxx xxxxxx colors: ansi: - cyan - magenta - blue hex: - "#453A62" - "#5E5086" - "#8F4E8B" chip: "#5E5086" icon: '\u{E777}' Haxe: type: programming ascii: | {0}############# {2}@@@@@@@@@@@@@ {0}################# {2}@@@@@@@@@@@@@@@@@ {0}###################{1}XX{2}@@@@@@@@@@@@@@@@@@@ {0}##################{1}XXXX{2}@@@@@@@@@@@@@@@@@@ {0}################{1}XXXXXXXX{2}@@@@@@@@@@@@@@@@ {0}##############{1}XXXXXXXXXXXX{2}@@@@@@@@@@@@@@ {0} ###########{1}XXXXXXXXXXXXXXXX{2}@@@@@@@@@@@ {0} ########{1}XXXXXXXXXXXXXXXXXXXX{2}@@@@@@@@ {0} #####{1}XXXXXXXXXXXXXXXXXXXXXXXX{2}@@@@@ {0} ##{1}XXXXXXXXXXXXXXXXXXXXXXXXXXXX{2}@@ {0} ##{1}XXXXXXXXXXXXXXXXXXXXXXXXXXXX{2}@@ {0} #####{1}XXXXXXXXXXXXXXXXXXXXXXXX{2}@@@@@ {0} ########{1}XXXXXXXXXXXXXXXXXXXX{2}@@@@@@@@ {0} ###########{1}XXXXXXXXXXXXXXXX{2}@@@@@@@@@@@ {0}##############{1}XXXXXXXXXXXX{2}@@@@@@@@@@@@@@ {0}################{1}XXXXXXXX{2}@@@@@@@@@@@@@@@@ {0}##################{1}XXXX{2}@@@@@@@@@@@@@@@@@@ {0}###################{1}XX{2}@@@@@@@@@@@@@@@@@@@ {0}################# {2}@@@@@@@@@@@@@@@@@ {0}############# {2}@@@@@@@@@@@@@ colors: ansi: - yellow - yellow - yellow hex: - "#FAB20B" - "#F69912" - "#F47216" chip: "#DF7900" icon: '\u{E666}' Hcl: type: programming ascii: | {0}:: {0}:::: {0}:::::: {0}:::::::: {0}:::::::::: {0}:::::::::: :: {1} .. {0} :::::::: :::: {1} .... {0} :::::: :::::: {1} ...... {0} :::: :::::::: {1} ........ {0} :: ::::::::::{1} .......... {0} ::::::::::{1} .......... {0} ::::::::{1} ........ {0} :: ::::::{1} ...... {0} :::: ::::{1} .... {0} :::::: ::{1} .. {0} :::::::: {0} :::::::::: {0} :::::::::: {0} :::::::: {0} :::::: {0} :::: {0} :: colors: ansi: - magenta - magenta hex: - "#5F43E9" - "#4040B2" chip: "#AACE60" Hlsl: type: programming ascii: | {0}████████████████ {1}████████████████ {0}█████ ██ █████ {1}█████ █████████ {0}█████ ██ █████ {1}█████ █████████ {0}█████ █████ {1}█████ █████████ {0}█████ ██ █████ {1}█████ █████████ {0}█████ ██ █████ {1}█████ █████ {0}████████████████ {1}████████████████ {2}████████████████ {3}████████████████ {2}█████ █████ {3}█████ █████████ {2}█████ █████████ {3}█████ █████████ {2}█████ █████ {3}█████ █████████ {2}█████████ █████ {3}█████ █████████ {2}█████ █████ {3}█████ █████ {2}████████████████ {3}████████████████ colors: ansi: - red - green - blue - yellow hex: - "#F65314" - "#7CBB00" - "#00A1F1" - "#FFBB00" chip: "#AACE60" icon: '\u{229E}' HolyC: type: programming ascii: | {0} ++++++ {0} ++++++++++++ {0} ++++++++++++++++++++ {0} ++++++++++++++++++++++++++ {0} ++++++++++++++++++++++++++++++++ {0} +++++++++++++{3}************{0}+++++++++++++ {0}+++++++++++{3}******************{0}++++++++{2};;; {0}+++++++++{3}**********************{0}++{2};;;;;;; {0}++++++++{3}*********{0}++++++{3}******{2};;;;;;;;;;; {0}+++++++{3}********{0}++++++++++{3}**{2};;;;{3}**{2};;;;;;; {0}+++++++{3}*******{0}+++++++++{2};;;;;;{3}******{2};;;;; {0}+++++++{3}******{0}+++++++{2};;;;;;;;;;;{3}**{2};;;;;;; {0}+++++++{3}*******{0}+++{1}:::::{2};;;;;;;;;{3}**{2};;;;;;; {0}+++++++{3}********{1}::::::::::{3}**{2};;;;{3}**{2};;;;;;; {0}++++++++{3}*********{1}::::::{3}******{2};;;;;;;;;;; {0}++++++{1}:::{3}**********************{1}::{2};;;;;;; {0}+++{1}::::::::{3}******************{1}::::::::{2};;; {1} :::::::::::::{3}************{1}::::::::::::: {1} :::::::::::::::::::::::::::::::: {1} :::::::::::::::::::::::::: {1} :::::::::::::::::::: {1} :::::::::::: {1} :::::: colors: ansi: - yellow - yellow - yellow - white hex: - "#D6AE46" - "#AB5921" - "#C37C2E" - "#FFFFFF" chip: "#FFEFAF" icon: '\u{E61E}' Html: type: markup ascii: | {1} ## ## ###### ## ## ## {1} ## ## ## ### ### ## {1} ###### ## ## # ## ## {1} ## ## ## ## ## ## {1} ## ## ## ## ## ###### {0}((((((((((((((((((((((((((((((((((( {0}(((((((((((((((((/////////////((((( {0}(((((((((((((((((/////////////((((( {0}((((((( //((((( {0} (((((( //(((( {0} (((((( ((((((/////////////(((( {0} (((((( (((((/////////////(((( {0} (((((( ///(((( {0} ((((( ///((( {0} (((((((((((((((////// ///((( {0} (((((( (((((///// ///((( {0} (((((( ///((( {0} ((((((( /////(( {0} ((((((((((((((/////////////(( {0} ((((((((((((((//////((((((((( {0} ((((((((((((((( colors: ansi: - red - white chip: "#E34C26" icon: '\u{E736}' Idris: type: programming ascii: | {0} % {0} % {0} %&&& %% {0} %% %& {0}&%%%& % %% {0} %% %% {0} % %% {0} %%% %%& {0} %% %%% {0} % &%%% {0} %%%& {0} &%%% {0} %%%% {0} %%% {0} %%% {0} %%% {0} &%% {0} %%% colors: ansi: - red chip: "#B30000" Java: type: programming ascii: | {0} | {0} || {0} ||| {0} |||| || {0} ||||| |||| {0} |||| ||| {0} |||| ||| {0} ||| ||| {0} ||| ||| {0} || || {0} | | {1} #### # ## {1} ################ ## {1} # ## {1} ################ ### {1} {1} ############## {1}#### ####### # {1}##### #### {1} ##################### # {1} ### {1} ############### colors: ansi: - red - blue hex: - "#F44336" - "#1665C0" chip: "#B07219" icon: '\u{E738}' JavaScript: type: programming ascii: | {0}JSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJS {0}JSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJS {0}JSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJS {0}JSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJS {0}JSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJS {0}JSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJS {0}JSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJS {0}JSJSJSJSJSJSJSJSJ SJSJS JSJSJS {0}JSJSJSJSJSJSJSJSJ SJS JSJS {0}JSJSJSJSJSJSJSJSJ SJS JSJSJSJSJ {0}JSJSJSJSJSJSJSJSJ SJSJ SJSJSJSJ {0}JSJSJSJSJSJSJSJSJ SJSJSJ SJSJSJ {0}JSJSJSJSJSJSJSJSJ SJSJSJSJ JSJS {0}JSJSJSJSJSJSJSJSJ SJSJSJSJS JSJ {0}JSJSJSJSJS JS JSJS JSJ {0}JSJSJSJSJSJ SJSJSJ SJSJS {0}JSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJS {0}JSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJS colors: ansi: - yellow hex: - "#ECE653" chip: "#F1E05A" icon: '\u{F2EE}' Json: type: data ascii: | {0} `:+osyyyso+/:` {0} :smNNNmmmddddhhhmds: {0} .oNNNNNmmmddddhhhyyyym{1}MNs. {0} oNNNNNmmmddddhhhyyyysssh{1}MMMs` {0} .dNNNNmmmddmmmdyyyyysssoooh{1}MMMm. {0} `mNNNmmmmm{1}NMMMy-{0} .+ssoooo++N{1}MMMN. {0} yNNmmmdm{1}MMMMN- {0} .ooo+++/d{1}MMMMd {0}-Nmmmddm{1}MMMMM: {0} .+++///y{1}MMMMM- {0}+mmdddd{1}MMMMMm {0} /////:y{1}MMMMM+ {0}+ddddhd{1}MMMMMm {0} ///:::m{1}MMMMM+ {0}-ddhhhd{1}MMMMMM- {0} `/::::y{1}MMMMMM- {0} shhyyh{1}MMMMMMm- {0} `:::::h{1}MMMMMMh {0} .yyyyyN{1}MMMMMMMs.{0} `-:::/y{1}NMMMMMMm` {0} .osssh{1}MMMMMMMMMmhyyydNMMMMMMMMd. {0} :oood{1}MMMMMMMMMMMMMMMMMMMMMNo {0} `:++yN{1}MMMMMMMMMMMMMMMMMNs. {0} .-/ym{1}MMMMMMMMMMMMmy: {0} `-/oyhhhys+:` colors: ansi: - white - black chip: "#292929" icon: '\u{eb0f}' Jsonnet: type: programming ascii: | {0} . . {0} /{1}:{0}\ /{1}:{0}\ {0} /{1}:::{0}\ /{1}:::{0}\ {0} /{1}:::::{0}\ /{1}:::::{0}\ {0} /|\{1}:::::{0}/|\{1}:::::{0}/| {0} /{1}:{0}|#\{1}:::{0}/{1}.{0}|#\{1}:::{0}/{1}.{0}| {0} /{1}::{0}|##\{1}:{0}/{1}..{0}|##\{1}:{0}/{1}..{0}| {0}|\{1}::{0}|###|{1}...{0}|###|{1}...{0}| {0}|#\{1}:{0}|###|{1}...{0}|###|{1}...{0}| {0}|##\|###|{1}...{0}|###|{1}...{0}| {0}|#######|{1}..{0}/{1}:{0}\##|{1}..{0}/ {0}|#######|{1}.{0}/{1}:::{0}\#|{1}.{0}/ {0}|#######|/{1}:::::{0}\|/ {0} \#######\{1}:::::{0}/|\ {0} \#######\{1}:::{0}/{1}.{0}|{1}:{0}\ {0} \#######\{1}:{0}/{1}..{0}|{1}::{0}\ {0} |#######|{1}...{0}|{1}::{0}/| {0} |#######|{1}...{0}|{1}:{0}/{1}.{0}| {0} |#######|{1}...{0}|/{1}..{0}| {0} |###|\##|{1}..{0}/|{1}...{0}| {0} |###|{1}.{0}\#|{1}.{0}/#|{1}...{0}| {0} |###|{1}..{0}\|/##|{1}...{0}| {0} \##|{1}..{0}/ \##|{1}..{0}/ {0} \#|{1}.{0}/ \#|{1}.{0}/ {0} \|/ \|/ colors: ansi: - white - black chip: "#0064BD" Jsx: type: programming ascii: | {0}JSXJSXJSXJSXJSXJSXJSXJSXJSXJSXJSXJSX{1}JSX {0}JSXJSXJSXJSXJSXJSXJSXJSXJSXJSXJSXJS{1}XJSX {0}JSXJSXJSXJSXJSXJSXJSXJSXJSXJSXJSXJ{1}SXJSX {0}JSXJSXJSXJSXJSXJSXJSXJSXJSXJSXJSX{1}JSXJSX {0}JSXJSXJSXJSXJSXJSXJSXJSXJSXJSXJS{1}XJSXJSX {0}JSXJSXJSXJSXJSXJSXJSXJSXJSXJSXJ{1}SXJSXJSX {0}JSXJSXJSXJSXJSXJSXJSXJSXJSXJSX{1}JSXJSXJSX {0}JSXJSXJSXJSXJSXJSXJSXJSXJSXJS{1}XJSXJSXJSX {0}JSXJSXJSXJSXJSXJSXJSXJSXJSXJ{1}SXJSXJSXJSX {0}JSXJSXJSXJSXJSXJSXJSXJSXJSX{1}JSXJSXJSXJSX {0}JSXJSXJ SXJS XJSXJS{1}X{2}JSX{1}JSX{2}JSX{1}JSX {0}JSXJSXJ SXJ SXJSXJSXJ{1}SXJ{2}SXJ{1}S{2}XJS{1}XJSX {0}JSXJSXJ SXJS XJSXJSX{1}JSXJSX{2}JSX{1}JSXJSX {0}JSXJSXJ SXJSX JSXJS{1}XJSXJS{2}XJSXJ{1}SXJSX {0}JS XJ SXJSXJ SXJ{1}SXJSXJ{2}SXJ{1}S{2}XJS{1}XJSX {0}JSX JS XJS{1}XJSXJS{2}XJS{1}XJS{2}XJS{1}XJS {0}JSXJSXJSXJSXJSXJSXJS{1}XJSXJSXJSXJSXJSXJSX {0}JSXJSXJSXJSXJSXJSXJ{1}SXJSXJSXJSXJSXJSXJSX colors: ansi: - yellow - magenta - white hex: - "#ECE653" - "#B684D3" - "#FFFFFF" chip: "#F1E05A" icon: '\u{F2EE}' Julia: type: programming ascii: | {0} {2}_ {0} {1}_ {0}_ {3}_{2}(_){4}_ {0} {1}(_) {0}| {3}(_) {4}(_) {0} _ _ _| |_ __ _ {0} | | | | | | |/ _` | {0} | | |_| | | | (_| | {0} _/ |\__'_|_|_|\__'_| {0}|__/ colors: ansi: - white - blue - green - red - magenta chip: "#A270BA" icon: '\u{E624}' Jupyter: type: programming ascii: | {0} +%%%+ {0} $$$$$$$ {0} +%+ $$$$$$$ {0} $$$$$ {1}****** {0}*%%%* {0} *%* {1}**************** {1} ************************ {1} ******** ******** {1} *** *** {1} * {0}_ {1}* {0} _ _ _ _ __ _ _ | |_ ___ _ _ {0} | || | | || '_ \ | | | || __|/ _ \| '_| {0} | || |_| || |_) || |_| || |_ | __/| | {0} | | \__,_|| .__/ \__, | \__|\___||_| {0}/_/ |_| |___/ {1} * * {1} *** *** {1} ******** ******** {1} ************************ {1} **************** {0} +%%%+ {1}****** {0} $$$$$$$ {0} $$$$$$$ {0} *%%%* colors: ansi: - white - yellow - white hex: - "#FFFFFF" - "#FF700F" - "#9E9E9E" chip: "#DA5B0B" icon: '\u{E80F}' serialization: jupyter-notebooks Kotlin: type: programming ascii: | {0}KOTLIN{2}KOTLINKOTLINKO{1}TLINKOTLINKOTLINKOTL {0}KOTLINKO{2}TLINKOTLIN{1}KOTLINKOTLINKOTLINKO {0}KOTLINKOTL{2}INKOTL{1}INKOTLINKOTLINKOTLIN {0}KOTLINKOTLIN{2}KO{1}TLINKOTLINKOTLINKOTL {0}KOTLINKOTLIN{1}KOTLINKOTLINKOTLINKO {0}KOTLINKOTL{1}INKOTLINKOTLINKOTLIN {0}KOTLINKO{1}TLINKOTLINKOTLINKOTL {0}KOTLIN{1}KOTLINKOTLINKOTLINKO {0}KOTL{1}INKOTLINKOTLINKOTLIN {0}KO{1}TLINKOTLINKOTLINKOTL {1}KOTLINKOTLINKOTLINKO{2}TL {2}KO{1}TLINKOTLINKOTLIN{2}KOTLIN {2}KOTL{1}INKOTLINKOTL{2}INKOTLINKO {2}KOTLIN{1}KOTLINKO{2}TLINKOTLINKOTL {2}KOTLINKO{1}TLIN{0}K{2}OTLINKOTLINKOTLIN {2}KOTLINKOTL{0}INKOT{2}LINKOTLINKOTLINKO {2}KOTLINKO{0}TLINKOTLI{2}NKOTLINKOTLINKOTL {2}KOTLIN{0}KOTLINKOTLINK{2}OTLINKOTLINKOTLIN {2}KOTL{0}INKOTLINKOTLINKOT{2}LINKOTLINKOTLINKO {2}KO{0}TLINKOTLINKOTLINKOTLI{2}NKOTLINKOTLINKOTL colors: ansi: - blue - yellow - magenta chip: "#A97BFF" icon: '\u{E634}' Lean: type: programming ascii: | {0} ______ {0}| |\ /|\ | {0}| | \ / | \ | {0}| | \ / | \ | {0}| ______| \________/ | \ | {0}| | \ / | \ | {0}| | \ / | \ | {0}| | \ / | \ | {0}|____________| \/ | \| colors: ansi: - white chip: "#FFFFFF" Lisp: type: programming ascii: | {0} ............ {0} ********.............. {0} *************............. {0} ****************.............. {0} *******************...***......... {0} **...********...*****...***......... {0} ***...*******...******....***......... {0}****...******...*******....****......... {0}*****...****...*******.....*****........ {0}******...**...******.......******....... {0}*******......******.......***..***...... {0}********.....*****.......***....***..... {0}*********....****.......***......***.... {0} *********...****......***.......***... {0} *********...***.....***........***.. {0} *********...***................... {0} **************................ {0} *************............. {0} **************........ {0} ************ colors: ansi: - white chip: "#3FB68B" icon: '\u{E6B0}' LLVM: type: programming ascii: | {0}KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK {0}KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK {0}KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK {0}KKKKKKKKK" "KKKKKKKK {0}KKKKKKK KKKKKKKKKK "KKKKK {0}KKKKK KKKKKKKKKKKKKKK "KKK {0}KKKK KKKKKKKKKKKKKKKKK {0}KKKK KKKKKKKKKKKKKKKKK {0}KKKK KKKKKKKKKKKKKKKK {0}KKKK KKKKKKKKKKKKKK {0}KKKK KKKKKKKKKKKKK {0}KKKK ,KKKKKKKKKKKK {0}KKKKKK, , KKKKKKKKKKKK {0}KKKKKKKK KK, `KKKKKKKKKK {0}KKKKKKKKK KKKKKKKKKKKKKKKKK {0}KKKKKKKK, ,KKKKKKKKKKKKKKK {0} `KKKKKKKKKKKKKKKKKKKKKKK` {0} `KKKKKKKKKKKKKKKKKKK` {0} `KKKKKKKKKKKKKK` colors: ansi: - red hex: - "#98012E" chip: "#185619" icon: '\u{E823}' Lua: type: programming ascii: | {1} -- -- {1} -- --{0} @@@@ {1} -- {0}@@@@@@@@@@@ @@@@@@ {0} @@@@@@@@@@@@@@@@@ @@@@ {1} -- {0}@@@@@@@@@@@@@@{1}@@@@{0}@@@ {1}-- {1} -- {0}@@@@@@@@@@@@@@@{1}@@@@@@{0}@@@@ {1}-- {0} @@@@@@@@@@@@@@@@@{1}@@@@{0}@@@@@@ {1}-- {0}@@@{1}@@{0}@@@@@@@@@@@@@@@@@@@@@@@@ {1}-- {1}-- {0}@@@{1}@@{0}@@@@@@{1}@@{0}@@{1}@@{0}@@{1}@@@@@@{0}@@@@ {1}-- {0} @@@{1}@@{0}@@@@@@{1}@@{0}@@{1}@@{0}@{1}@@{0}@@@{1}@@{0}@@@@ {1}-- {0}@@@{1}@@{0}@@@@@@{1}@@{0}@@{1}@@{0}@@@{1}@@@@@{0}@@@@ {1}-- {1}-- {0}@@@{1}@@{0}@@@@@@{1}@@{0}@@{1}@@{0}@{1}@@@{0}@@{1}@@{0}@@@@ {1}-- {0} @@{1}@@@@@@@{0}@{1}@@@@@@{0}@{1}@@@@@@@@{0}@@ {1} -- {0}@@@@@@@@@@@@@@@@@@@@@@@@@ {1}-- {1} -- {0}@@@@@@@@@@@@@@@@@@@@@ {1}-- {0} @@@@@@@@@@@@@@@@@ {1} -- {0}@@@@@@@@@@@ {1}-- {1} -- -- {1} -- -- colors: ansi: - blue - white hex: - "#134074" - "#FFFFFF" chip: "#000080" icon: '\u{E620}' Makefile: type: programming ascii: | {0} _-`````-, ,- '- . {0} .' .- - | | - -. `. {0} /.' / `. \ {0}:/ : {1}_... ..._ {0}`` : {0}:: : {1}/._ .`:'_.._\. {0}|| : {0}:: `._ {1}./ ,` : \{0} . _.'' . {0}`:. {1}/ | -. \-. \\_{0} / {0} \:._ {1}_/ .' .{2}@{1}) \{2}@{1}) ` `\{0} ,.' {1} {0}'{1}_/,--' .- .\,-.`--`. {1} ,'/'' (( \ ` ) {1} /'/' \ `-' ( {1} '/'' `._,-----' {1} ''/' .,---' {1} ''/' ;: {1} ''/'' ''/ {1} ''/''/'' {1} '/'/' {1} `; colors: ansi: - white - yellow - red hex: - "#FFFFFF" - "#FAEC9A" - "#610000" chip: "#427819" icon: '\u{E673}' Markdown: type: prose ascii: | {0}####### {1} ,#####. .#####. {0} ### {1}########.######## {0} ### {1}################# {0} ### {1}`###############' {0} ### {1} `#############' {0} ### {1} `#########' {0} ### {1} `#####' {0}####### {1} `#' {0} {0}#### #### ### {0}##### ##### ### {0}######.###### ### {0}### ##### ### ### {0}### ### ### ####### {0}### # ### ##### {0}### ### ### {0}### ### # colors: ansi: - white - red hex: - "#FFFFFF" - "#FF0000" chip: "#083FA1" icon: '\u{E73E}' Modelica: type: programming ascii: | {0} ######### ######## ######### {0} ############ ########## ########### {0} ###### ######## ####### ###### {0} #### ######## ####### ###### {0} ### ####### ###### ##### {0} ## ###### ##### #### {0} ###### ##### ### {0} ##### #### ## {0} ##### #### {0} #### ### {1}*** {0} #### ## {1}******* {0} #### {1}********* {0} ### {1}********* {0} ## {1}******* {1} *** colors: ansi: - white - red hex: - "#FFFFFF" - "#FF0000" chip: "#de1d31" Nim: type: programming ascii: | {0} ++ {0} ++ ++++++ ++ {0} ++++++++++++++++++++++++++++ {0} ++++++++++++++++++++++++++++++ {0}++ ++++++++++++++++++++++++++++++++ ++ {0} ++++++++++++++++++++++++++++++++++++++ {0} +++++++++++ +++++++++++ {0} ++++++++ ++++++++ {0} +++++ +++++ {1} ? {0}++ ++ {1}? {1} ?? ?????? ?? {1} ??? ?????????? ??? {1} ???? ?????????????? ???? {1} ?????????????????????????????? {1} ???????????????????????????? {1} ?????????????????????????? {1} ?????????????????????? {1} ?????????????????? colors: ansi: - yellow - white chip: "#FFC200" icon: '\u{E677}' Nix: type: programming ascii: | {1} :::. {0}'::::: ::::' {1} ':::: {0}':::::. ::::' {1} :::: {0}'::::.::::: {1} ......:::::..... {0}:::::::: {1} :::::::::::::::::. {0}:::::: {1}::::. {1} :::::::::::::::::::: {0}:::::. {1}.::::' {0} ..... {0}::::' {1}:::::' {0} ::::: {0}'::' {1}:::::' {0} ......::::: {0}' {1}::::::::::. {0}::::::::::: {1}:::::::::::: {0} ::::::::: {1}.. {1}::::: {0} .:::: {1}.::: {1}::::: {0} .:::: {1}::::: {1}''''' {0}..... {0} :::: {1}':::::. {0}......:::::::::::::' {0} :: {1}::::::. {0}':::::::::::::::::' {1} {1}.:::::::: {0}':::::::::: {1} {1}.::::''::::. {0}'::::. {1} {1}.::::' ::::. {0}'::::. {1} {1}.:::: :::: {0}'::::. colors: ansi: - cyan - blue chip: "#7E7EFF" icon: '\u{f313}' Nushell: type: programming ascii: | {0} _ __ {0}| '_ \ {1}__ {0}| | | | {1}\ \ {0}| | |_| _ {1} \ \ {0}|_| _ | | {1} / / {0} | | | | {1}/_/ {0} | |_| | {0} \__,_| colors: ansi: - green - white chip: "#4E9906" ObjectiveC: type: programming ascii: | {0}888 888 {0}8 8888 8 8 8888 8 {0}8 8 8 8 8 88 8 {0}8 8 8 8 8 8 8 {0}8 8 8 8 888 8 8 8 {0}8 8 8 88 8 8 ==== 8 8 {0}8 8 8 8 8 8 8 8 8 {0}8 8 8 88 8 8 8 88 8 {0}8 8888 8 888 8 88888 8 {0}888 8 888 {0} 8 {0} 88Y colors: ansi: - cyan - blue chip: "#438EFF" icon: '\u{E84D}' serialization: objective-c OCaml: type: programming ascii: | {0}/////////////////////////////////////// {0}/////////////////////////////////////// {0}/////////////////////////////////////// {0}/////////////////////////////////////// {0}/////////////////////////////////////// {0}/// \//// \/////////////////////// {0}// // ///////// .//////// {0}/ /////// \///// {0} ///// ////////// {0} /////////// {0} //////////// {0} // /////////////// {0} ///////// /// //////////////////// {0}///////// ////// //////////////////// {0}//////// /////// //////////////////// {0}/////// //////// //////////////////// {0}////// ///////// //////////////////// colors: ansi: - yellow chip: "#3BE133" icon: '\u{E67A}' Odin: type: programming ascii: | {0} @@@@@@@@@ {0} @@@@ @@@ @@@ {0} @@@@ @@@ @@@@@@ {1} @@@@ @@@ @@@ @@@@ {1} @@@ @@@ @@@ @@@ {1}@@@ @@@ @@@ @@@ {2}@@@ @@@ @@@ @@@ {2}@@@ @@@ @@@ @@@ {2}@@@ @@@ @@@ @@@ {3}@@@ @@@ @@@ @@@ {3} @@@ @@@ @@@ @@@ {3} @@@@@@ @@@ @@@@ {4} @@@ @@@ @@@@ {4} @@@ @@@@ {4} @@@@@@@@@@ colors: ansi: - blue - blue - blue - blue - blue hex: - "#265A99" - "#3473BE" - "#3F88DD" - "#4797F3" - "#499AF7" chip: "#60AFFE" OpenScad: type: programming ascii: | {0} ________ {0} .:------------: {1}... {0} .-+= =+=- {1}:. {0} :+*** +**=: {1}.:. {0} =*****+ +*****= {1}-. {0} +**********+++++++**********+ {1}- {0} =*****************************= {1}- {0} .*+==+********************+++***. {1}.: {1} .::-:. {0}.-+***************- =*-{1}.. {1}-. .:. {0}-************= *. {1}= .:. {0}:**********- :+ {1}= :. {0}=********= .+. {1}.- - {0}.********- :=. {1} .-. : {0}=********+. .:=- {1} :: .-{0}:=************++==: {1} ·...· {0}.-=++*****++=-. {0} --------- colors: ansi: - yellow - white hex: - "#FFFA56" - "#F6C59A" chip: "#E5CD45" icon: '\u{F34E}' Org: type: prose ascii: | {2} j {2} eL {0} Q {2}kD {0} Nt{1}yew{2}kQ{0}y {1} :r/2K{0}@Q@@@#N@@Qmir {1} -cDBQB6XXe{0}Q@@@@@@@@@@@@@Q@@g {1} =NQQQR6XwPee{0}6@@@@@@@@@@@QdRm {1}?#QB#HKXej{0}D@QQRNkPD9| {1}SQNHDXwmXq{0}@@@QDR {1}=D6XwmSm{0}D@Q@@QDH {1} tXaZe{0}H@QQ@@@@QRdz {1} u{0}QRQ@@@@@@@@@QDDd {0} B@@@@@@@@@@@QDHDd {0} Syz*:'--'~;\oM colors: ansi: - green - red - white chip: "#77AA99" icon: '\u{E633}' Oz: type: programming ascii: | {0} ooooooooo {0} oooooo{1}zzz{0}oooooo {0} oooooo{1}zzzzzz{0}ooooooo {0} oooooo{1}zzz{0}ooo{1}zzz{0}oooooooo {0} ooooooooooooooo{1}zzz{0}ooooooooo {0} oooo oooooooooo{1}zzz{0}ooo{1}zzz{0}oooo {0} ooo oooo ooooooo{1}zzzzzz{0}oooooooo {0}ooo oooooo ooooo{1}zzz{0}oooooooooooo {0}ooo oooooo ooooooooooo oooooo {0}oooo oooooo oooooooo ooooooo {0} ooooo oooo oooooo ooo oooooooo {0} ooooooo ooooooooooooooo oooooooo {0} ooooooooooo{1}zzzz{0}oooooooooo ooo oo {0} ooooooo{1}zzz{0}oooo{1}zzz{0}ooooooo oooo {0} ooooo{1}zzz{0}oooooo{1}zzzz{0}ooooo ooooo {0} oooo{1}zzzz{0}oooooo{1}zzzz{0}ooooooooo {0} oooo{1}zzzz{0}oooooo{1}zzz{0}oooooo {0} ooooo{1}zzz{0}oooo{1}zzz{0}ooo {0} ooooooo{1}zzzz{0}oooo {0} ooooooooo colors: ansi: - yellow - white hex: - "#FCAF3E" - "#FFFFFF" chip: "#FAB738" Pascal: type: programming ascii: | {0}█████{1}╗ {0}████{1}╗ {0}█████{1}╗ {0}████{1}╗ {0}████{1}╗ {0}██{1}╗ {0}██{1}╔═{0}██{1}╗{0}██{1}╔═{0}██{1}╗{0}██{1}╔══╝{0}██{1}╔══╝{0}██{1}╔═{0}██{1}╗{0}██{1}║ {0}█████{1}╔╝{0}██████{1}║{0}█████{1}╗{0}██{1}║ {0}██████{1}║{0}██{1}║ {0}██{1}╔══╝ {0}██{1}╔═{0}██{1}║╚══{0}██{1}║{0}██{1}║ {0}██{1}╔═{0}██{1}║{0}██{1}║ {0}██{1}║ {0}██{1}║ {0}██{1}║{0}█████{1}║╚{0}████{1}╗{0}██{1}║ {0}██{1}║{0}█████{1}╗ {1}╚═╝ ╚═╝ ╚═╝╚════╝ ╚═══╝╚═╝ ╚═╝╚════╝ colors: ansi: - blue - white chip: "#E3F171" Perl: type: programming ascii: | {0} ###### {0} ### ######### {0} ######## ########## {0}######### ############ {0} ###### ############### {0} ####### ################## {0} ####### ################### {0} ############################ {0} ############################# {0} ########################### ## {0} ######################### ## {0} ################### ### # {0} ##### #### ### ### # {0} #### #### ### ## {0} #### ### ### # {0} ## ### ### # {0} ## ## ## # {0} ## # # # {0} # ## # {0} # # # # {0} # ### ## ## {0} ## colors: ansi: - cyan chip: "#0298C3" icon: '\u{E67E}' Php: type: programming ascii: | {0} ################ {0} ##########{1}/ |{0}############## {0} #############{1}| |{0}################# {0} #####{1}/ __ \| __ \/ __ \{0}### {0}######{1}| |{0}##{1}| || |{0}##{1}| || |{0}##{1}| |{0}#### {0}######{1}| |{0}##{1}/ || |{0}##{1}| || |{0}##{1}/ |{0}#### {0} #####{1}| ____ /|__|{0}##{1}|__|| ____ /{0}### {0} ###{1}| |{0}################{1}| |{0}####### {1} |_ /{0}################{1}|_ /{0}#### {0} ################ colors: ansi: - blue - white hex: - "#777BB3" - "#FFFFFF" chip: "#4F5D95" icon: '\u{f031f}' PowerShell: type: programming ascii: | {0} ######################### {0} ####{1}####{0}################# {0} ######{1}####{0}############### {0} ########{1}####{0}############# {0} ##########{1}####{0}########### {0} #########{1}####{0}############ {0} ########{1}####{0}############# {0} #######{1}####{0}############## {0} ######{1}####{0}#####{1}######{0}#### {0}######################### colors: ansi: - blue - white hex: - "#316CB9" - "#FFFFFF" chip: "#012456" icon: '\u{f0a0a}' Processing: type: programming ascii: | {0} PPPPPPPPPPPP {0} PPPPPPPPPPPPPPPPPPPP {0} PPPPPPPPPPPP{1}PPPPPP{0}PPPPPP {0} PPPPPPPPPPPPP{1}P{0}PPPP{1}PP{0}PPPPPP {0} PPPPPPPPPPPPPPPPPPP{1}PP{0}PPPPPPP {0} PPPPPPPPPPPPPPPPPPP{1}PP{0}PPPPPPPPP {0}PPPPPPPPPPP{1}PPPP{0}PP{1}PPPPP{0}PPPPPPPPPP {0}PPPPPPPPPPPP{1}PPP{0}PPPPPP{1}PP{0}PPPPPPPPP {0}PPPPPPPPPPPP{1}PPP{0}PPPPPP{1}PP{0}PPPPPPPPP {0}PPPPPPPPPPPP{1}PPP{0}PP{1}PPPPP{0}PPPPPPPPPP {0}PPPPPPPPPPPP{1}PPP{0}PPPPPPPPPPPPPPPPP {0} PPPPPPPPPPP{1}PPP{0}PPPPPPPPPPPPPPPP {0} PPPPPPPPPP{1}PPP{0}PPPPPPPPPPPPPPP {0} PPPPPPP{1}PPPPPPP{0}PPPPPPPPPPPP {0} PPPPPPPPPPPPPPPPPPPPPPPP {0} PPPPPPPPPPPPPPPPPPPP {0} PPPPPPPPPPPP colors: ansi: - blue - white hex: - "#505050" - "#FFFFFF" chip: "#0096D8" Prolog: type: programming ascii: | {0} ############ # {0} ################# #### {0} ################### ###### {0} ##################### ####### {0} ###################### ######## {0} ####### ####### ######### {0}###### ### ##### ########## {0}##### #### # #### ########## {0}##### ##### ## #### ########## {0}##### ######### #### ########## {0}##### ##### ####### ######## {0} #### ########### ## {0} ### ########################### {0} # ########################## {0} ######################## {0} ###################### {0} ################ colors: ansi: - white chip: "#74283C" icon: '\u{E7A1}' Protobuf: type: programming ascii: | {0} ;;;;;;;; {2}:::::::: {0} ;;;;;;;; {2}:::::::: {0} ;;;;;;;; {2}:::::::: {1} :{0};;;;;;; {2}:::::::: {1} :::{0};;;;; {2}:::::::: {1} :::::{0};;; {2}:::::::: {1}:::::::{0}; {3};{2}::::::: {1}:::::::: {3};;;{2}::::: {1} :::::::: {3};;;;;{2}::: {1} :::::::: {3};;;;;;;{2}: {1} :::::::: {3};;;;;;;; {1} :::::::: {3};;;;;;;; {1} :::::::: {3};;;;;;;; colors: ansi: - red - blue - green - yellow chip: "#74283C" serialization: protocol-buffers PureScript: type: programming ascii: | {0} \\\\\\\\\\\\\\ \\\\\ {0} \\\\\\\\\\\\\\ \\\\\ {0} ///// \\\\\ {0} ///// ////////////// ///// {0}///// ////////////// ///// {0}\\\\\ ///// {0} \\\\\ \\\\\\\\\\\\\\ {0} \\\\\ \\\\\\\\\\\\\\ colors: ansi: - white chip: "#1D222D" icon: '\u{E630}' Python: type: programming ascii: | {0} ========= {0} =============== {0} ================= {0} === ============== {0} =================== {0} ========== {0} ========================== {1}======= {0} ============================ {1}======== {0}============================= {1}========= {0}============================ {1}========== {0}========================== {1}============ {0}============ {1}========================== {0}========== {1}============================ {0}========= {1}============================= {0} ======== {1}============================ {0} ======= {1}========================== {1} ========== {1} =================== {1} ============== === {1} ================= {1} =============== {1} ========= colors: ansi: - blue - yellow hex: - "#2F69A2" - "#FFD940" chip: "#3572A5" icon: '\u{E73C}' Qml: type: programming ascii: | {0}**************************************** {0}**************************************** {0}**************************************** {0}**************************************** {0}**************************************** {0}*******{1}####{0}*****{1}###{0}*****{1}###{0}**{1}###{0}******** {0}*****{1}########{0}***{1}####{2},{0}**{1}####{2},{0}*{1}###{2},,{0}****** {0}****{1}###{2},,,,{1}###{2},{0}*{1}#####{2},{1}#####{2},,{1}###{2},,,,{0}**** {0}***{1}###{2},,,,,,{1}###{2},{1}###########{2},,{1}###{2},,,,,,{0}** {0}***{1}###{2},,,,,,{1}###{2},{1}###{2},{1}###{2},{1}###{2},,{1}###{2},,,,,,,{0}* {0}***{1}###{2},,,,,,{1}###{2},{1}###{2},,{1}#{2},,{1}###{2},,{1}###{2},,,,,,,, {0}****{1}###{2},,,,{1}###{2},,{1}###{2},,,,,{1}###{2},,{1}###{2},,,,,,,, {0}*****{1}########{2},,,{1}###{2},,,,,{1}###{2},,{1}########{2},,, {0}*******{1}####{2},,,,,{1}###{2},,,,,{1}###{2},,{1}########{2},,, {0}********{2},{1}#####{2},,,,,,,,,,,,,,,,,,,,,,,,,, {0}*********{2},,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, {0}***********{2},,,,,,,,,,,,,,,,,,,,,,,,,,,,, {0}*************{2},,,,,,,,,,,,,,,,,,,,,,,,,,, {0}***************{2},,,,,,,,,,,,,,,,,,,,,,,,, {0}*****************{2},,,,,,,,,,,,,,,,,,,,,,, colors: ansi: - green - white - green hex: - "#80C342" - "#FFFFFF" - "#4D7528" chip: "#44A51C" R: type: programming ascii: | {0} .,,,,,,,,,,,,, {0} ,,,,,,,,,,,,,,,,,******** {0} ,,,,,,,,,,,,,,,,,************** {0} ,,,,,,,,,,,, ***** {0} ,,,,,,,,, {1}RRRRRRRRRRRRRRRR {0}*** {0},,,,,,,,, {1}RRRRRRRRRRRRRRRRRRR {0}*** {0},,,,,,,, {1}RRRRRRRRRRRRRRRRRRRR {0}// {0},,,,,,* {1}RRRRRRR RRRRRRR {0}// {0},,,***** {1}RRRRRRR RRRRRRR {0}// {0} ******** {1}RRRRRRRRRRRRRRRRRR {0}// {0} ********* {1}RRRRRRRRRRRRRR {0}// {0} **********{1}RRRRRRR RRRRRRR {0} *******{1}RRRRRRR RRRRRRR {1} RRRRRRR RRRRRRRR colors: ansi: - white - blue chip: "#198CE7" icon: '\u{E68A}' Racket: type: programming ascii: | {0} {2}.:--::////::--.` {0} {1}`/yNMMNho{2}////////////:. {0} {1}`+NMMMMMMMMmy{2}/////////////:` {0} `-:::{1}ohNMMMMMMMNy{2}/////////////:` {0} .::::::::{1}odMMMMMMMNy{2}/////////////- {0} -:::::::::::{1}/hMMMMMMMmo{2}////////////- {0} .::::::::::::::{1}oMMMMMMMMh{2}////////////- {0}`:::::::::::::{1}/dMMMMMMMMMMNo{2}///////////` {0}-::::::::::::{1}sMMMMMMmMMMMMMMy{2}//////////- {0}-::::::::::{1}/dMMMMMMs{0}:{1}+NMMMMMMd{2}/////////: {0}-:::::::::{1}+NMMMMMm/{0}:::{1}/dMMMMMMm+{2}///////: {0}-::::::::{1}sMMMMMMh{0}:::::::{1}dMMMMMMm+{2}//////- {0}`:::::::{1}sMMMMMMy{0}:::::::::{1}dMMMMMMm+{2}/////` {0} .:::::{1}sMMMMMMs{0}:::::::::::{1}mMMMMMMd{2}////- {0} -:::{1}sMMMMMMy{0}::::::::::::{1}/NMMMMMMh{2}//- {0} .:{1}+MMMMMMd{0}::::::::::::::{1}oMMMMMMMo{2}- {0} {1}`yMMMMMN/{0}:::::::::::::::{1}hMMMMMh. {0} {1}-yMMMo{0}::::::::::::::::{1}/MMMy- {0} {1}`/s{0}::::::::::::::::::{1}o/` {0} ``.---::::---..` colors: ansi: - red - white - blue chip: "#3C5CAA" Raku: type: programming ascii: | {0} +@8DM#8W, {0}#DM"{1},ypy,{0}"8# {0}DDU {1}8M]N8u{0} DM {0}8DD {1}TMD8M,{0}8M {4}8 {0} 8D#=e@8MM^ {4}8 {0} *MDw {4},.,+#M` {0} "8# {0},e88DDDD8m, {0} "8 {3}x33#, {0}z8D#M`9Dw "9DW {3} JE E {2}BBW. {0}DM {1}p#Kw {0}D8 {0}JDM {1} #pp#pr {3} JRFMy{2}#EEF{3}y#Rr, {0}DM{1} MD]8 {0}9DM {4}`N {1}Z#{0}8#D]{1}D# {2}EE#EEEEE{3}`EW E {0}8M,{1}"RM`{0} 8DM {4}D {1}88{0}8]D]{1}D8 {2}EEM{1}#{2}EEE{1}E{2}Bp{3}TFF^ {0}*M888#` {4}#M {1}*#88EE8 {2} RRk{1}8BMM{2}#EEE, {4}'^' {1} `` {2}'"F*FFF* {1},yw, {1} ,#]{0}[D8{1}8W {1} k8{0}]DDN8{1}8L {1} '8E{0}$DE8{1}8M {1} R#E#R^ colors: ansi: - blue - red - yellow - white - green hex: - "#5B00FD" - "#FF005E" - "#F3FF27" - "#FFFFFF" - "#00FF39" chip: "#0000FB" Razor: type: markup ascii: | {0} @ {0} @ @@ {0} @@@@ @@@@ {0} @@@@@@@@@@@@@@@@@@@@ @@@@@@ {0} @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ {0} @@@@ @@@@@@@@@@@@@@@@ {0} @@@ @@@@@@@@@ @@@@@@@@@@@@@@ {0} @@@ @@@@@@@@@@@@@@@ @@@@@@@@@@@@ {0} @@@ @@@@ @@@@ @@@@@@@@@@ {0}@@@ @@@ @@@@@@ @@@@ @@@@@@@@ {0}@@@ @@ @@@@@@@ @@@@ @@@@@@@ {0}@@@ @@@ @@@@@@ @@@@ @@@@@@ {0} @@@ @@@ @@ @@@@@ {0} @@@ @@@@@ @@ @@@@@ {0} @@@ @@@@@@@@@@@@@@@@@@@ @ {0} @@@ @@@@@@@@@ @@ {0} @@@@@ @@@@@ {0} @@@@@@@@@@@@@@@@ colors: ansi: - magenta hex: - "#5c2994" chip: "#512be4" Renpy: type: programming ascii: | {0} ++++++ {0} ++++++++++ {0} ++++++++++++ {0} ++++++++++++++ {0} ++++++++++++++++ {0} +++++++++++++{1}***{0}+++ {0} +++++++{1}*********** {0} +++++{1}************** {0}+++{1}***************** {0}++{1}********{2}#{1}********** {1} *****{2}#{1}*{2}#{1}*{2}#{1}****{2}#{1}*{2}#{1}*** {1} *****{2}#{1}*{2}###{1}*{2}#{1}**{2}#{1}*{2}#{1}*** {1} *****{2}##########{1}*{2}#{1}*** {1} *****{2}##{3}**{2}####{3}**{2}##{1}*** {1} *****{2}##{3}**{2}####{3}**{2}##{1}*** {1} *****{2}############{1}*** {1} *****{2}#####{5}--{2}####{1}*** {1} **{4}#####{2}#######{1}** {4} #{5}**{4}#{5}**{4}#{2}###{4}#### {4} #{5}**{4}#{5}**{4}#{2}###{4}###### {4} ##{5}*{4}#{5}*{4}##{6}++++{4}###### {4} #####{6}++++++{4}##### {4} ###{6}++++++++{4}#### {6} +++++++++++{4}#### {6} ++++++++++{4}#### colors: ansi: - white - red - white - blue - yellow - white - magenta hex: - "#EADBCC" - "#FF7F7F" - "#FBEEE2" - "#495F8E" - "#FAE45A" - "#FFFFFF" - "#B5A396" chip: "#FF7F7F" icon: '\u{E88D}' Ruby: type: programming ascii: | {0} -+sdmhmMMhyhNMMddm` {0} .smdy+:` `-smmNy/ :h\ {0} -yNs. mmhmo. Md {0} -hNo` oM- .oNh: :s {0} :dm+` .Ns `/dmo.d {0} +Mo` hN yMMM {0} `sN/ /dMmsssoo++///NM {0} `hN- +md/sM. hNM {0} .dm. +mh: .Ns .dm+M {0} +My .oNy- sM. :Nd.+M {0} +MM+ .:/sNd- .Ns sNo sM {0}`+MyMyhdddysmMoydmhs+:smdsM.+Nh- hN {0}`+M.MM:` -Mo hMNm/ md {0}`+M hm. dm` `+Nmdm+ My {0}`/M: md` /M/ -sNy: -yNs. .Mo {0} `Nh Nh`Nh :smd+. .sNyoM/ {0} `h:mh:MmNss:+sdNds:-::///++oosyN- colors: ansi: - red hex: - "#F30301" chip: "#701516" icon: '\u{E739}' Rust: type: programming ascii: | {0} R RR RR {0} R RRRRRRRR R R {0} R RR R RRRRRRRRRRRRR R RR {0}rR RRR R RRRRRRRRRRRRRRRRR R RRR R {0}RRR RR RRRRRRRRRRRRRRRRRRRRRRR RRRRR {0} RRRRR RRRRRRRRRRRRRRRRRRRRRRRR RRRR {0} RRR RRRRRRRRRRRRRRRRRRRRRRRRRRRR RR {0} R RRRRRRRRRR{1}= {0}RR{1} = {0}RRRRRRRRRRR {0} RRRRRRRRRRRR{1}= {0}RR{1} = {0}RRRRRRRRRR {0} RRRRRRRRRRR RR RRRRRRRRRR {0} RR==RRRRRRRRRRRRRRRRRRRRRR===RR {0} RR = ==RRRRRRR RRRRRR== = RR {0} RR = =========== = RR {0} RR R {0} R R {0} R colors: ansi: - red - white hex: - "#E43717" - "#FFFFFF" chip: "#DEA584" icon: '\u{E7A8}' Sass: type: markup ascii: | {0} ,wppbbbbbp, {0} ,wpb@KP"``` ``"T@b {0} ,pb@P"` @@ {0} ,b@P` /@P {0} p@b` ,bK` {0}{@@ 'w, ,,wpbP*` {0} 0@b ```` ,pp ;@@ {0} "0bw ,bPK ,K@L /PT@ {0} "0b, ,,pbP @b .b Tb{" $bP"""*Tb, {0} ,/b@P &@ 0@M.b ,@K ,P @L `b {0} ,pb" Ib @@ &h@bP ,pCpP bb*` /` {0} p@` ,@` `bb` T" ""` {0} @@w,pbK` {0} `***^ colors: ansi: - magenta hex: - "#CD6799" chip: "#A53B70" icon: '\u{E74B}' Scala: type: programming ascii: | {0} + {0} +++ {0} +++++++++++++++ {0}+++++++++++++++++++++++++ {0}+++++++++++++++++++++++++ {0}+++++++++++++++++++++++++ {0}+++++++++++++++++{1}------- {0}+++{1}-------------------{0}+++ {1} ---{0}++++++++++++++ {0}+++++++++++++++++++++++++ {0}+++++++++++++++++++++++++ {0}+++++++++++++++++++++++++ {0}+++++++++++++++++{1}------- {0}+++{1}-------------------{0}+++ {1} ---{0}++++++++++++++ {0}+++++++++++++++++++++++++ {0}+++++++++++++++++++++++++ {0}+++++++++++++++++++++++++ {0}+++++++++++++++ {0}+++ colors: ansi: - red - red hex: - "#DF3F3D" - "#7F0C1D" chip: "#C22D40" icon: '\u{E737}' Scheme: type: programming ascii: | {0} //// {0} // // {0} / // {0} // {0} // {0} // {0} //// {0} /// // {0} /// // {0} /// // {0} /// // / {0} /// // // {0} /// //// colors: ansi: - white hex: - "#555555" chip: "#1E4AEC" icon: '\u{E6B1}' Sh: type: programming ascii: | {0} ___ ___ ___ {0} #### #### #### {0} #### #### #### {0} _____####______####___ #### {0} ####################### #### {0} ####################### #### {0} #### #### #### {0} #### #### #### {0} ____####______####____ #### {0} ####################### #### {0}####################### ___ {0} #### #### #### {0} #### #### #### {0} #### #### #### colors: ansi: - green chip: "#89E051" icon: '\u{f1183}' serialization: shell Slint: type: markup ascii: | {0} s {0} ss {0} sss {0} ssss {0} ssss {0} sssss {0} ssssss {0} ssssssss {0}sssssssss s {0} sssssss sss {0} sssss sssss {0} sss sssssss {0} s sssssssss {0} ssssssss {0} ssssss {0} sssss {0} ssss {0} ssss {0} sss {0} ss {0} s colors: ansi: - blue hex: - "#2379F4" chip: "#2379F4" Solidity: type: programming ascii: | {0}MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM {0}MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM {0}MMMMMMMMMMMM{2}SS{3}SSSSSSSSSS{4}SS{0}MMMMMMMMMMMM {0}MMMMMMMMMMM{2}SSSS{3}SSSSSSSS{4}SSSS{0}MMMMMMMMMMM {0}MMMMMMMMMM{2}SSSSSS{3}SSSSSS{4}SSSSSS{0}MMMMMMMMMM {0}MMMMMMMMM{2}SSSSSSSS{3}SSSS{4}SSSSSSSS{0}MMMMMMMMM {0}MMMMMMMM{2}SSSSSSSSSS{3}SS{4}SSSSSSSSSS{0}MMMMMMMM {0}MMMMMMMM{1}SSSSSSSSSS{0}MMMMMMMMMMMMMMMMMMMM {0}MMMMMMMMM{1}SSSSSSSS{0}MMMMMMMMMMMMMMMMMMMMM {0}MMMMMMMMMM{1}SSSSSS{0}MMMMMMMM{1}SS{0}MMMMMMMMMMMM {0}MMMMMMMMMMM{1}SSSS{0}MMMMMMMM{1}SSSS{0}MMMMMMMMMMM {0}MMMMMMMMMMMM{1}SS{0}MMMMMMMM{1}SSSSSS{0}MMMMMMMMMM {0}MMMMMMMMMMMMMMMMMMMMM{1}SSSSSSSS{0}MMMMMMMMM {0}MMMMMMMMMMMMMMMMMMMM{1}SSSSSSSSSS{0}MMMMMMMM {0}MMMMMMMM{4}SSSSSSSSSS{3}SS{2}SSSSSSSSSS{0}MMMMMMMM {0}MMMMMMMMM{4}SSSSSSSS{3}SSSS{2}SSSSSSSS{0}MMMMMMMMM {0}MMMMMMMMMM{4}SSSSSS{3}SSSSSS{2}SSSSSS{0}MMMMMMMMMM {0}MMMMMMMMMMM{4}SSSS{3}SSSSSSSS{2}SSSS{0}MMMMMMMMMMM {0}MMMMMMMMMMMM{4}SS{3}SSSSSSSSSS{2}SS{0}MMMMMMMMMMMM {0}MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM {0}MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM colors: ansi: - white - black - black - black - black hex: - "#FFFFFF" - "#2E2E2E" - "#1A1A1A" - "#333333" - "#515151" chip: "#AA6746" icon: '\u{E8A6}' Sql: type: data ascii: | {0} _..------.._ {0}.-~ ~-. {0}| | {0}|"-..________..-"| {0}| | {1} ____ ___ _ {0}| | {1}/ ___| / _ \| | {0}|"-..________..-"| {1}\___ \| | | | | {0}| | {1} ___) | |_| | |___ {0}| | {1}|____/ \__\_|_____| {0}|"-..________..-"| {0}| | {0}| | {0} "-..________..-" colors: ansi: - cyan - yellow chip: "#E38C00" icon: '\u{E737}' Svelte: type: markup ascii: | {0}SSSSSSSSSSSSSSSSSS{1}sssssssssss{0}SSSSSSSS {0}SSSSSSSSSSSSSSS{1}sssssssssssssssss{0}SSSSS {0}SSSSSSSSSSS{1}sssssssssss{0}SSSS{1}ssssssss{0}SSS {0}SSSSSSSS{1}ssssssssss{0}SSSSSSSSSSS{1}sssssss{0}S {0}SSSSS{1}sssssssss{0}SSSSSSSSSSSSSSSSS{1}sssss{0}S {0}SSS{1}ssssssss{0}SSSSSSSSSS{1}sssss{0}SSSSSS{1}ssss{0}S {0}S{1}sssssss{0}SSSSSSSSSS{1}sssssssss{0}SSSSS{1}ssss{0}S {0}S{1}sssss{0}SSSSSSSSS{1}sssssssssssssssssssss{0}S {0}S{1}sssss{0}SSSSSS{1}ssssssss{0}SSSSSS{1}ssssssssss{0}S {0}S{1}sssss{0}SSSSS{1}ssssss{0}SSSSSSSSSSSS{1}ssssss{0}SS {0}S{1}sssss{0}SSSSSSSSSSSSSSSSSSSSSSSSS{1}sssss{0}S {0}SS{1}ssssss{0}SSSSSSSSSSSS{1}ssssss{0}SSSSS{1}sssss{0}S {0}S{1}ssssssssss{0}SSSSSS{1}ssssssss{0}SSSSSS{1}sssss{0}S {0}S{1}sssssssssssssssssssss{0}SSSSSSSSS{1}sssss{0}S {0}S{1}ssss{0}SSSSS{1}sssssssss{0}SSSSSSSSSS{1}ssssss{0}SS {0}S{1}ssss{0}SSSSSS{1}sssss{0}SSSSSSSSSS{1}ssssssss{0}SSS {0}S{1}sssss{0}SSSSSSSSSSSSSSSSS{1}sssssssss{0}SSSSS {0}S{1}sssssss{0}SSSSSSSSSSS{1}ssssssssss{0}SSSSSSSS {0}SSS{1}ssssssss{0}SSSS{1}sssssssssss{0}SSSSSSSSSSS {0}SSSSS{1}sssssssssssssssss{0}SSSSSSSSSSSSSSS {0}SSSSSSSS{1}sssssssssss{0}SSSSSSSSSSSSSSSSSS colors: ansi: - red - white hex: - "#FF3C00" - "#FFFFFF" chip: "#FF3E00" icon: '\u{E697}' Svg: type: data ascii: | {0} ...... {0} ....{1}--{0}.... {0} .... {0}...{1}------{0}... {0}.... {0} ............{1}------{0}............ {0} ...{1}-----{0}......{1}----{0}......{1}-----{0}... {0} ...{1}------{0}.....{1}----{0}.....{1}------{0}... {0} ...{1}--------{0}...{1}----{0}...{1}--------{0}... {0} .....{1}-------{0}.{1}----{0}.{1}-------{0}..... {0} ..........{1}----------------{0}.......... {0} ...{1}---{0}.......{1}------------{0}.......{1}---{0}... {0}...{1}----------------------------------{0}... {0}...{1}----------------------------------{0}... {0} ...{1}---{0}.......{1}------------{0}.......{1}---{0}... {0} ..........{1}----------------{0}.......... {0} .....{1}-------{0}.{1}----{0}.{1}-------{0}..... {0} ...{1}--------{0}...{1}----{0}...{1}--------{0}... {0} ...{1}------{0}.....{1}----{0}.....{1}------{0}... {0} ...{1}-----{0}......{1}----{0}......{1}-----{0}... {0} ............{1}------{0}............ {0} .... {0}...{1}------{0}... {0}.... {0} ....{1}--{0}.... {0} ...... colors: ansi: - white - yellow hex: - "#FFFFFF" - "#EBA71F" chip: "#FF9900" icon: '\u{f0721}' Swift: type: programming ascii: | {0} : {0} :: {1} ::: {1} : :::: {2} : : :::: {2} : :: ::::: {3} :: ::: ::::: {3} ::: ::: :::::: {4} ::: ::: ::::::: {4} :::: :::: ::::::: {5} ::::::::::: :::::::: {5} ::::::::::: ::::::::: {5} :::::::::::::::::::::: {6} ::::::::::::::::::::: {6} ::::::::::::::::::: {6}: ::::::::::::::::: {7} :: :::::::::::::: {7} :::: :::::::::::::::: {7} :::::::::::::::::::::::::::::::::: {8} ::::::::::::::::::::::::::::::::: {8} ::::::::::::::::::::::::::::::: {8} :::::::::::::::::::::: ::::: {9} .::::::::::::::. :: {9} colors: ansi: - red - red - red - red - red - red - red - red - red - red hex: - "#F88134" - "#F97732" - "#F96D30" - "#FA632E" - "#FA592C" - "#FB502A" - "#FB4628" - "#FC3C26" - "#FC3224" - "#FD2822" chip: "#F05138" icon: '\u{E755}' SystemVerilog: type: programming ascii: | {0} _.._ _.._ _.._ _.._ {0} _.._ _.._ _.._ _.._ {0} ................................. {0}. {1}---- {0}. {0}. {1}-------------- {0}. {0}. {1}---- --------- {0}. {0}. {1}--- ----- {0}. {0}. {1}- ##### # # ----- {0}. {0}. {1}# # # # {0}. {0}. {1}# # # {0}. {0}. {1}##### # # {0}. {0}. {1}# # # {0}. {0}. {1}# # # # {0}. {0}. {1}----- ##### # - {0}. {0}. {1}----- --- {0}. {0}. {1}--------- ---- {0}. {0}. {1}-------------- {0}. {0}. {1}---- {0}. {0} ................................. {0} _.._ _.._ _.._ _.._ {0} _.._ _.._ _.._ _.._ colors: ansi: - blue - white chip: "#DAE1C2" icon: '\u{F4BC}' Tcl: type: programming ascii: | {0} // {2} . /{0}//// {2} /{0}/////// . {2} //{0}//{1}/{0}///// {2} //{0}//{1}/{0}///// {2} . //{0}/{1}//{0}//// {2} //{0}//{1}//{0}//// {2} //{0}/{1}//{0}///// {2} /{0}//{1}//{0}//// {2} /{0}/{1}//{0}//// . {2}. /{0}/{1}//{0}///// {2} /{0}/{1}//{0}//// {2} /{1}//{0}// {0} {1}// {0} {1}// {0} {1}/ {0} {1}/ colors: ansi: - blue - white - cyan chip: "#E4CC98" icon: '\u{e7c4}' Tex: type: markup ascii: | {0}$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ {0}$$$ $$$$$$$ $$$$$ $$ {0}$$ $$$$ $$$$ $$$$$$$$$ $$$$$$$ $$$$$ {0}$$ $$$$$ $$$$$ $$$$$$$$$$ $$$$$ $$$$$$ {0}$$ $$$$$ $$$ $$$$ $$$ $$$$$$$ {0}$$ $$$$$ $$$$$ $$$$$ $$$$ $ $$$$$$$$ {0}$$$$$$$$ $$$$$ $$$$$$ $$$$$ $$$$$$$$$ {0}$$$$$$$$ $$$$$ $$$$$$ $$$$$ $$$$$$$$$ {0}$$$$$$$$ $$$$$ $$$$$$$$$$$$ $$$$$$$$ {0}$$$$$$$$ $$$$$ $$$ $$$$$$$ $$ $$$$$$$ {0}$$$$$$$$ $$$$$ $$$$$$ $$$$ $$$$$$ {0}$$$$$$$$ $$$$$ $$$ $$$$$ $$$$$$ $$$$$ {0}$$$$$$$$ $$$$$ $$$$$$$$ $$$$$$$$ $$$$ {0}$$$$$ $$ $$$$$ $$$$$$ $$ {0}$$$$$$$$$$$$$$$ $$$$$$$ $$$$$$$$$$$$$$$ {0}$$$$$$$$$$$$$$$ $$$$$$ $$$$$$$$$$$$$$$$ {0}$$$$$$$$$$$$$ $$$$$$$$$$$$$$$$ {0}$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ colors: ansi: - white chip: "#3D6117" icon: '\u{E69B}' Text: type: prose ascii: | {0} ----------------- {0}| .txt ========== | {0}| =============== | {0}| =============== | {0}| =============== | {0}| =============== | {0}| ============ | {0}| | {0}| =============== | {0}| =============== | {0}| =============== | {0}| =============== | {0}| =============== | {0} ----------------- colors: ansi: - white chip: "#ffffff" icon: '\u{f09a8}' Toml: type: data ascii: | {0}[[[[[[[[ ]]]]]]]] {0}[[[[[[[[ ]]]]]]]] {0}[[[[ ]]]] {0}[[[[ {1}TTTTTTTTTTTTTTTT{0} ]]]] {0}[[[[ {1}TTTTTTTTTTTTTTTT{0} ]]]] {0}[[[[ {1}TTTT{0} ]]]] {0}[[[[ {1}TTTT{0} ]]]] {0}[[[[ {1}TTTT{0} ]]]] {0}[[[[ {1}TTTT{0} ]]]] {0}[[[[ {1}TTTT{0} ]]]] {0}[[[[ {1}TTTT{0} ]]]] {0}[[[[ {1}TTTT{0} ]]]] {0}[[[[ {1}TTTT{0} ]]]] {0}[[[[ {1}TTTT{0} ]]]] {0}[[[[ {1}TTTT{0} ]]]] {0}[[[[ {1}TTTT{0} ]]]] {0}[[[[[[[[ ]]]]]]]] {0}[[[[[[[[ ]]]]]]]] colors: ansi: - red - white hex: - "#9C4221" - "#FFFFFF" chip: "#9C4221" icon: '\u{E6B2}' Tsx: type: programming ascii: | {0}TSXTSXTSXTSXTSXTSXTSXTSXTSXTSXTSXTSX{1}TSX {0}TSXTSXTSXTSXTSXTSXTSXTSXTSXTSXTSXTS{1}XTSX {0}TSXTSXTSXTSXTSXTSXTSXTSXTSXTSXTSXT{1}SXTSX {0}TSXTSXTSXTSXTSXTSXTSXTSXTSXTSXTSX{1}TSXTSX {0}TSXTSXTSXTSXTSXTSXTSXTSXTSXTSXTS{1}XTSXTSX {0}TSXTSXTSXTSXTSXTSXTSXTSXTSXTSXT{1}SXTSXTSX {0}TSXTSXTSXTSXTSXTSXTSXTSXTSXTSX{1}TSXTSXTSX {0}TSXTSXTSXTSXTSXTSXTSXTSXTSXTS{1}XTSXTSXTSX {0}TSXTSXTSXTSXTSXTSXTSXTSXTSXT{1}SXTSXTSXTSX {0}TSXTSXTSXTSXTSXTSXTSXTSXTSX{1}TSXTSXTSXTSX {0}TS{2}XTSXTSXTS{0}XTSX{2}TSXTSX{0}TSXTS{1}X{2}TSX{1}TSX{2}TSX{1}TSX {0}TSXTS{2}XTS{0}XTSXTS{2}XTS{0}XTSXTSXT{1}SXT{2}SXT{1}S{2}XTS{1}XTSX {0}TSXTS{2}XTS{0}XTSXTSX{2}TSX{0}TSXTSX{1}TSXTSX{2}TSX{1}TSXTSX {0}TSXTS{2}XTS{0}XTSXTSXT{2}SXT{0}SXTS{1}XTSXTS{2}XTSXT{1}TSTSX {0}TSXTS{2}XTS{0}XTSXTSXTS{2}XTS{0}XT{1}SXTSXT{2}SXT{1}S{2}XTS{1}XTSX {0}TSXTS{2}XTS{0}XTSXT{2}SXTSXT{0}SX{1}TSXTSX{2}TSX{1}TSX{2}TSX{1}TSX {0}TSXTSXTSXTSXTSXTSXTS{1}XTSXTSXTSXTSXTSXTSX {0}TSXTSXTSXTSXTSXTSXT{1}SXTSXTSXTSXTSXTSXTSX colors: ansi: - cyan - magenta - white hex: - "#007ACC" - "#8A53A6" - "#FFFFFF" chip: "#2B7489" icon: '\u{E69D}' TypeScript: type: programming ascii: | {0}TSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTS {0}TSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTS {0}TSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTS {0}TSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTS {0}TSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTS {0}TSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTS {0}TSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTS {0}TSTSTSTS{1}TSTSTSTSTSTSTS{0}TSTS{1}TSTSTS{0}TSTSTS {0}TSTSTSTS{1}TSTSTSTSTSTSTS{0}TS{1}TSTSTSTSTS{0}TSTS {0}TSTSTSTSTSTST{1}STST{0}STSTSTS{1}TSTST{0}TSTSTSTST {0}TSTSTSTSTSTST{1}STST{0}STSTSTST{1}STSTS{0}TSTSTSTS {0}TSTSTSTSTSTST{1}STST{0}STSTSTSTST{1}STSTS{0}TSTSTS {0}TSTSTSTSTSTST{1}STST{0}STSTSTSTSTST{1}STSTS{0}TSTS {0}TSTSTSTSTSTST{1}STST{0}STSTSTSTSTSTS{1}TSTST{0}TST {0}TSTSTSTSTSTST{1}STST{0}STSTSTST{1}STSTSTSTST{0}STS {0}TSTSTSTSTSTST{1}STST{0}STSTSTSSTS{1}TSTSTS{0}TSTST {0}TSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTS {0}TSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTS colors: ansi: - cyan - white hex: - "#007ACC" - "#FFFFFF" chip: "#2B7489" icon: '\u{E69D}' Typst: type: markup ascii: | {0}ttttttttttttttttttttttttttttttttttttttt {0}ttttttttttttttttttttttttttttttttttttttt {0}ttttttttttttttttttttttttttttttttttttttt {0}ttttttttttttttttttttttttttttttttttttttt {0}ttttttttttttttt{1}tttt{0}tttttttttttttttttttt {0}ttttttttttttt{1}tttttt{0}tttttttttttttttttttt {0}tttttttttt{1}ttttttttttttttt{0}tttttttttttttt {0}tttttttttt{1}tttttttttttttt{0}ttttttttttttttt {0}ttttttttttttt{1}tttttt{0}tttttttttttttttttttt {0}ttttttttttttt{1}tttttt{0}tttttttttttttttttttt {0}ttttttttttttt{1}tttttt{0}tttttttttttttttttttt {0}ttttttttttttt{1}tttttt{0}tttttttttttttttttttt {0}ttttttttttttt{1}tttttt{0}tttttttttttttttttttt {0}ttttttttttttt{1}tttttt{0}tttttttttttttttttttt {0}ttttttttttttt{1}tttttt{0}tttttttttttttttttttt {0}ttttttttttttt{1}ttttttt{0}tttttttt{1}t{0}tttttttttt {0}tttttttttttttt{1}tttttttttttttt{0}ttttttttttt {0}tttttttttttttttt{1}tttttttttt{0}ttttttttttttt {0}ttttttttttttttttttttttttttttttttttttttt {0}ttttttttttttttttttttttttttttttttttttttt {0}ttttttttttttttttttttttttttttttttttttttt {0}ttttttttttttttttttttttttttttttttttttttt colors: ansi: - cyan - white hex: - "#239DAD" - "#FFFFFF" chip: "#239DAD" icon: '\u{F37F}' Vala: type: programming ascii: | {0} ################################### {0}##################################### {0}##################################### {0}############{1}######{0}##########{1}##{0}####### {0}##########{1}###{0}#{1}####{0}#########{1}##{0}######## {0}########{1}###{0}###{1}####{0}########{1}##{0}######### {0}#######{1}###{0}####{1}####{0}#######{1}##{0}########## {0}######{1}###{0}#####{1}####{0}######{1}##{0}########### {0}######{1}###{0}#####{1}####{0}#####{1}##{0}############ {0}########{1}#{0}#####{1}####{0}####{1}##{0}############# {0}##############{1}####{0}###{1}##{0}############## {0}##############{1}####{0}##{1}##{0}############### {0}##############{1}####{0}#{1}##{0}################ {0}##############{1}######{0}################# {0}##############{1}#####{0}################## {0}##############{1}####{0}################### {0}##################################### {0}##################################### {0} ################################### colors: ansi: - magenta - white chip: "#A56DE2" icon: '\u{E8D1}' Verilog: type: programming ascii: | {0} _.._ _.._ _.._ {0} _.._ _.._ _.._ {0} _.._ _.._ _.._ {0} _......................._ {0} _.{1}----- -----{0}._ {0}_..._.{1} --- --- {0}._..._ {0}_..._.{1} --- --- {0}._..._ {0} _.{1} --- --- {0}._ {0} _.{1} --- --- {0}._ {0}_..._.{1} --- --- {0}._..._ {0}_..._.{1} --- --- {0}._..._ {0} _.{1} --- --- {0}._ {0} _.{1} --- --- {0}._ {0}_..._.{1} ----- {0}._..._ {0}_..._.{1} --- {0}._..._ {0} _.{1} - {0}._ {0} _......................._ {0} _.._ _.._ _.._ {0} _.._ _.._ _.._ {0} _.._ _.._ _.._ colors: ansi: - white - magenta chip: "#b2b7f8" icon: '\u{F4BC}' Vhdl: type: programming ascii: | {0} | | | | {0} {1}------------ {0} --{1}| {2}---- {1}|{0}-- {0} --{1}| {2}| | {1}|{0}-- {0} --{1}| {2}| | {1}|{0}-- {0} --{1}| {2}---- {1}|{0}-- {0} {1}------------ {0} | | | | {2}__ ___ _ ____ _ {2}\ \ / / | | | _ \| | {2} \ \ / /| |_| | | | | | {2} \ V / | _ | |_| | |___ {2} \_/ |_| |_|____/|_____| colors: ansi: - yellow - green - white chip: "#ADB2CB" icon: '\u{F4BC}' VimScript: type: programming ascii: | {1} ________{0} ++ {1}________ {1} /{2}VVVVVVVV{1}\{0}++++ {1}/{2}VVVVVVVV{1}\ {1} \{2}VVVVVVVV{1}/{0}++++++{1}\{2}VVVVVVVV{1}/ {1} |{2}VVVVVV{1}|{0}++++++++{1}/{2}VVVVV{1}/' {1} |{2}VVVVVV{1}|{0}++++++{1}/{2}VVVVV{1}/' {0} +{1}|{2}VVVVVV{1}|{0}++++{1}/{2}VVVVV{1}/'{0}+ {0} +++{1}|{2}VVVVVV{1}|{0}++{1}/{2}VVVVV{1}/'{0}+++++ {0}+++++{1}|{2}VVVVVV{1}|/{2}VVV{1}___{0}++++++++++ {0} +++{1}|{2}VVVVVVVVVV{1}/{2}##{1}/ {0}+{1}_{0}+{1}_{0}+{1}_{0}+{1}_ {0} +{1}|{2}VVVVVVVVV{1}___ {0}+{1}/{2}#{1}_{2}#{1},{2}#{1}_{2}#{1},\ {1} |{2}VVVVVVV{1}//{2}##{1}/{0}+{1}/{2}#{1}/{0}+{1}/{2}#{1}/'/{2}#{1}/ {1} |{2}VVVVV{1}/'{0}+{1}/{2}#{1}/{0}+{1}/{2}#{1}/{0}+{1}/{2}#{1}/ /{2}#{1}/ {1} |{2}VVV{1}/'{0}++{1}/{2}#{1}/{0}+{1}/{2}#{1}/ /{2}#{1}/ /{2}#{1}/ {1} '{2}V{1}/' /{2}##{1}//{2}##{1}//{2}##{1}//{2}###{1}/ {0} ++ colors: ansi: - green - black - white chip: "#199F4B" icon: '\u{E7C5}' VisualBasic: type: programming ascii: | {1} :::::::::: {1} :::::::::::::::::: {1} :::::::::::::::::::::::: {0} &&&&{1}:::::::::::::::::::::::: {0} &&&&&&&&{1}:::::::::::::::::::::::: {0} &&&&{2}##{0}&&&&&{1}::::::{2}##{1}:::{2}######{1}:::::: {0}&&&&&&{2}##{0}&&&&&&{1}:::{2}##{1}::::{2}#{1}:::::{2}##{1}::::: {0}&&&&&&&{2}##{0}&&&&&&&{2}##{1}:::::{2}#{1}:::::{2}##{1}::::: {0}&&&&&&&&{2}##{0}&&&&&{2}##{0}&{1}:::::{2}#######{1}:::::: {0}&&&&&&&&&{2}##{0}&&&{2}##{0}&&&&{1}:::{2}#{1}::::::{2}##{1}:::: {0}&&&&&&&&&&{2}##{0}&{2}##{0}&&&&&&&{1}:{2}#{1}::::::{2}##{1}:::: {0} &&&&&&&&&&{2}###{0}&&&&&&&&&{2}######{1}:::::: {0} &&&&&&&&&&&&&&&&&&&&&&&&{1}:::::::: {0} &&&&&&&&&&&&&&&&&&&&&&&&{1}:::: {0} &&&&&&&&&&&&&&&&&&&&&&&& {0} &&&&&&&&&&&&&&&&&& {0} &&&&&&&&&& colors: ansi: - blue - blue - white hex: - "#195F97" - "#004E8C" - "#FFFFFF" chip: "#945db7" icon: '\u{E8D5}' Vue: type: markup ascii: | {0}VUE{1}\\\\\ /////{0}VUE {0} VUE{1}\\\\\ /////{0}VUE {0} VUE{1}\\\\\ /////{0}VUE {0} VUE{1}\\\\\ /////{0}VUE {0} VUE{1}\\\\\ /////{0}VUE {0} VUE{1}\\\\\ /////{0}VUE {0} VUE{1}\\\\\ /////{0}VUE {0} VUE{1}\\\\\ /////{0}VUE {0} VUE{1}\\\\\/////{0}VUE {0} VUE{1}\\\\////{0}VUE {0} VUE{1}\\\///{0}VUE {0} VUE{1}\\//{0}VUE {0} VUE{1}||{0}VUE {0} VUEVUE {0} VUEV colors: ansi: - green - blue chip: "#199F4B" icon: '\u{E6A0}' WebAssembly: type: programming ascii: | {0}::::::::::: :::::::::::: {0}:::::::::::: ::::::::::::: {0}::::::::::::::: :::::::::::::::: {0}:::::::::::::::::::::::::::::::::::: {0}:::::::::::::::::::::::::::::::::::: {0}:::::::::::::::::::::::::::::::::::: {0}:::::::::::::::::::::::::::::::::::: {0}:::::::::::::::::::::::::::::::::::: {0}:::::::::::::::::::::::::::::::::::: {0}:::::::::::::::::::::::::::::::::::: {0}::::::::::::{1}WW{0}:::{1}WW{0}:::{1}WW{0}::::{1}AA{0}:::::: {0}::::::::::::{1}WW{0}:::{1}WW{0}:::{1}WW{0}:::{1}AAAA{0}::::: {0}::::::::::::{1}WW{0}:::{1}WW{0}:::{1}WW{0}::{1}AA{0}::{1}AA{0}:::: {0}:::::::::::::{1}WW{0}:{1}WWWW{0}:{1}WW{0}::{1}AAAAAAAA{0}::: {0}::::::::::::::{1}WWW{0}::{1}WWW{0}::{1}AA{0}::::::{1}AA{0}:: {0}:::::::::::::::::::::::::::::::::::: colors: ansi: - magenta - white hex: - "#654FF0" - "#FFFFFF" chip: "#04133B" icon: '\u{E6A1}' Wolfram: type: programming ascii: | {0} OOOOOOOOOOOOOO {0} OOOOOO OOOOOOOOOOOOOO {0} OOOOOO {1}WW{0} OOOO OOOOOOOOOOO {0} OOOOOOO {1}WWW {0}OOO {1}W{0} OOOOOOOOOOOO {0} OOOOOOOO {1}WWWWW {0}O {1}WW{0} OOOOOOOOOOOOO {0} OOOOOOOO {1}WWWWWW WWW{0} OOOOOOOOOOOOOO {0} OOOOOOOOO {1}WWWWWWW WWW{0} OOOOOOOOOOOOOOO {0} OOOOOOO {1}WWWWWWWWWW WW{0} OOOOOOOOOOOOOOO {0}OOOOOOO {1}WWWWWWWWWWWWWW{0} OOOOOOOOOOOOOOO {0}OOOOOO {1}WWWWWWWWWWWWWWWWW{0} OOOOOOOOOOOO {0}OOOOO {1}WWW WWWWWWWWW WWWWW{0} OOOOOOOOO {0}OOO {1}WW WWWWWWWWWWWWWWWWWWWWW{0} OOOOOOO {0} O {1}WWWW WWWWWWWWWWWWWWWWWWWWW{2}D{0} OOOO {0} {1}WWWW WWWWWWWWWWWWWWWWWWWWWW{0} OOOOO {1} WWWWW.............. {0}.........OOOOO {1} WWWWWWWWWWWWWWWWWW{0} OOOOOOOOOOOO {1} WWWWWWWWWWWWWWWWWW{0} OOOOOOOO {1} WWWWWWWWWWWWWWWWW{0} OOOOOO {1} WWWWWWWWWWWWWWWW{0} OO {1} WWWWWWWWWWWWW{0} colors: ansi: - red - white - black hex: - "#FF0A01" - "#FFFFFF" - "#000000" chip: "#DD1100" Xaml: type: data ascii: | {0} :::::::::::::::::::::.. {0} :::{1}------{0}::::::::::::.... {0} :::{1}------{0}::::::::::::..{1}-{0}... {0} :::{1}------{0}::::::::::::..{1}---{0}... {0} :::{1}------{0}::::::::::::..{1}-----{0}... {0} :::{1}------{0}::::::::::::...{1}------{0}... {0} :::{1}------{0}::::::::::::.....{1}------{0}... {0} :::{1}------{0}::::::::::::.......{1}------{0}... {0}:::{1}------{0}::::::::::::.........{1}------{0}... {0} :::{1}------{0}::::::::::::.......{1}------{0}... {0} :::{1}------{0}::::::::::::.....{1}------{0}... {0} :::{1}------{0}::::::::::::...{1}------{0}... {0} :::{1}------{0}::::::::::::..{1}-----{0}... {0} :::{1}------{0}::::::::::::..{1}---{0}... {0} :::{1}------{0}::::::::::::..{1}-{0}... {0} :::{1}------{0}::::::::::::.... {0} :::::::::::::::::::::.. colors: ansi: - blue - white hex: - "#3378CE" - "#FFFFFF" chip: "#0060AC" icon: '\u{f0673}' Xml: type: data ascii: | {0} __{1} __ _ __ __ _ {2} __{0}__ {0} / /{1} \ \/ | \ \| | {2} / /{0}\ \ {0}< < {1} \ \ | || |_ {2} / / {0} > > {0} \_\{1} _/\_\ |_|_|_||___| {2}/_/ {0}/_/ colors: ansi: - yellow - white - green chip: "#0060AC" icon: '\u{f05c0}' XSL: type: programming ascii: | {0} ::: {0} ::::: ::: ::::: {0} ::::: ::: ::::: {0} ::::: ::: ::::: {0} ::::: ::: ::::: {0}::::: ::: ::::: {0} ::::: ::: ::::: {0} ::::: ::: ::::: {0} ::::: ::: ::::: {0} ::::: ::: ::::: {0} ::: colors: ansi: - cyan chip: "#EB8CEB" icon: '\u{f05c0}' Yaml: type: data ascii: | {0}__ __ __ __ __ _ {0}\ \ / / / | | \ / | | | {0} \ \/ / / | | | \ \/ / | | |. {0} \ / / /| | | |\__/| | | | . {0} / / / / | | | | | | | | . {0} / / / / | | | | | | | |___. {0}/_/ /_/ |_| |_| |_| |______\ colors: ansi: - white chip: "#CB171E" icon: '\u{E6A8}' Zig: type: programming ascii: | {0} z {0} zzz {0} zzzzzz {0}zzzzzzzzzzz zzzzzzzzzzzzzzzzzzzz zzz {0}zzzzzzzzz zzzzzzzzzzzzzzzzzzzz zzzzz {0}zzzzzzz zzzzzzzzzzzzzzzzzzzz zzzzzzz {0}zzzzz zzzzzz zzzzz {0}zzzzz zzzzzz zzzzz {0}zzzzz zzzzzz zzzzz {0}zzzzz zzzzzz zzzzz {0}zzzzz zzzzzz zzzzz {0}zzzzz zzzzzz zzzzz {0}zzzzzzz zzzzzzzzzzzzzzzzzzzz zzzzzzz {0}zzzzz zzzzzzzzzzzzzzzzzzzz zzzzzzzzz {0}zzz zzzzzzzzzzzzzzzzzzzz zzzzzzzzzzz {0} zzzzzz {0} zzz {0}z colors: ansi: - yellow chip: "#EC915C" icon: '\u{E6A9}' Zsh: type: programming ascii: | {0}ZSHZSHZSHZSHZSHZSHZSHZSHZSHZSHZS {0}ZSHZSHZSHZSHZSHZSHZSHZSHZSHZSHZS {0}ZSHZ ZSHZSHZSHZSHZSHZSHZSHZS {0}ZSHZSH SHZSHZSHZSHZSHZSHZSHZ {0}ZSHZSHZS SHZSHZSHZSHZSHZSHZS {0}ZSHZSHZSHZ HZSHZSHZSHZSHZSHZ {0}ZSHZSHZSHZSH ZSHZSHZSHZSHZSH {0}ZSHZSHZSHZ SHZSHZSHZSHZSHZSH {0}ZSHZSHZS ZSHZSHZSHZSHZSHZSHZ {0}ZSHZSH SHZSHZSHZSHZSHZSHZSHZ {0}ZSHZ ZSHZSH SHZS {0}ZSHZSHZSHZSHZSHZSHZSHZSHZSHZSHZS {0}ZSHZSHZSHZSHZSHZSHZSHZSHZSHZSHZS colors: ansi: - white chip: "#89E051" icon: '\u{f1183}' ================================================ FILE: manifest/Cargo.toml ================================================ [package] authors.workspace = true edition.workspace = true version.workspace = true license.workspace = true repository.workspace = true name = "onefetch-manifest" description = "Detect and parse manifest files" [dependencies] anyhow = "1.0.101" cargo_toml = "0.22.3" serde = { version = "1.0.228", features = ["derive"] } serde_json = "1.0.149" strum = { version = "0.28.0", features = ["derive"] } ================================================ FILE: manifest/README.md ================================================ # manifest [![crates.io](https://img.shields.io/crates/v/onefetch-manifest)](https://crates.io/crates/onefetch-manifest) [![docs.rs](https://img.shields.io/docsrs/onefetch-manifest)](https://docs.rs/onefetch-manifest) Provides the primary interface to detect and parse the repository's manifest(s). _This crate is designed as part of the [onefetch](https://github.com/o2sh/onefetch) project._ ================================================ FILE: manifest/src/lib.rs ================================================ use anyhow::{Context, Result}; use serde::Deserialize; use std::{ collections::HashMap, fs, path::{Path, PathBuf}, }; use strum::{Display, EnumIter}; #[derive(Clone, PartialEq, Eq, Debug)] pub struct Manifest { pub manifest_type: ManifestType, pub number_of_dependencies: usize, pub name: Option, pub description: Option, pub version: Option, pub license: Option, } #[derive(Display, Clone, Copy, PartialEq, Eq, Debug, EnumIter)] pub enum ManifestType { Npm, Cargo, } pub fn get_manifests>(path: P) -> Result> { let manifests = fs::read_dir(path)? .filter_map(|entry| entry.ok()) .map(|entry| entry.path()) .filter(|p| p.is_file()) .filter_map(|file_path: PathBuf| { let file_name = file_path.file_name()?.to_str()?; let manifest_type = file_name_to_manifest_type(file_name)?; Some((file_path, manifest_type)) }) .filter_map(|(file_path, manifest_type)| match manifest_type { ManifestType::Cargo => parse_cargo_manifest(&file_path).ok(), ManifestType::Npm => parse_npm_manifest(&file_path).ok(), }) .collect::>(); Ok(manifests) } fn parse_cargo_manifest(path: &Path) -> Result { let m = cargo_toml::Manifest::from_path(path) .with_context(|| format!("Failed to parse Cargo.toml at '{}'", path.display()))?; let package = m.package.context("Not a package (only a workspace)")?; let description = package.description().map(Into::into); Ok(Manifest { manifest_type: ManifestType::Cargo, number_of_dependencies: m.dependencies.len(), name: Some(package.name.clone()), description, version: Some(package.version().into()), license: package.license().map(Into::into), }) } #[derive(Deserialize)] struct PackageJson { name: Option, description: Option, version: Option, license: Option, #[serde(default)] dependencies: HashMap, } fn parse_npm_manifest(path: &Path) -> Result { let content = fs::read_to_string(path) .with_context(|| format!("Failed to read package.json at '{}'", path.display()))?; let pkg: PackageJson = serde_json::from_str(&content) .with_context(|| format!("Failed to parse package.json at '{}'", path.display()))?; Ok(Manifest { manifest_type: ManifestType::Npm, number_of_dependencies: pkg.dependencies.len(), name: pkg.name, description: pkg.description, version: pkg.version, license: pkg.license, }) } fn file_name_to_manifest_type(filename: &str) -> Option { match filename { "Cargo.toml" => Some(ManifestType::Cargo), "package.json" => Some(ManifestType::Npm), _ => None, } } ================================================ FILE: manifest/tests/cargo.rs ================================================ use anyhow::Result; use onefetch_manifest::{ManifestType, get_manifests}; #[test] fn should_detect_and_parse_cargo_manifest() -> Result<()> { let manifests = get_manifests("tests/fixtures/cargo")?; assert_eq!(manifests.len(), 1); let cargo_manifest = manifests.first().unwrap(); assert_eq!(cargo_manifest.manifest_type, ManifestType::Cargo); assert_eq!(cargo_manifest.number_of_dependencies, 5); assert_eq!(cargo_manifest.name, Some(String::from("project"))); assert_eq!( cargo_manifest.description, Some("this is a description".into()) ); assert_eq!(cargo_manifest.version, Some(String::from("0.1.0"))); assert_eq!(cargo_manifest.license, Some("MIT".into())); Ok(()) } ================================================ FILE: manifest/tests/fixtures/cargo/Cargo.toml ================================================ [package] name = "project" version = "0.1.0" edition = "2024" description = "this is a description" license = "MIT" [dependencies] cortex-m-rtic = "0.6.0-alpha.1" anyhow = "1.0" [dependencies.cortex-m] version = "0.7.1" [dependencies.cortex-m-rt] version = "0.6.11" [dependencies.stm32f4xx-hal] version = "0.8.3" features = ["rt", "stm32f401"] ================================================ FILE: manifest/tests/fixtures/npm/package.json ================================================ { "name": "my_package", "description": "description for my_package", "version": "1.0.0", "main": "index.js", "dependencies": { "@rollup/plugin-yaml": "^4.0.1", "@sveltejs/vite-plugin-svelte": "^1.0.8", "@tsconfig/svelte": "^3.0.0" }, "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "repository": { "type": "git", "url": "https://github.com//my_package.git" }, "keywords": [], "author": "", "license": "ISC", "bugs": { "url": "https://github.com//my_package/issues" }, "homepage": "https://github.com//my_package" } ================================================ FILE: manifest/tests/npm.rs ================================================ use anyhow::Result; use onefetch_manifest::{ManifestType, get_manifests}; #[test] fn should_detect_and_parse_npm_manifest() -> Result<()> { let manifests = get_manifests("tests/fixtures/npm")?; assert_eq!(manifests.len(), 1); let npm_manifest = manifests.first().unwrap(); assert_eq!(npm_manifest.manifest_type, ManifestType::Npm); assert_eq!(npm_manifest.number_of_dependencies, 3); assert_eq!(npm_manifest.name, Some(String::from("my_package"))); assert_eq!( npm_manifest.description, Some("description for my_package".into()) ); assert_eq!(npm_manifest.version, Some(String::from("1.0.0"))); assert_eq!(npm_manifest.license, Some("ISC".into())); Ok(()) } ================================================ FILE: scripts/nf-preview.rb ================================================ #!/usr/bin/env ruby require "yaml" LANGUAGES_FILE = File.expand_path("../../languages.yaml", __FILE__) languages = YAML.safe_load_file(ARGV[0] || LANGUAGES_FILE, symbolize_names: true) languages.each do |language, attributes| icon = attributes[:icon] next if icon.nil? match = /\A\\u\{([A-F0-9]{4,})\}\z/i.match(icon) raise "Icon for #{language} is not in the correct format: `#{icon}`" unless match glyph = match.captures[0].hex.chr("UTF-8") puts "#{language}: #{glyph}" end ================================================ FILE: snap/snapcraft.yaml ================================================ name: onefetch base: core22 adopt-info: onefetch summary: Command-line Git information tool description: | Onefetch is a command-line Git information tool that displays project information and code statistics for a local Git repository directly to your terminal. grade: stable confinement: strict parts: onefetch: plugin: rust source: . build-packages: - cargo - rustc - cmake stage-packages: - git override-build: | snapcraftctl build snapcraftctl set-version $(git describe --abbrev=0 --tags) plugs: etc-gitconfig: interface: system-files read: - /etc/gitconfig gitconfig: interface: personal-files read: - $HOME/.gitconfig - $HOME/.config/git/config apps: onefetch: environment: HOME: $SNAP_REAL_HOME command: bin/onefetch plugs: - home - removable-media - etc-gitconfig - gitconfig ================================================ FILE: src/cli.rs ================================================ use crate::info::langs::language::{Language, LanguageType}; use crate::info::utils::info_field::InfoType; use crate::ui::printer::SerializationFormat; use anyhow::Result; use clap::builder::PossibleValuesParser; use clap::builder::Styles; use clap::builder::TypedValueParser as _; use clap::builder::styling::AnsiColor; use clap::{Args, Command, Parser, ValueHint, value_parser}; use clap_complete::{Generator, Shell, generate}; use num_format::CustomFormat; use onefetch_image::ImageProtocol; use onefetch_manifest::ManifestType; use regex::Regex; use serde::Serialize; use std::env; use std::io; use std::path::PathBuf; use std::str::FromStr; use strum::IntoEnumIterator; const COLOR_RESOLUTIONS: [&str; 5] = ["16", "32", "64", "128", "256"]; pub const NO_BOTS_DEFAULT_REGEX_PATTERN: &str = r"(?:-|\s)[Bb]ot$|\[[Bb]ot\]"; const STYLES: Styles = Styles::styled() .header(AnsiColor::Yellow.on_default()) .usage(AnsiColor::Green.on_default()) .literal(AnsiColor::Green.on_default()) .placeholder(AnsiColor::Green.on_default()); #[derive(Clone, Debug, Parser, PartialEq, Eq)] #[command(version, about)] #[command(styles = STYLES)] pub struct CliOptions { /// Run as if onefetch was started in instead of the current working directory #[arg(default_value = ".", hide_default_value = true, value_hint = ValueHint::DirPath)] pub input: PathBuf, #[command(flatten)] pub info: InfoCliOptions, #[command(flatten)] pub text_formatting: TextForamttingCliOptions, #[command(flatten)] pub ascii: AsciiCliOptions, #[command(flatten)] pub image: ImageCliOptions, #[command(flatten)] pub visuals: VisualsCliOptions, #[command(flatten)] pub developer: DeveloperCliOptions, #[command(flatten)] pub other: OtherCliOptions, } #[derive(Clone, Debug, Args, PartialEq, Eq)] #[command(next_help_heading = "INFO")] pub struct InfoCliOptions { /// Allows you to disable FIELD(s) from appearing in the output #[arg( long, short, num_args = 1.., hide_possible_values = true, value_enum, value_name = "FIELD" )] pub disabled_fields: Vec, /// Hides the title #[arg(long)] pub no_title: bool, /// Maximum NUM of authors to be shown #[arg(long, default_value_t = 3usize, value_name = "NUM")] pub number_of_authors: usize, /// Maximum NUM of languages to be shown #[arg(long, default_value_t = 6usize, value_name = "NUM")] pub number_of_languages: usize, /// Maximum NUM of file churns to be shown #[arg(long, default_value_t = 3usize, value_name = "NUM")] pub number_of_file_churns: usize, /// Minimum NUM of commits from HEAD used to compute the churn summary /// /// By default, the actual value is non-deterministic due to time-based computation /// and will be displayed under the info title "Churn (NUM)" #[arg(long, value_name = "NUM")] pub churn_pool_size: Option, /// Ignore all files & directories matching EXCLUDE #[arg(long, short, num_args = 1..)] pub exclude: Vec, /// Exclude [bot] commits. Use to override the default pattern #[arg( long, num_args = 0..=1, require_equals = true, default_missing_value = NO_BOTS_DEFAULT_REGEX_PATTERN, value_name = "REGEX" )] pub no_bots: Option, /// Ignores merge commits #[arg(long)] pub no_merges: bool, /// Show the email address of each author #[arg(long, short = 'E')] pub email: bool, /// Display repository URL as HTTP #[arg(long)] pub http_url: bool, /// Hide token in repository URL #[arg(long)] pub hide_token: bool, /// Count hidden files and directories #[arg(long)] pub include_hidden: bool, /// Filters output by language type #[arg( long, num_args = 1.., default_values = &["programming", "markup"], short = 'T', value_enum, )] pub r#type: Vec, } #[derive(Clone, Debug, Args, PartialEq, Eq)] #[command(next_help_heading = "ASCII")] pub struct AsciiCliOptions { /// Takes a non-empty STRING as input to replace the ASCII logo /// /// It is possible to pass a generated STRING by command substitution /// /// For example: /// /// '--ascii-input "$(fortune | cowsay -W 25)"' #[arg(long, value_name = "STRING", value_hint = ValueHint::CommandString)] pub ascii_input: Option, /// Colors (X X X...) to print the ascii art #[arg( long, num_args = 1.., value_name = "X", short = 'c', value_parser = value_parser!(u8).range(..16), )] pub ascii_colors: Vec, /// Which LANGUAGE's ascii art to print #[arg( long, short, value_name = "LANGUAGE", value_enum, hide_possible_values = true )] pub ascii_language: Option, /// Specify when to use true color /// /// If set to auto: true color will be enabled if supported by the terminal #[arg(long, default_value = "auto", value_name = "WHEN", value_enum)] pub true_color: When, } #[derive(Clone, Debug, Args, PartialEq, Eq)] #[command(next_help_heading = "IMAGE")] pub struct ImageCliOptions { /// Path to the IMAGE file #[arg(long, short, value_hint = ValueHint::FilePath)] pub image: Option, /// Which image PROTOCOL to use #[arg(long, value_enum, requires = "image", value_name = "PROTOCOL")] pub image_protocol: Option, /// VALUE of color resolution to use with SIXEL backend #[arg( long, value_name = "VALUE", requires = "image", default_value_t = 64usize, value_parser = PossibleValuesParser::new(COLOR_RESOLUTIONS) .map(|s| s.parse::().unwrap()) )] pub color_resolution: usize, } #[derive(Clone, Debug, Args, PartialEq, Eq)] #[command(next_help_heading = "TEXT FORMATTING")] pub struct TextForamttingCliOptions { /// Changes the text colors (X X X...) /// /// Goes in order of title, ~, underline, subtitle, colon, and info /// /// For example: /// /// '--text-colors 9 10 11 12 13 14' #[arg( long, short, value_name = "X", value_parser = value_parser!(u8).range(..16), num_args = 1..=6 )] pub text_colors: Vec, /// Use ISO 8601 formatted timestamps #[arg(long, short = 'z')] pub iso_time: bool, /// Which thousands SEPARATOR to use #[arg(long, value_name = "SEPARATOR", default_value = "plain", value_enum)] pub number_separator: NumberSeparator, /// Turns off bold formatting #[arg(long)] pub no_bold: bool, } #[derive(Clone, Debug, Args, PartialEq, Eq, Default)] #[command(next_help_heading = "VISUALS")] pub struct VisualsCliOptions { /// Hides the color palette #[arg(long)] pub no_color_palette: bool, /// Hides the ascii art or image if provided #[arg(long)] pub no_art: bool, /// Use Nerd Font icons /// /// Replaces language chips with Nerd Font icons #[arg(long)] pub nerd_fonts: bool, } #[derive(Clone, Debug, Args, PartialEq, Eq, Default)] #[command(next_help_heading = "DEVELOPER")] pub struct DeveloperCliOptions { /// Outputs Onefetch in a specific format #[arg(long, short, value_name = "FORMAT", value_enum)] pub output: Option, /// If provided, outputs the completion file for given SHELL #[arg(long = "generate", value_name = "SHELL", value_enum)] pub completion: Option, } #[derive(Clone, Debug, Args, PartialEq, Eq, Default)] #[command(next_help_heading = "OTHER")] pub struct OtherCliOptions { /// Prints out supported languages #[arg(long, short)] pub languages: bool, /// Prints out supported package managers #[arg(long, short)] pub package_managers: bool, } impl Default for CliOptions { fn default() -> CliOptions { CliOptions { input: PathBuf::from("."), info: InfoCliOptions::default(), text_formatting: TextForamttingCliOptions::default(), visuals: VisualsCliOptions::default(), ascii: AsciiCliOptions::default(), image: ImageCliOptions::default(), developer: DeveloperCliOptions::default(), other: OtherCliOptions::default(), } } } impl Default for InfoCliOptions { fn default() -> Self { InfoCliOptions { number_of_authors: 3, number_of_languages: 6, number_of_file_churns: 3, churn_pool_size: Option::default(), exclude: Vec::default(), no_bots: Option::default(), no_merges: Default::default(), email: Default::default(), http_url: Default::default(), hide_token: Default::default(), include_hidden: Default::default(), r#type: vec![LanguageType::Programming, LanguageType::Markup], disabled_fields: Vec::default(), no_title: Default::default(), } } } impl Default for TextForamttingCliOptions { fn default() -> Self { TextForamttingCliOptions { text_colors: Vec::default(), iso_time: Default::default(), number_separator: NumberSeparator::Plain, no_bold: Default::default(), } } } impl Default for AsciiCliOptions { fn default() -> Self { AsciiCliOptions { ascii_input: Option::default(), ascii_colors: Vec::default(), ascii_language: Option::default(), true_color: When::Auto, } } } impl Default for ImageCliOptions { fn default() -> Self { ImageCliOptions { image: Option::default(), image_protocol: Option::default(), color_resolution: 64, } } } pub fn print_supported_languages() -> Result<()> { for l in Language::iter() { println!("{l}"); } Ok(()) } pub fn print_supported_package_managers() -> Result<()> { for p in ManifestType::iter() { println!("{p}"); } Ok(()) } pub fn is_truecolor_terminal() -> bool { env::var("COLORTERM") .map(|colorterm| colorterm == "truecolor" || colorterm == "24bit") .unwrap_or(false) } pub fn get_git_version() -> String { let version = std::process::Command::new("git").arg("--version").output(); match version { Ok(v) => String::from_utf8_lossy(&v.stdout).replace('\n', ""), Err(_) => String::new(), } } pub fn print_completions(generator: G, cmd: &mut Command) { generate( generator, cmd, cmd.get_name().to_string(), &mut io::stdout(), ); } #[derive(clap::ValueEnum, Clone, PartialEq, Eq, Debug)] pub enum When { Auto, Never, Always, } #[derive(clap::ValueEnum, Clone, PartialEq, Eq, Debug, Serialize, Copy)] pub enum NumberSeparator { Plain, Comma, Space, Underscore, } impl NumberSeparator { fn separator(self) -> &'static str { match self { Self::Plain => "", Self::Comma => ",", Self::Space => "\u{202f}", Self::Underscore => "_", } } pub fn get_format(&self) -> CustomFormat { num_format::CustomFormat::builder() .grouping(num_format::Grouping::Standard) .separator(self.separator()) .build() .unwrap() } } #[cfg(test)] mod test { use super::*; #[test] fn test_default_config() { let config: CliOptions = CliOptions::default(); assert_eq!(config, CliOptions::parse_from(["onefetch"])); } #[test] fn test_custom_config() { let config: CliOptions = CliOptions { input: PathBuf::from("/tmp/folder"), info: InfoCliOptions { number_of_authors: 4, no_merges: true, disabled_fields: vec![InfoType::Version, InfoType::URL], ..Default::default() }, ascii: AsciiCliOptions { ascii_colors: vec![5, 0], ascii_language: Some(Language::Lisp), ..Default::default() }, visuals: VisualsCliOptions { no_art: true, ..Default::default() }, ..Default::default() }; assert_eq!( config, CliOptions::parse_from([ "onefetch", "/tmp/folder", "--number-of-authors", "4", "--no-merges", "--ascii-colors", "5", "0", "--disabled-fields", "version", "url", "--no-art", "--ascii-language", "lisp" ]) ); } #[test] fn test_config_with_image_protocol_but_no_image() { assert!(CliOptions::try_parse_from(["onefetch", "--image-protocol", "sixel"]).is_err()) } #[test] fn test_config_with_color_resolution_but_no_image() { assert!(CliOptions::try_parse_from(["onefetch", "--color-resolution", "32"]).is_err()) } #[test] fn test_config_with_ascii_colors_but_out_of_bounds() { assert!(CliOptions::try_parse_from(["onefetch", "--ascii-colors", "17"]).is_err()) } #[test] fn test_config_with_text_colors_but_out_of_bounds() { assert!(CliOptions::try_parse_from(["onefetch", "--text-colors", "17"]).is_err()) } } #[derive(Clone, Debug)] pub struct MyRegex(pub Regex); impl Eq for MyRegex {} impl PartialEq for MyRegex { fn eq(&self, other: &MyRegex) -> bool { self.0.as_str() == other.0.as_str() } } impl FromStr for MyRegex { type Err = anyhow::Error; fn from_str(s: &str) -> Result { Ok(MyRegex(Regex::new(s)?)) } } ================================================ FILE: src/info/authors.rs ================================================ use super::git::sig::Sig; use crate::{ cli::NumberSeparator, info::utils::{format_number, info_field::InfoField}, }; use serde::Serialize; use std::{collections::HashMap, fmt::Write}; #[derive(Serialize, Clone, Debug, PartialEq)] #[serde(rename_all = "camelCase")] pub struct Author { pub name: String, email: Option, nbr_of_commits: usize, contribution: usize, #[serde(skip_serializing)] number_separator: NumberSeparator, } impl Author { pub fn new( name: String, email: Option, nbr_of_commits: usize, total_nbr_of_commits: usize, number_separator: NumberSeparator, ) -> Self { let contribution = (nbr_of_commits as f32 * 100. / total_nbr_of_commits as f32).round() as usize; Self { name, email, nbr_of_commits, contribution, number_separator, } } } impl std::fmt::Display for Author { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { if let Some(email) = &self.email { write!( f, "{}% {} <{}> {}", self.contribution, self.name, email, format_number(&self.nbr_of_commits, self.number_separator) ) } else { write!( f, "{}% {} {}", self.contribution, self.name, format_number(&self.nbr_of_commits, self.number_separator) ) } } } #[derive(Serialize)] pub struct AuthorsInfo { pub authors: Vec, } impl AuthorsInfo { pub fn new( number_of_commits_by_signature: &HashMap, total_number_of_commits: usize, number_of_authors_to_display: usize, show_email: bool, number_separator: NumberSeparator, ) -> Self { let authors = compute_authors( number_of_commits_by_signature, total_number_of_commits, number_of_authors_to_display, show_email, number_separator, ); Self { authors } } fn top_contribution(&self) -> usize { if let Some(top_contributor) = self.authors.first() { return top_contributor.contribution; } 0 } } fn compute_authors( number_of_commits_by_signature: &HashMap, total_number_of_commits: usize, number_of_authors_to_display: usize, show_email: bool, number_separator: NumberSeparator, ) -> Vec { let mut signature_with_number_of_commits_sorted: Vec<(&Sig, &usize)> = Vec::from_iter(number_of_commits_by_signature); signature_with_number_of_commits_sorted.sort_by(|(sa, a_count), (sb, b_count)| { b_count.cmp(a_count).then_with(|| sa.name.cmp(&sb.name)) }); let authors: Vec = signature_with_number_of_commits_sorted .into_iter() .map(|(author, author_nbr_of_commits)| { Author::new( author.name.to_string(), if show_email { Some(author.email.to_string()) } else { None }, *author_nbr_of_commits, total_number_of_commits, number_separator, ) }) .take(number_of_authors_to_display) .collect(); authors } fn digit_difference(num1: usize, num2: usize) -> usize { let count_digits = |num: usize| (num.checked_ilog10().unwrap_or(0) + 1) as usize; count_digits(num1).abs_diff(count_digits(num2)) } impl std::fmt::Display for AuthorsInfo { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { let mut authors_info = String::new(); let pad = self.title().len() + 2; for (i, author) in self.authors.iter().enumerate() { if i == 0 { write!(authors_info, "{author}")?; } else { write!( authors_info, "\n{: String { self.to_string() } fn title(&self) -> String { let mut title: String = "Author".into(); if self.authors.len() > 1 { title.push('s'); } title } } #[cfg(test)] mod test { use super::*; use crate::ui::text_colors::TextColors; use insta::assert_snapshot; use owo_colors::DynColors; use rstest::rstest; #[test] fn test_display_author() { let author = Author::new( "John Doe".into(), Some("john.doe@email.com".into()), 1500, 2000, NumberSeparator::Plain, ); assert_eq!(author.to_string(), "75% John Doe 1500"); } #[test] fn test_display_author_with_no_email() { let author = Author::new("John Doe".into(), None, 1500, 2000, NumberSeparator::Plain); assert_eq!(author.to_string(), "75% John Doe 1500"); } #[test] fn test_authors_info_title_with_one_author() { let author = Author::new( "John Doe".into(), Some("john.doe@email.com".into()), 1500, 2000, NumberSeparator::Plain, ); let authors_info = AuthorsInfo { authors: vec![author], }; assert_eq!(authors_info.title(), "Author"); } #[test] fn test_authors_info_title_with_two_authors() { let author = Author::new( "John Doe".into(), Some("john.doe@email.com".into()), 1500, 2000, NumberSeparator::Plain, ); let author_2 = Author::new( "Roberto Berto".into(), None, 240, 300, NumberSeparator::Plain, ); let authors_info = AuthorsInfo { authors: vec![author, author_2], }; assert_eq!(authors_info.title(), "Authors"); } #[test] fn test_author_info_with_one_author() { let author = Author::new( "John Doe".into(), Some("john.doe@email.com".into()), 1500, 2000, NumberSeparator::Plain, ); let authors_info = AuthorsInfo { authors: vec![author], }; let colors = TextColors::new(&[], DynColors::Rgb(0xFF, 0xFF, 0xFF)); let mut buffer = String::new(); authors_info .write_styled(&mut buffer, false, &colors) .unwrap(); assert_snapshot!(buffer); } #[test] fn test_author_info_with_two_authors() { let author = Author::new( "John Doe".into(), Some("john.doe@email.com".into()), 1500, 2000, NumberSeparator::Plain, ); let author_2 = Author::new( "Roberto Berto".into(), None, 240, 300, NumberSeparator::Plain, ); let authors_info = AuthorsInfo { authors: vec![author, author_2], }; let colors = TextColors::new(&[], DynColors::Rgb(0xFF, 0xFF, 0xFF)); let mut buffer = String::new(); authors_info .write_styled(&mut buffer, false, &colors) .unwrap(); assert_snapshot!(buffer); } #[test] fn test_author_info_alignment_with_three_authors() { let author = Author::new( "John Doe".into(), Some("john.doe@email.com".into()), 1500, 2000, NumberSeparator::Plain, ); let author_2 = Author::new( "Roberto Berto".into(), None, 240, 300, NumberSeparator::Plain, ); let author_3 = Author::new("Jane Doe".into(), None, 1, 100, NumberSeparator::Plain); let authors_info = AuthorsInfo { authors: vec![author, author_2, author_3], }; let colors = TextColors::new(&[], DynColors::Rgb(0xFF, 0xFF, 0xFF)); let mut buffer = String::new(); authors_info .write_styled(&mut buffer, false, &colors) .unwrap(); assert_snapshot!(buffer); } #[rstest] #[case(456, 123, 0)] #[case(456789, 123, 3)] #[case(1, 12, 1)] fn test_digit_difference(#[case] num1: usize, #[case] num2: usize, #[case] expected: usize) { let result = digit_difference(num1, num2); assert_eq!(result, expected); } #[test] fn test_compute_authors() { let mut number_of_commits_by_signature: HashMap = HashMap::new(); number_of_commits_by_signature.insert( Sig { name: "John Doe".into(), email: "johndoe@example.com".into(), }, 30, ); number_of_commits_by_signature.insert( Sig { name: "Jane Doe".into(), email: "janedoe@example.com".into(), }, 20, ); number_of_commits_by_signature.insert( Sig { name: "Ellen Smith".into(), email: "ellensmith@example.com".into(), }, 50, ); let total_number_of_commits = 100; let number_of_authors_to_display = 2; let show_email = false; let number_separator = NumberSeparator::Comma; let actual = compute_authors( &number_of_commits_by_signature, total_number_of_commits, number_of_authors_to_display, show_email, number_separator, ); let expected = vec![ Author::new(String::from("Ellen Smith"), None, 50, 100, number_separator), Author::new(String::from("John Doe"), None, 30, 100, number_separator), ]; assert_eq!(actual, expected); } } ================================================ FILE: src/info/churn.rs ================================================ use super::utils::info_field::InfoField; use crate::{cli::NumberSeparator, info::utils::format_number}; use anyhow::Result; use gix::bstr::BString; use globset::{Glob, GlobSetBuilder}; use serde::Serialize; use std::{collections::HashMap, fmt::Write}; #[derive(Serialize, Clone, Debug, PartialEq)] #[serde(rename_all = "camelCase")] pub struct FileChurn { pub file_path: String, pub nbr_of_commits: usize, #[serde(skip_serializing)] number_separator: NumberSeparator, } impl FileChurn { pub fn new( file_path: String, nbr_of_commits: usize, number_separator: NumberSeparator, ) -> Self { Self { file_path, nbr_of_commits, number_separator, } } } impl std::fmt::Display for FileChurn { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!( f, "{} {}", shorten_file_path(&self.file_path, 2), format_number(&self.nbr_of_commits, self.number_separator) ) } } #[derive(Serialize)] pub struct ChurnInfo { pub file_churns: Vec, pub churn_pool_size: usize, } impl ChurnInfo { pub fn new( number_of_commits_by_file_path: &HashMap, churn_pool_size: usize, number_of_file_churns_to_display: usize, globs_to_exclude: &[String], number_separator: NumberSeparator, ) -> Result { let file_churns = compute_file_churns( number_of_commits_by_file_path, number_of_file_churns_to_display, globs_to_exclude, number_separator, )?; Ok(Self { file_churns, churn_pool_size, }) } } fn compute_file_churns( number_of_commits_by_file_path: &HashMap, number_of_file_churns_to_display: usize, globs_to_exclude: &[String], number_separator: NumberSeparator, ) -> Result> { let mut builder = GlobSetBuilder::new(); for glob in globs_to_exclude { builder.add(Glob::new(glob)?); } let glob_set = builder.build()?; let mut number_of_commits_by_file_path_sorted = Vec::from_iter(number_of_commits_by_file_path); number_of_commits_by_file_path_sorted .sort_by(|(_, a_count), (_, b_count)| b_count.cmp(a_count)); Ok(number_of_commits_by_file_path_sorted .into_iter() .filter_map(|(file_path, nbr_of_commits)| { if glob_set.is_match(file_path.to_string()) { None } else { Some(FileChurn::new( file_path.to_string(), *nbr_of_commits, number_separator, )) } }) .take(number_of_file_churns_to_display) .collect()) } impl std::fmt::Display for ChurnInfo { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { let mut churn_info = String::new(); let pad = self.title().len() + 2; for (i, file_churn) in self.file_churns.iter().enumerate() { if i == 0 { write!(churn_info, "{file_churn}")?; } else { write!(churn_info, "\n{: String { self.to_string() } fn title(&self) -> String { format!("Churn ({})", self.churn_pool_size) } } fn shorten_file_path(file_path: &str, depth: usize) -> String { let components: Vec<&str> = file_path.split('/').collect(); if depth == 0 || components.len() <= depth { return file_path.to_string(); } let truncated_components: Vec<&str> = components .iter() .skip(components.len() - depth) .copied() .collect(); format!("\u{2026}/{}", truncated_components.join("/")) } #[cfg(test)] mod tests { use super::*; #[test] fn test_display_file_churn() { let file_churn = FileChurn::new("path/to/file.txt".into(), 50, NumberSeparator::Plain); assert_eq!(file_churn.to_string(), "\u{2026}/to/file.txt 50"); } #[test] fn test_churn_info_value_with_two_file_churns() { let file_churn_1 = FileChurn::new("path/to/file.txt".into(), 50, NumberSeparator::Plain); let file_churn_2 = FileChurn::new("file_2.txt".into(), 30, NumberSeparator::Plain); let churn_info = ChurnInfo { file_churns: vec![file_churn_1, file_churn_2], churn_pool_size: 5, }; assert!( churn_info .value() .contains(&"\u{2026}/to/file.txt 50".to_string()) ); assert!(churn_info.value().contains(&"file_2.txt 30".to_string())); } #[test] fn test_truncate_file_path() { assert_eq!(shorten_file_path("path/to/file.txt", 3), "path/to/file.txt"); assert_eq!(shorten_file_path("another/file.txt", 2), "another/file.txt"); assert_eq!(shorten_file_path("file.txt", 1), "file.txt"); assert_eq!( shorten_file_path("path/to/file.txt", 2), "\u{2026}/to/file.txt" ); assert_eq!( shorten_file_path("another/file.txt", 1), "\u{2026}/file.txt" ); assert_eq!(shorten_file_path("file.txt", 0), "file.txt"); } #[test] fn test_compute_file_churns() -> Result<()> { let mut number_of_commits_by_file_path = HashMap::new(); number_of_commits_by_file_path.insert("path/to/file1.txt".into(), 2); number_of_commits_by_file_path.insert("path/to/file2.txt".into(), 5); number_of_commits_by_file_path.insert("path/to/file3.txt".into(), 3); number_of_commits_by_file_path.insert("path/to/file4.txt".into(), 7); number_of_commits_by_file_path.insert("foo/x/y/file.txt".into(), 70); number_of_commits_by_file_path.insert("foo/x/file.txt".into(), 10); let number_of_file_churns_to_display = 3; let number_separator = NumberSeparator::Comma; let globs_to_exclude = vec![ "foo/**/file.txt".to_string(), "path/to/file2.txt".to_string(), ]; let actual = compute_file_churns( &number_of_commits_by_file_path, number_of_file_churns_to_display, &globs_to_exclude, number_separator, )?; let expected = vec![ FileChurn::new(String::from("path/to/file4.txt"), 7, number_separator), FileChurn::new(String::from("path/to/file3.txt"), 3, number_separator), FileChurn::new(String::from("path/to/file1.txt"), 2, number_separator), ]; assert_eq!(actual, expected); Ok(()) } } ================================================ FILE: src/info/commits.rs ================================================ use super::git::metrics::GitMetrics; use crate::{ cli::NumberSeparator, info::utils::{format_number, info_field::InfoField}, }; use serde::Serialize; #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct CommitsInfo { pub number_of_commits: usize, is_shallow: bool, #[serde(skip_serializing)] number_separator: NumberSeparator, } impl CommitsInfo { pub fn new( git_metrics: &GitMetrics, is_shallow: bool, number_separator: NumberSeparator, ) -> Self { Self { number_of_commits: git_metrics.total_number_of_commits, is_shallow, number_separator, } } } #[typetag::serialize] impl InfoField for CommitsInfo { fn value(&self) -> String { format!( "{}{}", format_number(&self.number_of_commits, self.number_separator), if self.is_shallow { " (shallow)" } else { Default::default() } ) } fn title(&self) -> String { "Commits".into() } } #[cfg(test)] mod test { use super::*; #[test] fn test_display_commits_info() { let commits_info = CommitsInfo { number_of_commits: 3, is_shallow: false, number_separator: NumberSeparator::Plain, }; assert_eq!(commits_info.value(), "3".to_string()); } #[test] fn test_display_commits_info_shallow() { let commits_info = CommitsInfo { number_of_commits: 2, is_shallow: true, number_separator: NumberSeparator::Plain, }; assert_eq!(commits_info.value(), "2 (shallow)".to_string()); } } ================================================ FILE: src/info/contributors.rs ================================================ use super::utils::format_number; use crate::{cli::NumberSeparator, info::utils::info_field::InfoField}; use serde::Serialize; #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct ContributorsInfo { pub total_number_of_authors: usize, #[serde(skip_serializing)] pub number_of_authors_to_display: usize, #[serde(skip_serializing)] number_separator: NumberSeparator, } impl ContributorsInfo { pub fn new( total_number_of_authors: usize, number_of_authors_to_display: usize, number_separator: NumberSeparator, ) -> Self { Self { total_number_of_authors, number_of_authors_to_display, number_separator, } } } #[typetag::serialize] impl InfoField for ContributorsInfo { fn value(&self) -> String { if self.total_number_of_authors > self.number_of_authors_to_display { format_number(&self.total_number_of_authors, self.number_separator) } else { String::new() } } fn title(&self) -> String { "Contributors".into() } } #[cfg(test)] mod test { use super::*; #[test] fn test_display_contributors_info() { let contributors_info = ContributorsInfo::new(12, 2, NumberSeparator::Plain); assert_eq!(contributors_info.value(), "12".to_string()); assert_eq!(contributors_info.title(), "Contributors".to_string()); } #[test] fn test_display_contributors_less_than_authors_to_display() { let contributors_info = ContributorsInfo { total_number_of_authors: 1, number_of_authors_to_display: 3, number_separator: NumberSeparator::Plain, }; assert!(contributors_info.value().is_empty()); } } ================================================ FILE: src/info/created.rs ================================================ use super::{git::metrics::GitMetrics, utils::format_time}; use crate::info::utils::info_field::InfoField; use serde::Serialize; #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct CreatedInfo { pub creation_date: String, } impl CreatedInfo { pub fn new(iso_time: bool, git_metrics: &GitMetrics) -> Self { let creation_date = get_creation_date(git_metrics, iso_time); Self { creation_date } } } fn get_creation_date(git_metrics: &GitMetrics, iso_time: bool) -> String { format_time(git_metrics.time_of_first_commit, iso_time) } #[typetag::serialize] impl InfoField for CreatedInfo { fn value(&self) -> String { self.creation_date.to_string() } fn title(&self) -> String { "Created".into() } } #[cfg(test)] mod test { use super::*; #[test] fn test_display_created_info() { let created_info = CreatedInfo { creation_date: "2 years ago".to_string(), }; assert_eq!(created_info.value(), "2 years ago".to_string()); } } ================================================ FILE: src/info/dependencies.rs ================================================ use crate::{ cli::NumberSeparator, info::utils::{format_number, info_field::InfoField}, }; use onefetch_manifest::Manifest; use serde::Serialize; #[derive(Serialize)] pub struct DependenciesInfo { pub dependencies: String, } impl DependenciesInfo { pub fn new(manifest: Option<&Manifest>, number_separator: NumberSeparator) -> Self { let dependencies = manifest .and_then(|m| { (m.number_of_dependencies != 0).then(|| { format!( "{} ({})", format_number(&m.number_of_dependencies, number_separator), m.manifest_type ) }) }) .unwrap_or_default(); Self { dependencies } } } #[typetag::serialize] impl InfoField for DependenciesInfo { fn value(&self) -> String { self.dependencies.clone() } fn title(&self) -> String { "Dependencies".into() } } #[cfg(test)] mod test { use super::*; use onefetch_manifest::ManifestType; #[test] fn should_display_license() { let dependencies_info = DependenciesInfo::new( Some(&Manifest { manifest_type: ManifestType::Cargo, name: None, description: None, number_of_dependencies: 21, version: None, license: None, }), NumberSeparator::Plain, ); assert_eq!(dependencies_info.value(), "21 (Cargo)".to_string()); } } ================================================ FILE: src/info/description.rs ================================================ use crate::info::utils::info_field::InfoField; use onefetch_manifest::Manifest; use serde::Serialize; const NUMBER_OF_WORDS_PER_LINE: usize = 5; #[derive(Serialize)] pub struct DescriptionInfo { pub description: Option, } impl DescriptionInfo { pub fn new(manifest: Option<&Manifest>) -> Self { let description = match manifest { Some(m) => m.description.clone(), None => None, }; Self { description } } } #[typetag::serialize] impl InfoField for DescriptionInfo { fn value(&self) -> String { match &self.description { Some(description) => { let left_pad = self.title().len() + 2; break_sentence_into_lines(description, left_pad) } None => String::new(), } } fn title(&self) -> String { "Description".into() } } fn break_sentence_into_lines(sentence: &str, left_pad: usize) -> String { let words: Vec<&str> = sentence.split_whitespace().collect(); let mut lines = Vec::new(); for (i, chunk) in words.chunks(NUMBER_OF_WORDS_PER_LINE).enumerate() { let line = if i == 0 { chunk.join(" ") } else { format!("{:>width$}{}", "", chunk.join(" "), width = left_pad) }; lines.push(line); } lines.join("\n") } #[cfg(test)] mod test { use super::*; use onefetch_manifest::ManifestType; use rstest::rstest; #[test] fn should_display_description() { let description_info = DescriptionInfo::new(Some(&Manifest { manifest_type: ManifestType::Cargo, name: None, description: Some("test".into()), number_of_dependencies: 0, version: Some("0.1.0".into()), license: None, })); assert_eq!(description_info.value(), "test".to_string()); } #[rstest] #[case("Hello", "Hello")] #[case( "Hello world, how are you doing?", "Hello world, how are you\n doing?" )] #[case( "This is a long sentence that needs to be broken into multiple lines.", "This is a long sentence\n that needs to be broken\n into multiple lines." )] fn test_break_sentence_into_lines(#[case] sentence: &str, #[case] expected_result: &str) { assert_eq!(break_sentence_into_lines(sentence, 4), expected_result); } } ================================================ FILE: src/info/git/metrics.rs ================================================ use super::sig::Sig; use gix::bstr::BString; use gix::date::Time; use std::collections::HashMap; pub struct GitMetrics { pub number_of_commits_by_signature: HashMap, pub number_of_commits_by_file_path: HashMap, pub total_number_of_authors: usize, pub total_number_of_commits: usize, pub churn_pool_size: usize, pub time_of_most_recent_commit: gix::date::Time, pub time_of_first_commit: gix::date::Time, } impl GitMetrics { pub fn new( number_of_commits_by_signature: HashMap, number_of_commits_by_file_path: HashMap, churn_pool_size: usize, time_of_first_commit: Option