Full Code of XAMPPRocky/tokei for AI

master 505d6481c98c cached
258 files
525.5 KB
153.7k tokens
235 symbols
1 requests
Download .txt
Showing preview only (577K chars total). Download the full file or copy to clipboard to get everything.
Repository: XAMPPRocky/tokei
Branch: master
Commit: 505d6481c98c
Files: 258
Total size: 525.5 KB

Directory structure:
gitextract_x6tby1jr/

├── .git-blame-ignore-revs
├── .gitattributes
├── .github/
│   ├── FUNDING.yml
│   └── workflows/
│       ├── mean_bean_ci.yml
│       ├── mean_bean_deploy.yml
│       ├── publish_image.yaml
│       └── release-plz.yaml
├── .gitignore
├── .mailmap
├── .tokeignore
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Cargo.toml
├── Earthfile
├── LICENCE-APACHE
├── LICENCE-MIT
├── README.md
├── benchmark.sh
├── build.rs
├── ci/
│   ├── build.bash
│   ├── common.bash
│   ├── set_rust_version.bash
│   └── test.bash
├── fuzz/
│   ├── .gitignore
│   ├── Cargo.toml
│   ├── README.md
│   └── fuzz_targets/
│       ├── parse_from_slice.rs
│       ├── parse_from_slice_panic.rs
│       └── parse_from_slice_total.rs
├── languages.json
├── src/
│   ├── cli.rs
│   ├── cli_utils.rs
│   ├── config.rs
│   ├── consts.rs
│   ├── input.rs
│   ├── language/
│   │   ├── embedding.rs
│   │   ├── language_type.rs
│   │   ├── language_type.tera.rs
│   │   ├── languages.rs
│   │   ├── mod.rs
│   │   └── syntax.rs
│   ├── lib.rs
│   ├── main.rs
│   ├── sort.rs
│   ├── stats.rs
│   └── utils/
│       ├── ext.rs
│       ├── fs.rs
│       ├── macros.rs
│       └── mod.rs
├── tests/
│   ├── accuracy.rs
│   ├── data/
│   │   ├── Daml.daml
│   │   ├── Dockerfile
│   │   ├── MSBuild.csproj
│   │   ├── Makefile
│   │   ├── Modelica.mo
│   │   ├── NuGet.Config
│   │   ├── PKGBUILD
│   │   ├── Rakefile
│   │   ├── SConstruct
│   │   ├── Snakefile
│   │   ├── Tera.tera
│   │   ├── abnf.abnf
│   │   ├── alloy.als
│   │   ├── apl.apl
│   │   ├── arduino.ino
│   │   ├── arturo.art
│   │   ├── asciidoc.adoc
│   │   ├── asn1.asn1
│   │   ├── ats.dats
│   │   ├── awk.awk
│   │   ├── ballerina.bal
│   │   ├── bazel.bzl
│   │   ├── bean.bean
│   │   ├── bicep.bicep
│   │   ├── bitbake.bb
│   │   ├── bqn.bqn
│   │   ├── brightscript.brs
│   │   ├── c.c
│   │   ├── c3.c3
│   │   ├── cairo.cairo
│   │   ├── cangjie.cj
│   │   ├── chapel.chpl
│   │   ├── cil.cil
│   │   ├── circom.circom
│   │   ├── clojure.clj
│   │   ├── clojurec.cljc
│   │   ├── clojurescript.cljs
│   │   ├── cmake.cmake
│   │   ├── codeql.ql
│   │   ├── cogent.cogent
│   │   ├── cpp.cpp
│   │   ├── cppm.cppm
│   │   ├── crystal.cr
│   │   ├── csharp.cs
│   │   ├── cuda.cu
│   │   ├── cue.cue
│   │   ├── cython.pyx
│   │   ├── d.d
│   │   ├── d2.d2
│   │   ├── dhall.dhall
│   │   ├── dreammaker.dm
│   │   ├── dust.dust
│   │   ├── ebuild.ebuild
│   │   ├── edgeql.edgeql
│   │   ├── edn.edn
│   │   ├── eight.8th
│   │   ├── elvish.elv
│   │   ├── emacs_dev_env.ede
│   │   ├── emacs_lisp.el
│   │   ├── emojicode.🍇
│   │   ├── esdl.esdl
│   │   ├── example.umpl
│   │   ├── factor.factor
│   │   ├── fennel.fnl
│   │   ├── flatbuffers.fbs
│   │   ├── forgecfg.cfg
│   │   ├── fsharp.fs
│   │   ├── fstar.fst
│   │   ├── ftl.ftl
│   │   ├── futhark.fut
│   │   ├── gas.S
│   │   ├── gdb.gdb
│   │   ├── gdshader.gdshader
│   │   ├── gherkin.feature
│   │   ├── gleam.gleam
│   │   ├── glimmer_js.gjs
│   │   ├── glimmer_ts.gts
│   │   ├── gml.gml
│   │   ├── go.go
│   │   ├── gohtml.gohtml
│   │   ├── graphql.gql
│   │   ├── gwion.gw
│   │   ├── haml.haml
│   │   ├── hcl.tf
│   │   ├── headache.ha
│   │   ├── hex0.hex0
│   │   ├── hex1.hex1
│   │   ├── hex2.hex2
│   │   ├── hicad.mac
│   │   ├── hledger.hledger
│   │   ├── hpp.hpp
│   │   ├── html.html
│   │   ├── janet.janet
│   │   ├── java.java
│   │   ├── javascript.js
│   │   ├── jinja2.j2
│   │   ├── jq.jq
│   │   ├── jslt.jslt
│   │   ├── jsonnet.jsonnet
│   │   ├── jupyter.ipynb
│   │   ├── justfile
│   │   ├── k.k
│   │   ├── kaem.kaem
│   │   ├── kakoune_script.kak
│   │   ├── koka.kk
│   │   ├── ksh.ksh
│   │   ├── kvlanguage.kv
│   │   ├── lalrpop.lalrpop
│   │   ├── linguafranca.lf
│   │   ├── liquid.liquid
│   │   ├── livescript.ls
│   │   ├── llvm.ll
│   │   ├── logtalk.lgt
│   │   ├── lolcode.lol
│   │   ├── m1.m1
│   │   ├── m4.m4
│   │   ├── menhir.mly
│   │   ├── meson.build
│   │   ├── metal.metal
│   │   ├── mlatu.mlt
│   │   ├── moduledef.def
│   │   ├── mojo.mojo
│   │   ├── monkeyc.mc
│   │   ├── nextflow.nf
│   │   ├── nqp.nqp
│   │   ├── odin.odin
│   │   ├── open_policy_agent.rego
│   │   ├── openscad.scad
│   │   ├── opentype.fea
│   │   ├── org_mode.org
│   │   ├── pan.pan
│   │   ├── pcss.pcss
│   │   ├── pest.pest
│   │   ├── phix.e
│   │   ├── plantuml.puml
│   │   ├── pofile.po
│   │   ├── pofile_pot.pot
│   │   ├── poke.pk
│   │   ├── pony.pony
│   │   ├── postcss.sss
│   │   ├── powershell.ps1
│   │   ├── pug.pug
│   │   ├── puppet.pp
│   │   ├── pyret.arr
│   │   ├── python.py
│   │   ├── q.q
│   │   ├── qml.qml
│   │   ├── racket.rkt
│   │   ├── raku.raku
│   │   ├── razor.cshtml
│   │   ├── razorcomponent.razor
│   │   ├── redscript.reds
│   │   ├── renpy.rpy
│   │   ├── roc.roc
│   │   ├── ron.ron
│   │   ├── rpmspec.spec
│   │   ├── ruby.rb
│   │   ├── ruby_env
│   │   ├── ruby_html.erb
│   │   ├── rust.rs
│   │   ├── scheme.scm
│   │   ├── shaderlab.shader
│   │   ├── slang.slang
│   │   ├── slint.slint
│   │   ├── solidity.sol
│   │   ├── sql.sql
│   │   ├── srecode.srt
│   │   ├── stan.stan
│   │   ├── stata.do
│   │   ├── stratego.str
│   │   ├── stylus.styl
│   │   ├── svelte.svelte
│   │   ├── swift.swift
│   │   ├── swig.i
│   │   ├── tact.tact
│   │   ├── templ.templ
│   │   ├── thrift.thrift
│   │   ├── tsx.tsx
│   │   ├── ttcn.ttcn3
│   │   ├── twig.twig
│   │   ├── typescript.ts
│   │   ├── typst.typ
│   │   ├── uiua.ua
│   │   ├── unison.u
│   │   ├── urweb.ur
│   │   ├── urweb_urp.urp
│   │   ├── urweb_urs.urs
│   │   ├── vb6_bas.bas
│   │   ├── vb6_cls.cls
│   │   ├── vb6_frm.frm
│   │   ├── vbscript.vbs
│   │   ├── velocity.vm
│   │   ├── vhdl.vhd
│   │   ├── visualbasic.vb
│   │   ├── vqe.qasm
│   │   ├── vue.vue
│   │   ├── webassembly.wat
│   │   ├── wenyan.wy
│   │   ├── wgsl.wgsl
│   │   ├── xsl.xsl
│   │   ├── xtend.xtend
│   │   ├── yaml.yaml
│   │   ├── zencode.zs
│   │   ├── zig.zig
│   │   └── zokrates.zok
│   └── embedding/
│       └── file_triggeringprincipal_frame_1.html
└── tokei.example.toml

================================================
FILE CONTENTS
================================================

================================================
FILE: .git-blame-ignore-revs
================================================
# Format JSON
d7c548537cd5828b2d58e09f3207ddacc517b227
f356d27ab21e0f93839da90393c0edf9225740c2


================================================
FILE: .gitattributes
================================================
tests/data/* linguist-documentation


================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms

github: XAMPPRocky


================================================
FILE: .github/workflows/mean_bean_ci.yml
================================================
name: Mean Bean CI

on:
  push:
    branches:
      - master
  pull_request:

jobs:
  # This job downloads and stores `cross` as an artifact, so that it can be
  # redownloaded across all of the jobs. Currently this copied pasted between
  # `ci.yml` and `deploy.yml`. Make sure to update both places when making
  # changes.
  install-cross:
    runs-on: ubuntu-latest
    steps:
      - uses: XAMPPRocky/get-github-release@v1
        id: cross
        with:
          owner: rust-embedded
          repo: cross
          matches: ${{ matrix.platform }}
          token: ${{ secrets.GITHUB_TOKEN }}
      - uses: actions/upload-artifact@v4
        with:
          name: cross-${{ matrix.platform }}
          path: ${{ steps.cross.outputs.install_path }}
    strategy:
      matrix:
        platform: [linux-musl, apple-darwin]

  windows:
    runs-on: windows-latest
    # Windows technically doesn't need this, but if we don't block windows on it
    # some of the windows jobs could fill up the concurrent job queue before
    # one of the install-cross jobs has started, so this makes sure all
    # artifacts are downloaded first.
    needs: install-cross
    steps:
      - uses: actions/checkout@v3
      - run: ci/set_rust_version.bash ${{ matrix.channel }} ${{ matrix.target }}
        shell: bash
      - run: ci/build.bash cargo ${{ matrix.target }}
        shell: bash
      - run: ci/test.bash cargo ${{ matrix.target }}
        shell: bash

    strategy:
      fail-fast: true
      matrix:
        channel: [stable, beta, nightly]
        target:
          # MSVC
          - i686-pc-windows-msvc
          - x86_64-pc-windows-msvc
          # GNU: You typically only need to test Windows GNU if you're
          # specifically targeting it, and it can cause issues with some
          # dependencies if you're not so it's disabled by self.
          # - i686-pc-windows-gnu
          # - x86_64-pc-windows-gnu

  macos:
    runs-on: macos-latest
    needs: install-cross
    steps:
      - uses: actions/checkout@v3
      - uses: actions/download-artifact@v4
        with:
          name: cross-apple-darwin
          path: /usr/local/bin/

      - run: chmod +x /usr/local/bin/cross

      - run: ci/set_rust_version.bash ${{ matrix.channel }} ${{ matrix.target }}
      - run: ci/build.bash cross ${{ matrix.target }}
        # Only test on macOS platforms since we can't simulate iOS.
      - run: ci/test.bash cross ${{ matrix.target }}
        if: matrix.target == 'x86_64-apple-darwin'

    strategy:
      fail-fast: true
      matrix:
        channel: [stable, beta, nightly]
        target:
          # macOS
          - x86_64-apple-darwin
          # iOS
          - aarch64-apple-ios
          - x86_64-apple-ios

  linux:
    runs-on: ubuntu-latest
    needs: install-cross
    steps:
      - uses: actions/checkout@v3
      - name: Download Cross
        uses: actions/download-artifact@v4
        with:
          name: cross-linux-musl
          path: /tmp/
      - run: chmod +x /tmp/cross
      - run: ci/set_rust_version.bash ${{ matrix.channel }} ${{ matrix.target }}
      - run: ci/build.bash /tmp/cross ${{ matrix.target }}
        # These targets have issues with being tested so they are disabled
        # by default. You can try disabling to see if they work for
        # your project.
      - run: ci/test.bash /tmp/cross ${{ matrix.target }}
        if: |
          !contains(matrix.target, 'android') &&
          !contains(matrix.target, 'bsd') &&
          !contains(matrix.target, 'solaris') &&
          matrix.target != 'armv5te-unknown-linux-musleabi' &&
          matrix.target != 'sparc64-unknown-linux-gnu'

    strategy:
      fail-fast: true
      matrix:
        channel: [stable, beta, nightly]
        target:
          # WASM, off by default as most rust projects aren't compatible yet.
          # - wasm32-unknown-emscripten
          # Linux
          - aarch64-unknown-linux-gnu
          - aarch64-unknown-linux-musl
          - arm-unknown-linux-gnueabi
          - arm-unknown-linux-gnueabihf
          - arm-unknown-linux-musleabi
          - arm-unknown-linux-musleabihf
          - armv5te-unknown-linux-musleabi
          - armv7-unknown-linux-gnueabihf
          - armv7-unknown-linux-musleabihf
          - i586-unknown-linux-gnu
          - i586-unknown-linux-musl
          - i686-unknown-linux-gnu
          - i686-unknown-linux-musl
          # - mips-unknown-linux-gnu
          # - mips-unknown-linux-musl
          # - mips64-unknown-linux-gnuabi64
          # - mips64el-unknown-linux-gnuabi64
          # - mipsel-unknown-linux-gnu
          # - mipsel-unknown-linux-musl
          - powerpc-unknown-linux-gnu
          - powerpc64le-unknown-linux-gnu
          - s390x-unknown-linux-gnu
          - x86_64-unknown-linux-gnu
          - x86_64-unknown-linux-musl
          # Android
          # - aarch64-linux-android
          # - arm-linux-androideabi
          # - armv7-linux-androideabi
          # - i686-linux-android
          # - x86_64-linux-android
          # *BSD
          # The FreeBSD targets can have issues linking so they are disabled
          # by default.
          # - i686-unknown-freebsd
          # - x86_64-unknown-freebsd
          # - x86_64-unknown-netbsd
          # Solaris
          # - sparcv9-sun-solaris
          # - x86_64-sun-solaris
          # Bare Metal
          # These are no-std embedded targets, so they will only build if your
          # crate is `no_std` compatible.
          # - thumbv6m-none-eabi
          # - thumbv7em-none-eabi
          # - thumbv7em-none-eabihf
          # - thumbv7m-none-eabi


================================================
FILE: .github/workflows/mean_bean_deploy.yml
================================================
on:
  workflow_run:
    workflows: ["Release-plz"]
    branches: [master]
    types: 
      - completed

name: Mean Bean Deploy
env:
  BIN: tokei

jobs:
  # This job downloads and stores `cross` as an artifact, so that it can be
  # redownloaded across all of the jobs. Currently this copied pasted between
  # `ci.yml` and `deploy.yml`. Make sure to update both places when making
  # changes.
  install-cross:
    runs-on: ubuntu-latest
    steps:
      - uses: XAMPPRocky/get-github-release@v1
        id: cross
        with:
          owner: rust-embedded
          repo: cross
          matches: ${{ matrix.platform }}
          token: ${{ secrets.GITHUB_TOKEN }}
      - uses: actions/upload-artifact@v4
        with:
          name: cross-${{ matrix.platform }}
          path: ${{ steps.cross.outputs.install_path }}
    strategy:
      matrix:
        platform: [linux-musl, apple-darwin]

  windows:
    runs-on: windows-latest
    needs: install-cross
    strategy:
      matrix:
        target:
          # MSVC
          - i686-pc-windows-msvc
          - x86_64-pc-windows-msvc
          # GNU
          # - i686-pc-windows-gnu
          # - x86_64-pc-windows-gnu
    steps:
      - uses: actions/checkout@v3
      # FIXME: Hack around thinLTO being broken.
      - run: echo "RUSTFLAGS=-Clto=fat" >> $GITHUB_ENV
      - run: bash ci/set_rust_version.bash stable ${{ matrix.target }}
      - run: bash ci/build.bash cargo ${{ matrix.target }} RELEASE
        # We're using using a fork of `actions/create-release` that detects
        # whether a release is already available or not first.
      - uses: XAMPPRocky/create-release@v1.0.2
        id: create_release
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ github.ref }}
          release_name: ${{ github.ref }}
          # Draft should **always** be false. GitHub doesn't provide a way to
          # get draft releases from its API, so there's no point using it.
          draft: false
          prerelease: true
      - uses: actions/upload-release-asset@v1
        id: upload-release-asset
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }}
          asset_path: target/${{ matrix.target }}/release/${{ env.BIN }}.exe
          asset_name: ${{ env.BIN }}-${{ matrix.target }}.exe
          asset_content_type: application/zip

  macos:
    runs-on: macos-latest
    needs: install-cross
    strategy:
      matrix:
        target:
          # macOS
          - x86_64-apple-darwin
          # iOS
          # - aarch64-apple-ios
          # - armv7-apple-ios
          # - armv7s-apple-ios
          # - i386-apple-ios
          # - x86_64-apple-ios
    steps:
      - uses: actions/checkout@v3
      - uses: actions/download-artifact@v4
        with:
          name: cross-apple-darwin
          path: /usr/local/bin/
      - run: chmod +x /usr/local/bin/cross

      - run: ci/set_rust_version.bash stable ${{ matrix.target }}
      - run: ci/build.bash cross ${{ matrix.target }} RELEASE
      - run: tar -czvf ${{ env.BIN }}.tar.gz --directory=target/${{ matrix.target }}/release ${{ env.BIN }}
      - uses: XAMPPRocky/create-release@v1.0.2
        id: create_release
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ github.ref }}
          release_name: ${{ github.ref }}
          draft: false
          prerelease: true
      - uses: actions/upload-release-asset@v1
        id: upload-release-asset
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }}
          asset_path: ${{ env.BIN }}.tar.gz
          asset_name: ${{ env.BIN }}-${{ matrix.target }}.tar.gz
          asset_content_type: application/gzip

  linux:
    runs-on: ubuntu-latest
    needs: install-cross
    strategy:
      fail-fast: false
      matrix:
        target:
          # WASM, off by default as most rust projects aren't compatible yet.
          # - wasm32-unknown-emscripten
          # Linux
          - aarch64-unknown-linux-gnu
          - arm-unknown-linux-gnueabi
          - armv7-unknown-linux-gnueabihf
          - i686-unknown-linux-gnu
          - i686-unknown-linux-musl
          - mips-unknown-linux-gnu
          - mips64-unknown-linux-gnuabi64
          - mips64el-unknown-linux-gnuabi64
          - mipsel-unknown-linux-gnu
          - powerpc64-unknown-linux-gnu
          - powerpc64le-unknown-linux-gnu
          - s390x-unknown-linux-gnu
          - x86_64-unknown-linux-gnu
          - x86_64-unknown-linux-musl
          # Android
          - aarch64-linux-android
          - arm-linux-androideabi
          - armv7-linux-androideabi
          - i686-linux-android
          - x86_64-linux-android
          # *BSD
          # The FreeBSD targets can have issues linking so they are disabled
          # by default.
          # - i686-unknown-freebsd
          # - x86_64-unknown-freebsd
          - x86_64-unknown-netbsd
          # Solaris
          - sparcv9-sun-solaris
          # Bare Metal
          # These are no-std embedded targets, so they will only build if your
          # crate is `no_std` compatible.
          # - thumbv6m-none-eabi
          # - thumbv7em-none-eabi
          # - thumbv7em-none-eabihf
          # - thumbv7m-none-eabi
    steps:
      - uses: actions/checkout@v3
      - uses: actions/download-artifact@v4
        with:
          name: cross-linux-musl
          path: /tmp/
      - run: chmod +x /tmp/cross

      - run: ci/set_rust_version.bash stable ${{ matrix.target }}
      - run: ci/build.bash /tmp/cross ${{ matrix.target }} RELEASE
      - run: tar -czvf ${{ env.BIN }}.tar.gz --directory=target/${{ matrix.target }}/release ${{ env.BIN }}
      - uses: XAMPPRocky/create-release@v1.0.2
        id: create_release
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ github.ref }}
          release_name: ${{ github.ref }}
          draft: false
          prerelease: false
      - name: Upload Release Asset
        id: upload-release-asset
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }}
          asset_path: ${{ env.BIN }}.tar.gz
          asset_name: ${{ env.BIN }}-${{ matrix.target }}.tar.gz
          asset_content_type: application/gzip


================================================
FILE: .github/workflows/publish_image.yaml
================================================
name: Publish Docker Images

on:
  push:
    branches:
      - master
    tags:
      - v*

jobs:
  image:
    concurrency:
      group: ${{ github.workflow }}-${{ github.ref }}
      cancel-in-progress: true
    runs-on: ubuntu-latest
    permissions:
      packages: write
      contents: read
      attestations: write
    steps:
      - uses: earthly/actions-setup@v1
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
      - name: Check out the repo
        uses: actions/checkout@v4
      - name: Extract metadata (tags, labels) for Docker
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ghcr.io/${{ github.repository }}
          tags: |
            type=semver,pattern={{raw}}
            type=raw,value=latest,enable={{is_default_branch}}
      - name: Log in to the Container registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - name: Build and Push Docker Image
        run: echo "${{ steps.meta.outputs.tags }}" | xargs -I {} earthly --ci --push +docker --image_name="{}"


================================================
FILE: .github/workflows/release-plz.yaml
================================================
name: Release-plz

permissions:
  pull-requests: write
  contents: write

on:
  push:
    branches:
      - master

jobs:

  release-plz:
    name: Release-plz
    runs-on: ubuntu-22.04
    steps:
      - name: Checkout repository
        uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable
      - name: Run release-plz
        uses: MarcoIeni/release-plz-action@v0.5
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}


================================================
FILE: .gitignore
================================================
# Created by https://www.toptal.com/developers/gitignore/api/rust
# Edit at https://www.toptal.com/developers/gitignore?templates=rust

### Rust ###
# Generated by Cargo
# will have compiled files and executables
debug/
target/

# These are backup files generated by rustfmt
**/*.rs.bk

# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb

# End of https://www.toptal.com/developers/gitignore/api/rust


### IDE ###
.vscode
.idea/
*.iml

### Other ###

# macOS
.DS_Store

# settings
.settings
.tokeirc

# benchmark
results.csv

node_modules
*.code-workspace


================================================
FILE: .mailmap
================================================
Erin Power <xampprocky@gmail.com> <theaaronepower@gmail.com>
Erin Power <xampprocky@gmail.com> <Aaronepower@users.noreply.github.com>
Erin Power <xampprocky@gmail.com> <4464295+XAMPPRocky@users.noreply.github.com>
Erin Power <xampprocky@gmail.com> <aaron.power@softwaredesign.ie>


================================================
FILE: .tokeignore
================================================
tests/data
resources


================================================
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).

## [Unreleased]

## [14.0.0](https://github.com/XAMPPRocky/tokei/compare/v13.0.0...v14.0.0) - 2025-12-26

### Added

- add support for C++20 modules ([#1278](https://github.com/XAMPPRocky/tokei/pull/1278))
- Add language support for Ark TypeScript ([#1300](https://github.com/XAMPPRocky/tokei/pull/1300))

### Other

- Fix downcast type mismatches in clap_builder ([#1310](https://github.com/XAMPPRocky/tokei/pull/1310))
- remove tokei.rs references
- Add support for Koka ([#1306](https://github.com/XAMPPRocky/tokei/pull/1306))
- Stop recommending comma-separated CLI args ([#1305](https://github.com/XAMPPRocky/tokei/pull/1305))
- Update clap-cargo from 0.13 to 0.18 ([#1298](https://github.com/XAMPPRocky/tokei/pull/1298))

## [13.0.0-alpha.9](https://github.com/XAMPPRocky/tokei/compare/v13.0.0-alpha.8...v13.0.0-alpha.9) - 2025-07-21

### Other

- Update README.md
- Fix CRLF or mixed CRLF/LF line terminations in Markdown files ([#1219](https://github.com/XAMPPRocky/tokei/pull/1219))
- Fix a minor typo in CLI help text ([#1217](https://github.com/XAMPPRocky/tokei/pull/1217))
- Fix a missing space in CLI help text ([#1218](https://github.com/XAMPPRocky/tokei/pull/1218))
- Relax lifetime constraints in language::embedding ([#1225](https://github.com/XAMPPRocky/tokei/pull/1225))

## [13.0.0-alpha.8](https://github.com/XAMPPRocky/tokei/compare/v13.0.0-alpha.7...v13.0.0-alpha.8) - 2025-01-14

### Other

- add Mojo support ([#1107](https://github.com/XAMPPRocky/tokei/pull/1107)) ([#1185](https://github.com/XAMPPRocky/tokei/pull/1185))
- Add support for 8th language ([#1192](https://github.com/XAMPPRocky/tokei/pull/1192))
- Add support for `Roc` language ([#1197](https://github.com/XAMPPRocky/tokei/pull/1197))
- Add support for Ballerina language ([#1196](https://github.com/XAMPPRocky/tokei/pull/1196))
- Remove 'conf' extension from the Bitbake config. ([#1001](https://github.com/XAMPPRocky/tokei/pull/1001))
- Add support for Cairo language ([#1193](https://github.com/XAMPPRocky/tokei/pull/1193))
- Add support for Uiua language ([#1191](https://github.com/XAMPPRocky/tokei/pull/1191))

## [13.0.0-alpha.7](https://github.com/XAMPPRocky/tokei/compare/v13.0.0-alpha.6...v13.0.0-alpha.7) - 2024-11-10

### Other

- Fix alternative output formats ([#1188](https://github.com/XAMPPRocky/tokei/pull/1188))
- Add missing extension `fsti` for F* ([#1184](https://github.com/XAMPPRocky/tokei/pull/1184))

## [13.0.0-alpha.6](https://github.com/XAMPPRocky/tokei/compare/v13.0.0-alpha.5...v13.0.0-alpha.6) - 2024-10-11

### Added

- add `mbti` extension for MoonBit ([#1168](https://github.com/XAMPPRocky/tokei/pull/1168))

### Other

- Add language definition for Lauterbach PRACTICE Script ([#1162](https://github.com/XAMPPRocky/tokei/pull/1162))
- Add support for justfiles ([#1175](https://github.com/XAMPPRocky/tokei/pull/1175))
- Add Virgil ([#1178](https://github.com/XAMPPRocky/tokei/pull/1178))
- Add templ support ([#1122](https://github.com/XAMPPRocky/tokei/pull/1122))
- Update README.md with HiCAD from d4a1814 ([#1143](https://github.com/XAMPPRocky/tokei/pull/1143))
- Add BQN support ([#1151](https://github.com/XAMPPRocky/tokei/pull/1151))
- add more extensions for `Hlsl` ([#1164](https://github.com/XAMPPRocky/tokei/pull/1164))
- Add Phix ([#1167](https://github.com/XAMPPRocky/tokei/pull/1167))
- Add APL support ([#1152](https://github.com/XAMPPRocky/tokei/pull/1152))
- Add support for SIL ([#1153](https://github.com/XAMPPRocky/tokei/pull/1153))
- Use `OR` operator in Cargo.toml `license` field ([#1165](https://github.com/XAMPPRocky/tokei/pull/1165))
- Disable legacy Cargo features ([#1158](https://github.com/XAMPPRocky/tokei/pull/1158))
- add slint language support ([#1054](https://github.com/XAMPPRocky/tokei/pull/1054))
- Add Pyret support ([#1032](https://github.com/XAMPPRocky/tokei/pull/1032))
- Recognize GNUmakefile ([#1021](https://github.com/XAMPPRocky/tokei/pull/1021))

## [13.0.0-alpha.5](https://github.com/XAMPPRocky/tokei/compare/v13.0.0-alpha.4...v13.0.0-alpha.5) - 2024-08-23

### Fixed
- fix issue https://github.com/XAMPPRocky/tokei/issues/1147 ([#1149](https://github.com/XAMPPRocky/tokei/pull/1149))

### Other
- Fix issue [#1145](https://github.com/XAMPPRocky/tokei/pull/1145) (part 2) ([#1148](https://github.com/XAMPPRocky/tokei/pull/1148))

## [13.0.0-alpha.4](https://github.com/XAMPPRocky/tokei/compare/v13.0.0-alpha.3...v13.0.0-alpha.4) - 2024-08-22

### Fixed
- fix issue https://github.com/XAMPPRocky/tokei/issues/1145 ([#1146](https://github.com/XAMPPRocky/tokei/pull/1146))

### Other
- Add support for Glimmer JS/TS ([#1052](https://github.com/XAMPPRocky/tokei/pull/1052))
- Fix issue [#1141](https://github.com/XAMPPRocky/tokei/pull/1141) ([#1142](https://github.com/XAMPPRocky/tokei/pull/1142))

## [13.0.0-alpha.3](https://github.com/XAMPPRocky/tokei/compare/v13.0.0-alpha.2...v13.0.0-alpha.3) - 2024-08-20

### Fixed
- fix issue https://github.com/XAMPPRocky/tokei/issues/1138 ([#1139](https://github.com/XAMPPRocky/tokei/pull/1139))

## [13.0.0-alpha.2](https://github.com/XAMPPRocky/tokei/compare/v13.0.0-alpha.1...v13.0.0-alpha.2) - 2024-08-19

### Added
- Add support for Monkey C ([#1081](https://github.com/XAMPPRocky/tokei/pull/1081))
- added plantuml support ([#1125](https://github.com/XAMPPRocky/tokei/pull/1125))
- add language Tact ([#1103](https://github.com/XAMPPRocky/tokei/pull/1103))
- add support for bicep ([#1100](https://github.com/XAMPPRocky/tokei/pull/1100))
- add hledger ([#1121](https://github.com/XAMPPRocky/tokei/pull/1121))
- add SELinux CIL policy source files ([#1124](https://github.com/XAMPPRocky/tokei/pull/1124))
- --files argument now sorts alphabetically ([#1059](https://github.com/XAMPPRocky/tokei/pull/1059))
- add support for LALRPOP ([#1077](https://github.com/XAMPPRocky/tokei/pull/1077))

### Fixed
- read hidden from config file ([#1093](https://github.com/XAMPPRocky/tokei/pull/1093))

### Other
- Fix cargo audit issues ([#1137](https://github.com/XAMPPRocky/tokei/pull/1137))
- Add support for MDX ([#1046](https://github.com/XAMPPRocky/tokei/pull/1046))
- Add PRQL to README.md ([#1088](https://github.com/XAMPPRocky/tokei/pull/1088))
- add fypp extension `.fpp` to `languages.json` for Modern Fortran ([#1060](https://github.com/XAMPPRocky/tokei/pull/1060))
- Add support for Lex ([#1087](https://github.com/XAMPPRocky/tokei/pull/1087))
- Add d2 ([#1091](https://github.com/XAMPPRocky/tokei/pull/1091))
- Add support for Stata ([#1112](https://github.com/XAMPPRocky/tokei/pull/1112))
- Add support for CUE ([#1049](https://github.com/XAMPPRocky/tokei/pull/1049))
- bump libc from 0.2.147 to 0.2.155 ([#1104](https://github.com/XAMPPRocky/tokei/pull/1104))
- add cangjie language support ([#1127](https://github.com/XAMPPRocky/tokei/pull/1127)) ([#1128](https://github.com/XAMPPRocky/tokei/pull/1128))
- Add support for JSLT ([#1129](https://github.com/XAMPPRocky/tokei/pull/1129))
- Add Arturo support ([#1108](https://github.com/XAMPPRocky/tokei/pull/1108))
- Support Bazel's MODULE files and *.bzlmod files ([#1130](https://github.com/XAMPPRocky/tokei/pull/1130))
- read only first 128B from the file when searching for shebang ([#1040](https://github.com/XAMPPRocky/tokei/pull/1040))
- add OpenCL as a languages.json entry ([#980](https://github.com/XAMPPRocky/tokei/pull/980))
- Add GetText Portable Object (PO) files ([#814](https://github.com/XAMPPRocky/tokei/pull/814))
- Support godot shader ([#1118](https://github.com/XAMPPRocky/tokei/pull/1118))
- Add Modelica language ([#1061](https://github.com/XAMPPRocky/tokei/pull/1061))
- Add menhir support ([#781](https://github.com/XAMPPRocky/tokei/pull/781))
- Update README.md
- [issue_1114] remove Cargo.lock from .gitignore ([#1115](https://github.com/XAMPPRocky/tokei/pull/1115))
- [issue_891] give more space for Files column ([#933](https://github.com/XAMPPRocky/tokei/pull/933))
- GitHub Action to publish docker images ([#1096](https://github.com/XAMPPRocky/tokei/pull/1096))
- Support MoonBit language. ([#1095](https://github.com/XAMPPRocky/tokei/pull/1095))
- Add OpenSCAD ([#1097](https://github.com/XAMPPRocky/tokei/pull/1097))
- add jinja extension for Jinja2 ([#1083](https://github.com/XAMPPRocky/tokei/pull/1083))
- Fix slang ([#1089](https://github.com/XAMPPRocky/tokei/pull/1089))
- Temporarily remove Hare
- Support .pyi python file ([#1075](https://github.com/XAMPPRocky/tokei/pull/1075))
- add luau extension to lua ([#1066](https://github.com/XAMPPRocky/tokei/pull/1066))
- Adding support for Snakemake ([#1045](https://github.com/XAMPPRocky/tokei/pull/1045))
- Add Janet to languages.json ([#1042](https://github.com/XAMPPRocky/tokei/pull/1042))
- Add OpenQASM support ([#1041](https://github.com/XAMPPRocky/tokei/pull/1041))
- typst ([#1037](https://github.com/XAMPPRocky/tokei/pull/1037))
- Add the ZoKrates language ([#1035](https://github.com/XAMPPRocky/tokei/pull/1035))
- Add PRQL ([#1030](https://github.com/XAMPPRocky/tokei/pull/1030))
- remove refs ([#1006](https://github.com/XAMPPRocky/tokei/pull/1006))
- Add lingua franca language ([#993](https://github.com/XAMPPRocky/tokei/pull/993))
- Add support for Razor Components ([#992](https://github.com/XAMPPRocky/tokei/pull/992))
- Add arch's PKGBUILD files ([#972](https://github.com/XAMPPRocky/tokei/pull/972))
- Add Hare support ([#971](https://github.com/XAMPPRocky/tokei/pull/971))
- Add Max support ([#963](https://github.com/XAMPPRocky/tokei/pull/963))
- Add support for Chapel ([#960](https://github.com/XAMPPRocky/tokei/pull/960))
- Add language support for Slang ([#956](https://github.com/XAMPPRocky/tokei/pull/956))
- Update TypeScript language ([#953](https://github.com/XAMPPRocky/tokei/pull/953))
- Added support for Circom ([#949](https://github.com/XAMPPRocky/tokei/pull/949))
- link to earthly project ([#1078](https://github.com/XAMPPRocky/tokei/pull/1078))

## [13.0.0-alpha.1](https://github.com/XAMPPRocky/tokei/compare/v13.0.0-alpha.0...v13.0.0-alpha.1) - 2024-03-04

### Fixed
- fixed language names not showing when in Light mode (light background) ([#1048](https://github.com/XAMPPRocky/tokei/pull/1048))

### Other
- Create release-plz.yaml
- Update mean_bean_ci.yml
- Fix LD Script language data ([#1028](https://github.com/XAMPPRocky/tokei/pull/1028))
- Fix language data example in CONTRIBUTING.md ([#1029](https://github.com/XAMPPRocky/tokei/pull/1029))
- Update dependencies
- Add widget install instructions
- Update mean_bean_ci.yml
- Dockerize tokei ([#930](https://github.com/XAMPPRocky/tokei/pull/930))
- Ignore format commits for `languages.json` ([#1013](https://github.com/XAMPPRocky/tokei/pull/1013))
- Upgrade GitHub Actions ([#955](https://github.com/XAMPPRocky/tokei/pull/955))
- add --languages ouput formatter ([#1007](https://github.com/XAMPPRocky/tokei/pull/1007))
- Add Nuget Config, Bazel and EdgeQL Support, Fix Output Formatter ([#999](https://github.com/XAMPPRocky/tokei/pull/999))
- show nushell in the readme ([#991](https://github.com/XAMPPRocky/tokei/pull/991))
- Add support for Redscript ([#994](https://github.com/XAMPPRocky/tokei/pull/994))
- Add support for jq ([#965](https://github.com/XAMPPRocky/tokei/pull/965))
- Add support for Astro ([#966](https://github.com/XAMPPRocky/tokei/pull/966))
- Use XDG conventions on macOS too ([#989](https://github.com/XAMPPRocky/tokei/pull/989))
- Add JSON5 support for languages.json ([#986](https://github.com/XAMPPRocky/tokei/pull/986))
- Delete Smalltalk.cs.st ([#990](https://github.com/XAMPPRocky/tokei/pull/990))
- Add support for smalltalk ([#839](https://github.com/XAMPPRocky/tokei/pull/839))
- Disable *-android
- Add HiCAD to languages.json ([#985](https://github.com/XAMPPRocky/tokei/pull/985))
- Add Nushell to languages.json ([#982](https://github.com/XAMPPRocky/tokei/pull/982))
# 12.1.0

## Introduction
Tokei is a fast and accurate code analysis CLI tool and library, allowing you to
easily and quickly see how many blank lines, comments, and lines of code are in
your codebase. All releases and work on Tokei and tokei.rs ([the free companion
badge service][rs-info]) are [funded by the community through
GitHub Sponsors][sponsor].

You can always download the latest version of tokei through GitHub Releases or
Cargo. Tokei is also available through other [package managers][pkg], though
they may not always contain the latest release.

```
cargo install tokei
```

[pkg]: https://github.com/XAMPPRocky/tokei#package-managers
[rs-info]: https://github.com/XAMPPRocky/tokei/blob/master/README.md#Badges
[sponsor]: https://github.com/sponsors/XAMPPRocky

## What's New?

- [Added `-n/--num-format=[commas, dots, plain, underscores]` for adding
  separator formatting for numbers.](https://github.com/XAMPPRocky/tokei/pull/591)
- [The total is now included in output formats such as JSON.](https://github.com/XAMPPRocky/tokei/pull/580)
- [`--no-ignore` now implies other ignore flags.](https://github.com/XAMPPRocky/tokei/pull/588)
- [Added `--no-ignore-dot` flag to ignore files such as `.ignore`.](https://github.com/XAMPPRocky/tokei/pull/588)
- [Added single line comments to F\*](https://github.com/XAMPPRocky/tokei/pull/670)
- Updated various dependencies.

### Added Languages

- [ABNF](https://github.com/XAMPPRocky/tokei/pull/577)
- [CodeQL](https://github.com/XAMPPRocky/tokei/pull/604)
- [LiveScript](https://github.com/XAMPPRocky/tokei/pull/607)
- [Stylus](https://github.com/XAMPPRocky/tokei/pull/619)
- [DAML](https://github.com/XAMPPRocky/tokei/pull/620)
- [Tera](https://github.com/XAMPPRocky/tokei/pull/627)
- [TTCN-3](https://github.com/XAMPPRocky/tokei/pull/621)
- [Beancount](https://github.com/XAMPPRocky/tokei/pull/630)
- [Gleam](https://github.com/XAMPPRocky/tokei/pull/646)
- [JSONNet](https://github.com/XAMPPRocky/tokei/pull/634)
- [Stan](https://github.com/XAMPPRocky/tokei/pull/633)
- [Gwion](https://github.com/XAMPPRocky/tokei/pull/659)

# 12.0.0

## What's New? 
Tokei 12 comes with some of the biggest user facing changes since 1.0, now in
the latest version tokei will now **analyse and count multiple languages
embedded in your source code** as well as adding support for
**Jupyter Notebooks**. Now for the first time is able to handle and display
different languages contained in a single source file. This is currently available
for a limited set of languages, with plans to add more support for more in the
future. The currently supported languages are;

### HTML + Siblings (Vue, Svelte, Etc...)
Tokei will now analyse and report the source code contained in `<script>`,
`<style>`, and `<template>` tags in HTML and other similar languages. Tokei will
read the value of the`type` attribute from the `<script>` tag and detects the
appropriate language based on its mime type or JavaScript if not present. Tokei
will do the same for `<style>` and `<template>` except reading the `lang`
attribute instead of `type` and defaulting to CSS and HTML each respectively.

### Jupyter Notebooks
Tokei will now read Jupyter Notebook files (`.ipynb`) and will read the source
code and markdown from Jupyter's JSON and output the analysed result.

### Markdown
Tokei will now detect any code blocks marked with specified source language and
count each as their respective languages or as Markdown if not present or not
found. Now you can easily see how many code examples are included in
your documentation.

### Rust
Tokei will now detect blocks of rustdoc documentation  (e.g. `///`/`//!`) and
parse them as markdown.

### Verbatim Strings
Tokei is now also capable of handling "verbatim" strings, which are strings that
do not accept escape sequences like `\`. Thanks to @NickHackman for providing
the implementation! This is initially supported for C++, C#, F#, and Rust.

## New Look
To be able to show these new features, tokei's output has been changed to look
like below. For brevity the CLI only displays one level deep in each language,
however the library's parser is fully recursive and you can get access to the
complete report using the library or by outputting the JSON format.

```
===============================================================================
 Language            Files        Lines         Code     Comments       Blanks
===============================================================================
 BASH                    4           49           30           10            9
 JSON                    1         1332         1332            0            0
 Shell                   1           49           38            1           10
 TOML                    2           77           64            4            9
-------------------------------------------------------------------------------
 Markdown                5         1230            0          965          265
 |- JSON                 1           41           41            0            0
 |- Rust                 2           53           42            6            5
 |- Shell                1           22           18            0            4
 (Total)                           1346          101          971          274
-------------------------------------------------------------------------------
 Rust                   19         3349         2782          116          451
 |- Markdown            12          351            5          295           51
 (Total)                           3700         2787          411          502
===============================================================================
 Total                  32         6553         4352         1397          804
===============================================================================
```

This feature is not just limited to the default output of tokei. You can see it
broken down by each file with the `--files` option.

```
===============================================================================
 Language            Files        Lines         Code     Comments       Blanks
===============================================================================
 Markdown                5         1230            0          965          265
 |- JSON                 1           41           41            0            0
 |- Rust                 2           53           42            6            5
 |- Shell                1           22           18            0            4
 (Total)                           1346          101          971          274
-------------------------------------------------------------------------------
 ./CODE_OF_CONDUCT.md                46            0           28           18
 ./CHANGELOG.md                     570            0          434          136
-- ./markdown.md --------------------------------------------------------------
 |- Markdown                          4            0            3            1
 |- Rust                              6            4            1            1
 |- (Total)                          10            4            4            2
-- ./README.md ----------------------------------------------------------------
 |- Markdown                        498            0          421           77
 |- Shell                            22           18            0            4
 |- (Total)                         520           18          421           81
-- ./CONTRIBUTING.md ----------------------------------------------------------
 |- Markdown                        112            0           79           33
 |- JSON                             41           41            0            0
 |- Rust                             46           38            4            4
 |- (Total)                         200           79           84           37
===============================================================================
 Total                   5         1346          101          971          274
===============================================================================
```

## Breaking Changes
- The JSON Output and format of `Languages` has changed.
- The JSON feature has been removed and is now included by default.
- `Stats` has been split into `Report` and `CodeStats` to better represent the
  separation between analysing a file versus a blob of code.

# 11.2.0

- @alexmaco Added shebang and env detection for Crystal.
- @NickHackman Updated both Vue and HTML to count CSS & JS comments as comments.
- @XAMPPRocky renamed Perl6's display name to Rakudo.
- @dbackeus Added `erb` extension for Ruby HTML.
- @kobataiwan Tokei will now check for a configuration file in your home
  directory as well as your current and configuration directory.
- @dependabot Updated dependencies

**Added Languages**
- @alexmaco Dhall
- @NickHackman Svelte
- @athas Futhark
- @morphy2k Gohtml
- @LucasMW Headache
- @rosasynstylae Tsx
- @XAMPPRocky OpenType Feature Files

# 11.1.0

**Added Languages**

- @rubdos Arduino
- @LuqueDaniel Pan
- @itkovian Ren'Py

- Added `LanguageType::shebangs`, `LanguageType::from_file_extension`, and
  `LanguageType::from_shebang`. (@solanav)


# 11.0.0

**Added languages**

- @bwidawsk GNU Assembly, GDB Script
- @isker Dust, Apache Velocity
- @andreblanke FreeMarker


Thanks to some major internal refactoring, Tokei has received significant
performance improvements, and is now one of the fastest code counters across any
size of codebase. With Tokei 11 showing up to 40–60% faster results than tokei's
previous version. To showcase the improvements I've highlighted benchmarks
of counting five differently sized codebases. Redis (~220k lines), Rust (~16M
lines), and the Unreal Engine (~37.5M lines). In every one of these benchmarks
Tokei 11 performed the best by a noticeable margin.

*All benchmarks were done on a 15-inch MacBook Pro, with a 2.7GHz Intel Core i7
processor and 16GB 2133 MHz LPDDR3 RAM running macOS Catalina 10.15.3. Your
mileage may vary, All benchmarks were done using [hyperfine], using default
settings for all programs.*

[hyperfine]: https://github.com/sharkdp/hyperfine

### Tokei
**Note** This benchmark is not accurate due to `tokei` and `loc` both taking
less than 5ms to complete, there is a high degree of error between the times and
should mostly be considered equivalent. However it is included because it is
notable that `scc` takes nearly 3x as long to complete on smaller codebases
(~5k lines).
![Graph comparing programs running on the tokei source code](https://docs.google.com/spreadsheets/d/e/2PACX-1vRN2Um3G9Mn4Bg6UVWwgntsMy4faZMIP3EDjAfY5Y6Tav7T5z1TxVKmPu7wUNIpUSsSJDfCNH0SAKBB/pubchart?oid=1242634543&format=image)

### Redis
![Graph comparing programs running on the redis source code](https://docs.google.com/spreadsheets/d/e/2PACX-1vRN2Um3G9Mn4Bg6UVWwgntsMy4faZMIP3EDjAfY5Y6Tav7T5z1TxVKmPu7wUNIpUSsSJDfCNH0SAKBB/pubchart?oid=2009389097&format=image)

### Rust
![Graph comparing programs running on the rust source code](https://docs.google.com/spreadsheets/d/e/2PACX-1vRN2Um3G9Mn4Bg6UVWwgntsMy4faZMIP3EDjAfY5Y6Tav7T5z1TxVKmPu7wUNIpUSsSJDfCNH0SAKBB/pubchart?oid=424069399&format=image)

### Unreal
![Graph comparing programs running on the unreal source code](https://docs.google.com/spreadsheets/d/e/2PACX-1vRN2Um3G9Mn4Bg6UVWwgntsMy4faZMIP3EDjAfY5Y6Tav7T5z1TxVKmPu7wUNIpUSsSJDfCNH0SAKBB/pubchart?oid=439405321&format=image)

# 10.1.2

- Added `pyw` extension to Python.
- Updated dependencies

# 10.1.1

- Fixed `.tokeignore` always working even when `--no-ignore` is present.
- Updated dependencies

**Added languages**

- @erikaxel Gherkin (Cucumber)

# 10.1.0

- Added `cjsx` extension to CoffeeScript.
- Tokei will now recognise files with `#!/usr/bin/env ruby` as Ruby.
- Updated dependencies.
- Tokei now uses `crossbeam` channels over `std::mpsc`, which should have a
  noticeable performance improvement on large repos.
- Improved documentation for `libtokei`.

**Added languages**

- @lzybkr PowerShell
- @turbo MoonScript
- @dtolnay Thrift
- @Tranzystorek FlatBuffers
- @NieDzejkob Emojicode
- @DanteFalzone0 HolyC
- @sci4me Odin
- @fkarg Rusty Object Notation (RON)

# 10.0.0

- Fixed minor parsing bugs.
- Width is now limited to 80 unless you use the `--files` flag.
- Added the `mjs` extension to JavaScript.
- Added the `tpp` extension to C++.
- You can now disable Tokei's git ignore detection, similar to ripgrep. See
  `--help` for options.
- You can now add a `.tokeignore` file to your project to specify file paths
  for tokei to always ignore. This file uses the same syntax as `.gitignore`.
- Improved Pascal representation

**Added languages**

- @hobofan solidity
- @stefanmaric GraphQL
- @jhpratt PostCSS
- @evitalis RPM
- @alexmaco Pony
- @yjhmelody WASM, LLVM, Pest
- @XAMPPRocky ASN.1

# 9.0.0

- Tokei now has config files. You can now specify some commonly used arguments
  in a `.tokeirc`/`tokei.toml`. Namely `columns` to set the default column
  output, `types` to filter your count to just a single set of languages, and
  `treat_doc_strings_as_comments` which is a new option that allows you to
  specify whether to treat doc strings such as `"""` in Python as comments
  or code.
  The config files can be specified in two places, the current directory tokei
  is running in and your [system configuration
  directory](//docs.rs/tokei/struct.Config.html#method.from_config_files). The
  priority of options is as follows
  `CLI > <current_directory> > <configuration_directory>`.
- Tokei is now available on [Conda](https://anaconda.org/conda-forge/tokei).
- [Tokei's README has been translated
  to chinese.](https://github.com/chinanf-boy/tokei-zh#tokei-)
- `LanguageType` now implements `Hash`.
- Tokei now batches its console output, this should result in a small
  performance boost.
- There is now a `--columns` argument for manually setting tokei's output width.
- The `--sort` argument is now case-insensitive.
- Tokei will now mark languages who's files failed to parse correctly as
  potentially inaccurate.
- Due to a bug in trust-ci `x86_64-unknown-netbsd` versions will not be
  available in GitHub releases. (You will still be able to install from source.)
- Due to toml-rs's lacking enum support the TOML output option has
  been disabled.

**Added languages**

- @t-richards Liquid
- @diaphore Added the `.glsl` extension to GLSL.
- @ahmedelgabri Twig
- @pmoura Logtalk
- @alekratz Perl, Not Quite Perl
- @XAMPPRocky Automake, .NET Resource, HLSL, INI, Unreal Plugin,
  Unreal Project, Unreal Shader, Unreal Shader Header, Unreal Markdown,
  Visual Basic, Visual Studio Solution, Visual Studio Project, Xcode Config,
- @TheMrNomis SWIG
- @xnorme Added the `.vhdl` extension to VHDL

# 8.0.0

- A language's comments, and quotes are now available through the `LanguageType`
  enum.
- You can filter by language using the `-t/--type` option. e.g. `tokei -t "Rust,C"`
  will print only Rust and C files.
- Tokei now understands terminal width and will expand to fit it. (Thanks
  to @Veykril)
- Added [comparison](./COMPARISON.md) document to compare Tokei to other
  code counters.
- Updated dependencies

**Added languages**

- @BrandonBoone VB6, VBScript, XSLT
- @ialpert BrightScript
- @PJB3005 Dream Maker
- @schmee edn

# 7.0.3

Made various optimisations, up to 65% faster in some cases.

**Added languages**

- @DenialAdams Added Forsyth-Edwards-Notation (FEN)
- @DjebbZ Added ClojureC
- @grimm26 Added HCL/Terraform

# 7.0.2

- Updated dependencies.
- Changed how compilied serialization formats are handled.
- Fixed minor parser inaccuracies.
- Tokei should now recognise more python files from their shebang.

**Added languages**

- @ignatenko Added Meson
- @sprang Added Scheme
- @fengcms Added Vue
- @mark.knol Added Haxe
- @rleungx Added ABAP, COBOL, and Groovy
- @tiehuis Added Zig
- @murielsilveira Added Mint
- @notramo Added Elvish Shell and Kakoune
- @aatxe Added Racket
- @kamilchm Added ReasonML
- @cyplp Added XSL

# 7.0.1

- Updated dependencies

# 7.0.0

- Fixed parsing corner cases
- Changed storage of comments and quotes from `Vec` to static slices.
- Added tracing for debugging single files. Not recommended for use on
  multiple file
- Updated `log`

# 6.1.0

- Fixed inaccuracies relating to the end comment being smaller than start
  comment.

**Added languages**

- @mattico Added Xaml
- @weakish Added Ceylon
- @theduke Added tsx extension to typescript
- @vmchale Added Hamlet, Cassius, Lucius, Cabal, Nix, Happy, Alex, and Madlang
- @notramo Added Crystal

# 6.0.2

- Now can recognise file languages based on their filename.

**Added Languages:**

- @kazimuth CMake, Dockerfile, Rakefile, Scons

# 6.0.1

- Multiple exclude flags now allowed.

**Added Languages:**

- @seiks Added Fish Shell
- @XAMPPRocky Added Module-Definition
- @tbu- Added Vala

# 6.0.0

- Reworked internals
- Now uses serde*derive(\_and thusly requires rust v1.15*)
- Now has better file based testing

**Added languages:**

- @tuncer Added Ur/Web
- @svisser Added PureScript
- @tjodden Add some common extensions for HTML, C++ and Makefile
- @xd009642 Added VHDL

# 5.0.0

- Optimised internals

**Added languages:**

- @GungnirInd Added GDScript
- @tuncer Differentiate between sh and Bash, Added Cogent, F\*, F#
- @pthariensflame Added Agda

# 4.5.0

- Added Regex based hueristics so more expensive multi line handling isn't used
  if there are no multi line comments in the file.
- Now uses the `ignore` crate for getting files. Which now also makes
  determining language from path/file parallelised
- File counting used to only be parallelised per language, now it is also
  parallelised per file per language.
- Updated homepage, and documentation links
- @rmbreak Tokei will now not add directories with `foo.bar` like syntax
  to a language.
- @Michael-F-Bryan tokei will now exit gracefully when a feature is missing
  instead of panicking

**Added languages:**

- @hauleth Added Elixir support

# 4.4.0

- Simplified language definitions, now consolidated into a single JSON file.
- Fixed regression where lines and files weren't sorted.
- @llogiq : made clippy fixes
- @lligo : Added long verbose name

**Added languages:**

- @little-dude : Tcl(_tcl_)
- @svenstaro : GLSL(_vert, tesc, tese, geom, frag, comp_)
- @not-fl3 : Elm(_elm_)

**Changes to existing languages:**

- @xpayn : Added `pm` extension to Perl.

# 4.3.0

- @lligo : Tokei no longer panics on non-character-boundary when printing file names.
- Fixed regression where no comment style files(_json, markdown_) weren't counted.
- Tokei can now handle files in different encodings.(_using the [encoding](https://crates.io/crates/encoding) library_)
- Tokei now prints errors instead of silently skipping them.
- Tokei can now print unused extensions using `-v` option.

**Added languages:**

- Asp(_asa, asp_)
- Asp.NET(_asax, ascx, asmx, aspx, master, sitemap, webinfo_)
- Hex(_hex_)
- Intel Hex(_ihex_)
- ReStructuredText(_rst_)
- Razor(_cshtml_)

**Changes to existing languages Thanks to @mwilli20 :**

- Another Ada extension(_pad_)
- Assembly - Uses `' '` or `" "` and added another extension(_asm_)
- Bash - Uses `' '` or `" "`
- Batch - They don't use quotes for strings, added `::`
- Cold Fusion - Uses `' '` or `" "`
- D - Uses `" "` or
- Dart - Uses `" "` or `' '` or `""" """` or `''' '''`
- Forth - Uses `" "` but new, doesn't have a preset
- Fortrans - Use `" "` or `' '`
- Idris - Uses `" "` or `""" """`
- Julia - Uses `" "` or `""" """`
- Kotlin - Uses `" "` or `""" """`
- Lisp - Comments can be nested
- Moustache - Uses `" "` or `' '`
- Nim - Uses `" "` or `""" """`
- Pascal - Uses `' '`
- Perl - Uses `" "` or `' '`
- Php - Uses `" "` or `' '`
- Python - Uses `" "` or `' '` or `""" """` or `''' '''`
- Ruby - Uses `" "` or `' '`
- Sass - Uses `" "` or `' '`
- Sql - Uses `' '`
- Toml - Uses `" "` or `' '` or `""" """` or `''' '''`
- Typescript - Uses `" "` or `' '` or
- Vimscript - Uses `" "` or `' '`
- Yaml - Uses `" "` or `' '`
- Zsh - Uses `" "` or `' '`
- Clojure - Removed `#`
- Forth - `( Comment)` style comments need a space after the opening paren
- Haskell - Has nested comments
- Idris - Has nested comments
- Jai - Has nested block comments
- Julia - Has nested block comments
- Kotlin - Has nested block comments
- Pascal - Pascal should be multiline from `{` or `(*` to `}` or `*)`
- Perl - Perl5 and earlier for multiline comments need `=pod` to `=cut`.
- Swift - Has nested block comments

### Tokei's code count

```
-------------------------------------------------------------------------------
 Language            Files        Lines         Code     Comments       Blanks
-------------------------------------------------------------------------------
 Rust                   13         2413         1596          601          216
-------------------------------------------------------------------------------
 |ib\language\languages.rs          693          420          197           76
 |anguage\language_type.rs          500          386          102           12
 .\src\main.rs                      314          256           17           41
 |lib\language\language.rs          356          166          166           24
 .\src\lib\utils\fs.rs              129          107            9           13
 |\lib\utils\multi_line.rs          149           89           39           21
 .\src\lib\utils\macros.rs           59           50            3            6
 .\src\lib\stats.rs                  63           45           12            6
 .\src\lib\lib.rs                    76           25           47            4
 .\src\lib\build.rs                  31           23            0            8
 .\src\lib\sort.rs                   28           19            6            3
 .\src\lib\language\mod.rs           11            6            3            2
 .\src\lib\utils\mod.rs               4            4            0            0
-------------------------------------------------------------------------------
 Markdown                4          492          492            0            0
-------------------------------------------------------------------------------
 .\README.md                        252          252            0            0
 .\CHANGELOG.md                     202          202            0            0
 .\CONTRIBUTING.md                   25           25            0            0
 .\CONTRIBUTORS.md                   13           13            0            0
-------------------------------------------------------------------------------
 YAML                    2           70           67            3            0
-------------------------------------------------------------------------------
 .\cli.yml                           53           50            3            0
 .\.travis.yml                       17           17            0            0
-------------------------------------------------------------------------------
 TOML                    1           80           65            0           15
-------------------------------------------------------------------------------
 .\Cargo.toml                        80           65            0           15
-------------------------------------------------------------------------------
 Autoconf                1            9            7            1            1
-------------------------------------------------------------------------------
 .\src\lib\lib.rs.in                  9            7            1            1
-------------------------------------------------------------------------------
 Total                  21         3064         2227          605          232
-------------------------------------------------------------------------------
```

# 4.2.0

Tokei is now more precise, and shouldn't ever panic.
Tokei now handles comments in quotes and more precise nested comments properly.
Fixes #53

### Tokei's code count.

```
-------------------------------------------------------------------------------
 Language            Files        Lines         Code     Comments       Blanks
-------------------------------------------------------------------------------
 Rust                   13         2303         1487          594          222
-------------------------------------------------------------------------------
 |ib\language\languages.rs          682          401          198           83
 |anguage\language_type.rs          467          359           96           12
 .\src\main.rs                      302          243           17           42
 |lib\language\language.rs          356          166          166           24
 .\src\lib\utils\fs.rs              116           95            9           12
 |\lib\utils\multi_line.rs          156           93           41           22
 .\src\lib\stats.rs                  54           36           12            6
 .\src\lib\build.rs                  31           23            0            8
 .\src\lib\lib.rs                    69           22           43            4
 .\src\lib\utils\macros.rs           27           20            3            4
 .\src\lib\sort.rs                   28           19            6            3
 .\src\lib\language\mod.rs           11            6            3            2
 .\src\lib\utils\mod.rs               4            4            0            0
-------------------------------------------------------------------------------
 YAML                    2           68           65            3            0
-------------------------------------------------------------------------------
 .\cli.yml                           49           46            3            0
 .\.travis.yml                       19           19            0            0
-------------------------------------------------------------------------------
 TOML                    1           71           58            0           13
-------------------------------------------------------------------------------
 .\Cargo.toml                        71           58            0           13
-------------------------------------------------------------------------------
 Autoconf                1            9            7            1            1
-------------------------------------------------------------------------------
 .\src\lib\lib.rs.in                  9            7            1            1
-------------------------------------------------------------------------------
 Total                  17         2451         1617          598          236
-------------------------------------------------------------------------------
```

# 4.1.0

Tokei is now **~40%** faster.

**Added languages**

- Ada
- Forth

# 4.0.0

Tokei now has a minimal version without `serde` for faster compilation.

Updated various dependencies.

Internal dependencies removed.

## Regressions

- CBOR is not supported till it supports `serde 0.8`

**Added languages**

- Handlebars

# 3.0.0

Tokei is now available as a library.

Tokei now has a lot more tests.

Tokei now supports TOML

Fixed #41

Fixed #44

Fixed #45

# 2.1.0

Tokei, can now output results in various formats(_cbor, json, yaml_)

Conversely tokei can now take in results in those formats, and add them to the current run.

Premilarily support for nested comments(_currently only supported for rust_)

Change in the output format [PR #35](https://github.com/XAMPPRocky/tokei/pull/35)

Moved `.sc` from Lisp to Scala.

Internals changed to allow for multiple multi line comment formats.

**Added languages:**

- Isabelle

# 2.0.0

Major rewrite, now parallelized.
Can now support sorting files.
Added a progress message for when it is counting files.
Fixed #29

**Added languages:**

- Coq
- Erlang
- Kotlin
- Idris
- Nim
- Oz
- Prolog
- Qcl
- Scala
- Unreal Script
- Wolfram

# 1.6.0

Added file counting.

# 1.5.0

Added Shebang support.

**Added languages:**

- Assembly
- LD Scripts
- Device Trees
- Makefiles
- Plain Text
- C Shell

# 1.4.1

Changed the formatting so tokei looks nice for consoles of 80 column width.

# 1.4.0

Changed from handmade recursive file opening to [walkdir](https://github.com/BurntSushi/walkdir)


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at xampprocky+coc@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]

[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to Tokei

- [Language Addition](#language-addition)
- [Bug Reports](#bug-reports)

# Language Addition

Currently, Tokei generates languages from the [`languages.json`](languages.json)
file. JSON was chosen to make it easy to add new languages and change code
structure without changing large data structures. Here, we will go over the
properties of a language in `languages.json` through examples.

```json
"JavaScript": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"], ["`", "`"]],
      "extensions": ["js", "mjs"]
},
```

Above is the JavaScript's definition. The first thing that needs to be defined
is the key. The key's format should be same as [Rust's enum style]. As this key
will be used in an enum for identifying the language. For a lot of languages,
this also works for showing the language when we print to the screen.

However, there are some languages whose names don't work with the enum style.
For example, `JSON` is usually shown in all caps, but that doesn't fit in Rust's
enum style. So we have an additional optional field called `name` which defines
how the language should look when displayed to the user.

```json
"Json": {
    "name": "JSON",
    //...
},
```

For defining comments, there are a few properties. The most commonly used
property is `line_comment` which defines single line comments. These are comments
which don't continue onto the next line. Here is an example in Rust:

```rust
let x = 5; // default x position
let y = 0; // default y position
```

The `line_comment` property expects an array of strings, as some languages have
multiple syntaxes for defining a single line comment. For example, `PHP` allows
both `#` and `//` for single line comments.

```json
"Php": {
    "line_comment": [
        "#",
        "//"
    ],
    //...
},
```

For defining comments that also have an ending syntax, there is the `multi_line`
property. An example for such comments in Rust:

```rust
let x = /* There is a reason
    for this comment, I swear! */
    10;
```

The `verbatim_quotes` property expects an array of strings, as some languages
have multiple syntaxes for defining verbatim strings. A verbatim string
in the context of Tokei is a string literal that can have unescaped `"`s. For example [`CSharp`](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/strings/#regular-and-verbatim-string-literals)

```json
"CSharp": {
  "verbatim_quotes": [
    [
      "@\\\"",
      "\\\""
    ]
  ],
  //...
},
```

```csharp
const string BasePath = @"C:\";
```

Some languages have a single, standard filename with no extension
like `Makefile` or `Dockerfile`. These can be defined with the
`filenames` property:

```json
"Makefile": {
    "filenames": [
        "makefile"
    ],
    "extensions": [
        "makefile",
        "mak",
        "mk"
    ]
},
```

Filenames should be all-lowercase, whether or not the filename
typically has capital letters included.

Note that filenames will **override** extensions. With the
following definition, a file named `CMakeLists.txt` will be
detected as a `CMake` file, not a `Text` file.

```json
"Text": {
    "extensions": [
        "txt"
    ]
},
"CMake": {
    "filenames": [
        "cmakelists.txt"
    ]
},
```

# Tests

A test file is required for language additions. The file should
contain every variant comments and quotes, as well as a comment
at the top of the file containing the manually verified lines,
code, comments, blanks in the following format:

```
NUM lines NUM code NUM comments NUM blanks
```

### Example

In Rust for example, the first line should look like the following:

```rust
//! 39 lines 32 code 2 comments 5 blanks
```

The comment should use the syntax of the language you're testing.
A good example of a test file is [`tests/data/rust.rs`](tests/data/rust.rs).

```rust
//! 48 lines 36 code 6 comments 6 blanks
//! ```rust
//! fn main () {
//!     // Comment
//!
//!     println!("Hello World!");
//! }
//! ```

/* /**/ */
fn main() {
    let start = r##"/*##\"
\"##;
    // comment
    loop {
        if x.len() >= 2 && x[0] == '*' && x[1] == '/' { // found the */
            break;
        }
    }
}

fn foo<'a, 'b>(name: &'b str) {
    let this_ends = "a \"test/*.";
    call1();
    call2();
    let this_does_not = /* a /* nested */ comment " */
        "*/another /*test
            call3();
            */";
}

fn foobar() {
    let does_not_start = // "
        "until here,
        test/*
        test"; // a quote: "
    let also_doesnt_start = /* " */
        "until here,
        test,*/
        test"; // another quote: "
}

fn foo() {
    let a = 4; // /*
    let b = 5;
    let c = 6; // */
}


```

# Bug Reports

Please include the error message and a minimum working example
including the file or file structure.

````
This file crashes the program:

<filename>
```
<file/file structure>
```
````

[Rust's enum style]: https://github.com/rust-lang/rfcs/blob/master/text/0430-finalizing-naming-conventions.md#general-naming-conventions


================================================
FILE: Cargo.toml
================================================
[package]
authors = ["Erin Power <xampprocky@gmail.com>"]
build = "build.rs"
categories = ["command-line-utilities", "development-tools", "visualization"]
description = "Count your code, quickly."
homepage = "https://tokei.rs"
include = [
  "Cargo.lock",
  "Cargo.toml",
  "LICENCE-APACHE",
  "LICENCE-MIT",
  "build.rs",
  "languages.json",
  "src/**/*",
]
keywords = ["utility", "cli", "cloc", "lines", "statistics"]
license = "MIT OR Apache-2.0"
name = "tokei"
readme = "README.md"
repository = "https://github.com/XAMPPRocky/tokei.git"
version = "14.0.0"
rust-version = "1.71"
edition = "2021"

[features]
all = ["cbor", "yaml"]
cbor = ["dep:hex", "dep:serde_cbor"]
cli = ["dep:clap", "dep:colored", "dep:env_logger", "dep:num-format"]
default = ["cli"]
yaml = ["dep:serde_yaml"]

[profile.release]
lto = "thin"
panic = "abort"

[[bin]]
name = "tokei"
required-features = ["cli"]

[build-dependencies]
tera = "1.20.0"
ignore = "0.4.22"
serde_json = "1.0.125"
json5 = "0.4.1"

[dependencies]
aho-corasick = "1.1.3"
arbitrary = { version = "1.3.2", features = ["derive"] }
clap = { version = "4", optional = true, features = ["cargo", "string", "wrap_help"] }
colored = { version = "2.1.0", optional = true }
crossbeam-channel = "0.5.13"
encoding_rs_io = "0.1.7"
grep-searcher = "0.1.13"
ignore = "0.4.22"
log = "0.4.22"
rayon = "1.10.0"
serde = { version = "1.0.208", features = ["derive", "rc"] }
term_size = "0.3.2"
toml = "0.8.19"
parking_lot = "0.12.3"
dashmap = { version = "6.0.1", features = ["serde"] }
num-format = { version = "0.4.4", optional = true }
once_cell = "1.19.0"
regex = "1.10.6"
serde_json = "1.0.125"
etcetera = "0.8.0"
table_formatter = "0.6.1"
clap-cargo = "0.18.1"

[dependencies.env_logger]
optional = true
features = []
version = "0.11.5"

[dependencies.hex]
optional = true
version = "0.4.3"

[dependencies.serde_cbor]
optional = true
version = "0.11.2"

[dependencies.serde_yaml]
optional = true
version = "0.9.34"

[dev-dependencies]
proptest = "1.5.0"
strum = "0.27.2"
strum_macros = "0.27.2"
tempfile = "3.12.0"
git2 = { version = "0.19.0", default-features = false, features = [] }


================================================
FILE: Earthfile
================================================
VERSION 0.6
FROM alpine:3.19
WORKDIR /src

build:
    FROM rust:alpine3.19
    RUN apk update \
        && apk add \
            git \
            gcc \
            g++ \
            pkgconfig

    COPY . /src
    WORKDIR /src
    RUN cargo build --release
    SAVE ARTIFACT /src/target/release/tokei AS LOCAL ./tokei

docker:
    COPY +build/tokei /usr/local/bin/
    WORKDIR /src
    ENTRYPOINT [ "tokei" ]
    CMD [ "--help" ]
    ARG image_name=tokei:latest
    SAVE IMAGE --push $image_name


================================================
FILE: LICENCE-APACHE
================================================
Copyright 2016 Erin Power

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.


================================================
FILE: LICENCE-MIT
================================================
MIT License (MIT)

Copyright (c) 2016 Erin Power

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: README.md
================================================
# Tokei ([時計](https://en.wiktionary.org/wiki/%E6%99%82%E8%A8%88))
[![Mean Bean CI](https://github.com/XAMPPRocky/tokei/workflows/Mean%20Bean%20CI/badge.svg)](https://github.com/XAMPPRocky/tokei/actions?query=workflow%3A%22Mean+Bean+CI%22)
[![Help Wanted](https://img.shields.io/github/issues/XAMPPRocky/tokei/help%20wanted?color=green)](https://github.com/XAMPPRocky/tokei/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22)
[![Documentation](https://docs.rs/tokei/badge.svg)](https://docs.rs/tokei/)
![](https://img.shields.io/crates/d/tokei?label=downloads%20%28crates.io%29)
![](https://img.shields.io/github/downloads/xampprocky/tokei/total?label=downloads%20%28GH%29)
![](https://img.shields.io/homebrew/installs/dy/tokei?color=brightgreen&label=downloads%20%28brew%29)
![Chocolatey Downloads](https://img.shields.io/chocolatey/dt/tokei?label=Downloads%20(Chocolately))
[![dependency status](https://deps.rs/repo/github/XAMPPRocky/tokei/status.svg)](https://deps.rs/repo/github/XAMPPRocky/tokei)
[![Packaging status](https://repology.org/badge/tiny-repos/tokei.svg)](https://repology.org/project/tokei/versions)


Tokei is a program that displays statistics about your code. Tokei will show the number of files, total lines within those files and code, comments, and blanks grouped by language.

## Example
```console
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 Language            Files        Lines         Code     Comments       Blanks
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 BASH                    4           49           30           10            9
 JSON                    1         1332         1332            0            0
 Shell                   1           49           38            1           10
 TOML                    2           77           64            4            9
───────────────────────────────────────────────────────────────────────────────
 Markdown                5         1355            0         1074          281
 |- JSON                 1           41           41            0            0
 |- Rust                 2           53           42            6            5
 |- Shell                1           22           18            0            4
 (Total)                           1471          101         1080          290
───────────────────────────────────────────────────────────────────────────────
 Rust                   19         3416         2840          116          460
 |- Markdown            12          351            5          295           51
 (Total)                           3767         2845          411          511
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 Total                  32         6745         4410         1506          829
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```

## [API Documentation](https://docs.rs/tokei)

## Table of Contents

- [Features](#features)
- [Installation](#installation)
    - [Package Managers](#package-managers)
    - [Manual](#manual)
- [Configuration](#configuration)
- [How to use Tokei](#how-to-use-tokei)
- [Options](#options)
- [Supported Languages](#supported-languages)
- [Changelog](CHANGELOG.md)
- [Common Issues](#common-issues)
- [Canonical Source](#canonical-source)
- [Copyright and License](#copyright-and-license)

## Features

- Tokei is **very fast**, and is able to count millions of lines of code in seconds.
  Check out the [11.0.0 release](https://github.com/XAMPPRocky/tokei/releases/v11.0.0)
  to see how Tokei's speed compares to others.

- Tokei is **accurate**, Tokei correctly handles multi line comments,
  nested comments, and not counting comments that are in strings. Providing an
  accurate code statistics.

- Tokei has huge range of languages, supporting over **150** languages, and
  their various extensions.

- Tokei can output in multiple formats (**CBOR**, **JSON**, **YAML**)
  allowing Tokei's output to be easily stored, and reused. These can also be
  reused in tokei combining a previous run's statistics with another set.

- Tokei is available on **Mac**, **Linux**, and **Windows**. See [installation
  instructions](#installation) for how to get Tokei on your platform.

- Tokei is also a **library** allowing you to easily integrate it with other
  projects.

- Tokei comes with and without color. Set the env variable NO_COLOR to 1, and
  it'll be black and white.

## Installation

### Package Managers

#### Unix
```console
# Alpine Linux (since 3.13)
apk add tokei
# Arch Linux
pacman -S tokei
# Cargo
cargo install tokei
# Conda
conda install -c conda-forge tokei
# Fedora
sudo dnf install tokei
# FreeBSD
pkg install tokei
# NetBSD
pkgin install tokei
# Nix/NixOS
nix-env -i tokei
# OpenSUSE
sudo zypper install tokei
# Void Linux
sudo xbps-install tokei
```

#### macOS
```console
# Homebrew
brew install tokei
# MacPorts
sudo port selfupdate
sudo port install tokei
```

#### Windows
```console
# Winget
winget install XAMPPRocky.tokei
# Scoop
scoop install tokei
```

### Manual

#### Downloading
You can download prebuilt binaries in the
[releases section](https://github.com/XAMPPRocky/tokei/releases).

#### Building
You can also build and install from source (requires the latest stable [Rust] compiler.)
```console
cargo install --git https://github.com/XAMPPRocky/tokei.git tokei
```

[rust]: https://www.rust-lang.org


## Configuration

Tokei has a [configuration] file that allows you to change default behaviour.
The file can be named `tokei.toml` or `.tokeirc`. Currently tokei looks for
this file in three different places. The current directory, your home directory,
and your configuration directory.

## How to use Tokei

#### Basic usage

This is the basic way to use tokei. Which will report on the code in `./foo`
and all subfolders.

```shell
$ tokei ./foo
```

[configuration]: ./tokei.example.toml

#### Multiple folders
To have tokei report on multiple folders in the same call, simply add all the
folders you'd like tokei to examine.

```shell
$ tokei ./foo ./bar ./baz
```

#### Excluding folders
Tokei will respect all `.gitignore` and `.ignore` files, and you can use
the `--exclude` option to exclude any additional files. The `--exclude` flag has
the same semantics as `.gitignore`.

```shell
$ tokei ./foo --exclude *.rs
```

Paths to exclude can also be listed in a `.tokeignore` file, using the same
[syntax](https://git-scm.com/docs/gitignore) as .gitignore files.

#### Sorting output
By default tokei sorts alphabetically by language name, however using `--sort`
tokei can also sort by any of the columns.

`blanks, code, comments, lines`

```shell
$ tokei ./foo --sort code
```

#### Outputting file statistics
By default tokei only outputs the total of the languages, and using `--files`
flag tokei can also output individual file statistics.

```shell
$ tokei ./foo --files
```

#### Outputting into different formats
Tokei normally outputs into a nice human readable format designed for terminals.
There is also using the `--output` option various other formats that are more
useful for bringing the data into another program.

**Note:** This version of tokei was compiled without any serialization formats, to enable serialization, reinstall
tokei with the features flag.

```shell
  ALL:
  cargo install tokei --features all

  CBOR:
  cargo install tokei --features cbor

  YAML:
  cargo install tokei --features yaml
```

**Currently supported formats**
- JSON `--output json`
- YAML `--output yaml`
- CBOR `--output cbor`

```shell
$ tokei ./foo --output json
```

#### Reading in stored formats
Tokei can also take in the outputted formats added in the previous results to its
current run. Tokei can take either a path to a file, the format passed in as a
value to the option, or from stdin.

```shell
$ tokei ./foo --input ./stats.json
```

## Options

```
USAGE:
    tokei [FLAGS] [OPTIONS] [--] [input]...

FLAGS:
    -f, --files               Will print out statistics on individual files.
    -h, --help                Prints help information
        --hidden              Count hidden files.
    -l, --languages           Prints out supported languages and their extensions.
        --no-ignore           Don't respect ignore files (.gitignore, .ignore, etc.). This implies --no-ignore-parent,
                              --no-ignore-dot, and --no-ignore-vcs.
        --no-ignore-dot       Don't respect .ignore and .tokeignore files, including those in parent directories.
        --no-ignore-parent    Don't respect ignore files (.gitignore, .ignore, etc.) in parent directories.
        --no-ignore-vcs       Don't respect VCS ignore files (.gitignore, .hgignore, etc.), including those in parent
                              directories.
    -V, --version             Prints version information
    -v, --verbose             Set log output level:
                                          1: to show unknown file extensions,
                                          2: reserved for future debugging,
                                          3: enable file level trace. Not recommended on multiple files

OPTIONS:
    -c, --columns <columns>       Sets a strict column width of the output, only available for terminal output.
    -e, --exclude <exclude>...    Ignore all files & directories matching the pattern.
    -i, --input <file_input>      Gives statistics from a previous tokei run. Can be given a file path, or "stdin" to
                                  read from stdin.
    -o, --output <output>         Outputs Tokei in a specific format. Compile with additional features for more format
                                  support. [possible values: cbor, json, yaml]
    -s, --sort <sort>             Sort languages based on column [possible values: files, lines, blanks, code, comments]
    -t, --type <types>            Filters output by language type, separated by a comma. i.e. -t=Rust,Markdown

ARGS:
    <input>...    The path(s) to the file or directory to be counted.
```

## Dockerized version
Tokei is available in a small `alpine`-based docker image, buildable through [earthly](https://github.com/earthly/earthly):
```bash
earthly +docker
```

Once built, one can run the image with:
```bash
docker run --rm -v /path/to/analyze:/src tokei .
```

Or, to simply analyze the current folder (linux):
```bash
docker run --rm -v $(pwd):/src tokei .
```

## Supported Languages

If there is a language that you would to add to tokei feel free to make a pull
request. Languages are defined in [`languages.json`](./languages.json), and you can
read how to add and test your language in our [CONTRIBUTING.md](./CONTRIBUTING.md).

```
Abap
ActionScript
Ada
Agda
Alex
Alloy
APL
Asn1
Asp
AspNet
Assembly
AssemblyGAS
ATS
Autoconf
AutoHotKey
Automake
AWK
Bash
Batch
Bazel
Bean
Bicep
Bitbake
BQN
BrightScript
C
C3
Cabal
Cassius
Ceylon
CHeader
Cil
Clojure
ClojureC
ClojureScript
CMake
Cobol
CoffeeScript
Cogent
ColdFusion
ColdFusionScript
Coq
Cpp
CppHeader
Crystal
CSharp
CShell
Css
Cuda
CUE
Cython
D
D2
DAML
Dart
DeviceTree
Dhall
Dockerfile
DotNetResource
DreamMaker
Dust
Ebuild
EdgeDB
Edn
Elisp
Elixir
Elm
Elvish
EmacsDevEnv
Emojicode
Erlang
Factor
FEN
Fish
FlatBuffers
ForgeConfig
Forth
FortranLegacy
FortranModern
FreeMarker
FSharp
Fstar
GDB
GdScript
GdShader
Gherkin
Gleam
Glsl
Go
Graphql
Groovy
Gwion
Hamlet
Handlebars
Happy
Hare
Haskell
Haxe
Hcl
Hex
Hex0
Hex1
Hex2
HiCAD
hledger
Hlsl
HolyC
Html
Hy
Idris
Ini
IntelHex
Isabelle
Jai
Janet
Java
JavaScript
Jq
Json
Jsx
Julia
Julius
Just
KakouneScript
KaemFile
Koka
Kotlin
Lean
Less
Lingua Franca
LinkerScript
Liquid
Lisp
LLVM
Logtalk
Lua
Lucius
M1Assembly
Madlang
Max
Makefile
Markdown
Mdx
Meson
Mint
Mlatu
ModuleDef
MonkeyC
MoonScript
MsBuild
Mustache
Nim
Nix
NotQuitePerl
NuGetConfig
Nushell
ObjectiveC
ObjectiveCpp
OCaml
Odin
OpenSCAD
OpenQASM
Org
Oz
Pascal
Perl
Perl6
Pest
Phix
Php
Po
Poke
Polly
Pony
PostCss
PowerShell
Processing
Prolog
Protobuf
PRQL
PSL
PureScript
Pyret
Python
Qcl
Qml
R
Racket
Rakefile
Razor
Renpy
ReStructuredText
RON
RPMSpecfile
Ruby
RubyHtml
Rust
Sass
Scala
Scheme
Scons
Sh
ShaderLab
Slang
Sml
Solidity
SpecmanE
Spice
Sql
SRecode
Stata
Stratego
Svelte
Svg
Swift
Swig
SystemVerilog
Slint
Tact
Tcl
Templ
Tex
Text
Thrift
Toml
Tsx
Twig
TypeScript
UMPL
UnrealDeveloperMarkdown
UnrealPlugin
UnrealProject
UnrealScript
UnrealShader
UnrealShaderHeader
UrWeb
UrWebProject
Vala
VB6
VBScript
Velocity
Verilog
VerilogArgsFile
Vhdl
VimScript
VisualBasic
VisualStudioProject
VisualStudioSolution
Vue
WebAssembly
Wolfram
Xaml
XcodeConfig
Xml
XSL
Xtend
Yaml
ZenCode
Zig
ZoKrates
Zsh
```

## Common issues

### Tokei says I have a lot of D code, but I know there is no D code!
This is likely due to `gcc` generating `.d` files. Until the D people decide on
a different file extension, you can always exclude `.d` files using the
`-e --exclude` flag like so

```
$ tokei . -e *.d
```

## Canonical Source
The canonical source of this repo is hosted on
[GitHub](https://github.com/XAMPPRocky/tokei). If you have a GitHub account,
please make your issues, and pull requests there.

## Related Tools

- [tokei-pie](https://github.com/laixintao/tokei-pie): Render tokei's output to
  interactive sunburst chart.

## Copyright and License
(C) Copyright 2015 by XAMPPRocky and contributors

See [the graph](https://github.com/XAMPPRocky/tokei/graphs/contributors) for a full list of contributors.

Tokei is distributed under the terms of both the MIT license and the Apache License (Version 2.0).

See [LICENCE-APACHE](./LICENCE-APACHE), [LICENCE-MIT](./LICENCE-MIT) for more information.


================================================
FILE: benchmark.sh
================================================
#!/usr/bin/env bash
set -e

if [ "$1" = "--full" ]; then
    FILE=$2
    FULL=true
    else
    FILE=$1
    FULL=false
fi

echo 'Tokei Benchmarking Tool'

if [ $FULL = true ]; then
    REQUIRED='cloc, tokei, loc, hyperfine, and scc'
else
    REQUIRED='tokei, and hyperfine'
fi

echo "The use of this tool requires $REQUIRED to be installed and available in your PATH variable."

echo 'Please enter the path you would like to benchmark:'

if [ -z ${FILE+x} ]; then
    read -r input
else
    input=$FILE
fi

hyperfine --version
echo "old tokei: $(tokei --version)"

if [ $FULL = true ]; then
    scc --version
    loc --version
    echo "cloc: $(cloc --version)"
fi

cargo build --release

if [ $FULL = true ]; then
    hyperfine -w 10 --export-csv './results.csv' "target/release/tokei $input" \
                "tokei $input" \
                "scc $input" \
                "loc $input" # \ "cloc $input"
else
    hyperfine -w 5 "target/release/tokei $input" \
                "tokei $input"
fi


================================================
FILE: build.rs
================================================
extern crate ignore;
extern crate json5;
extern crate serde_json;

use std::ffi::OsStr;
use std::fs;
use std::path::Path;
use std::{cmp, env, error};

use ignore::Walk;
use serde_json::Value;

fn main() -> Result<(), Box<dyn error::Error>> {
    let out_dir = env::var_os("OUT_DIR").expect("No OUT_DIR variable.");
    generate_languages(&out_dir)?;
    generate_tests(&out_dir)?;

    Ok(())
}

fn generate_languages(out_dir: &OsStr) -> Result<(), Box<dyn error::Error>> {
    let mut tera = tera::Tera::default();

    let json_string: String = fs::read_to_string("languages.json")?.parse()?;
    let mut json: Value = json5::from_str(&json_string)?;

    for (_key, ref mut item) in json
        .get_mut("languages")
        .unwrap()
        .as_object_mut()
        .unwrap()
        .iter_mut()
    {
        macro_rules! sort_prop {
            ($prop:expr) => {{
                if let Some(ref mut prop) = item.get_mut($prop) {
                    prop.as_array_mut()
                        .unwrap()
                        .sort_unstable_by(compare_json_str_len)
                }
            }};
        }

        sort_prop!("quotes");
        sort_prop!("verbatim_quotes");
        sort_prop!("multi_line");
    }

    let output_path = Path::new(&out_dir).join("language_type.rs");
    let rust_code = tera.render_str(
        &std::fs::read_to_string("src/language/language_type.tera.rs")?,
        &tera::Context::from_value(json)?,
    )?;
    std::fs::write(output_path, rust_code)?;

    Ok(())
}

fn compare_json_str_len(a: &Value, b: &Value) -> cmp::Ordering {
    let a = a.as_array().expect("a as array");
    let b = b.as_array().expect("b as array");

    let max_a_size = a.iter().map(|e| e.as_str().unwrap().len()).max().unwrap();
    let max_b_size = b.iter().map(|e| e.as_str().unwrap().len()).max().unwrap();

    max_b_size.cmp(&max_a_size)
}

fn generate_tests(out_dir: &OsStr) -> Result<(), Box<dyn error::Error>> {
    // Length of string literal below by number of languages
    const INITIAL_BUFFER_SIZE: usize = 989 * 130;
    let mut string = String::with_capacity(INITIAL_BUFFER_SIZE);

    generate_tests_batch("./tests/data", None, &mut string)?;
    generate_tests_batch("./tests/embedding", Some("embedding"), &mut string)?;

    Ok(fs::write(Path::new(&out_dir).join("tests.rs"), string)?)
}

fn generate_tests_batch(
    src_dir: &str,
    test_module: Option<&str>,
    string: &mut String,
) -> Result<(), Box<dyn error::Error>> {
    let walker = Walk::new(src_dir).filter(|p| match p {
        Ok(ref p) => {
            if let Ok(ref p) = p.metadata() {
                p.is_file()
            } else {
                false
            }
        }
        _ => false,
    });

    if let Some(test_module) = test_module {
        string.push_str(&format!(
            r####"
#[cfg(test)]
mod {0} {{
use super::*;
        "####,
            test_module
        ));
    }

    for path in walker {
        let path = path?;
        let path = path.path();
        let root = std::path::PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());

        let name = path.file_stem().unwrap().to_str().unwrap().to_lowercase();

        if name == "jupyter" {
            continue;
        }

        string.push_str(&format!(
            r####"
        #[test]
        fn {0}() {{
            const _: &str = include_str!(r###"{2}"###);
            let mut languages = Languages::new();
            languages.get_statistics(&["{1}"], &[], &Config::default());

            if languages.len() != 1 {{
                panic!("wrong languages detected: expected just {0}, found {{:?}}",
                       languages.into_iter().collect::<Vec<_>>());
            }}

            let (name, language) = languages.into_iter().next().unwrap();
            let mut language = language.summarise();

            let contents = fs::read_to_string("{1}").unwrap();

            println!("{{}} {1}", name);
            assert_eq!(get_digit!(LINES, contents), language.lines());
            println!("{{}} LINES MATCH", name);
            assert_eq!(get_digit!(CODE, contents), language.code);
            println!("{{}} CODE MATCH", name);
            assert_eq!(get_digit!(COMMENTS, contents), language.comments);
            println!("{{}} COMMENTS MATCH", name);
            assert_eq!(get_digit!(BLANKS, contents), language.blanks);
            println!("{{}} BLANKS MATCH", name);

            let report = language.reports.pop().unwrap();
            let stats = report.stats.summarise();

            assert_eq!(language.lines(), stats.lines());
            assert_eq!(language.code, stats.code);
            assert_eq!(language.comments, stats.comments);
            assert_eq!(language.blanks, stats.blanks);
        }}
        "####,
            name,
            path.to_string_lossy().replace('\\', "/"),
            std::fs::canonicalize(root.join(path)).unwrap().display(),
        ));
    }

    if test_module.is_some() {
        string.push_str("\n}");
    }

    Ok(())
}


================================================
FILE: ci/build.bash
================================================
#!/usr/bin/env bash
# Script for building your rust projects.
set -e

source ci/common.bash

# $1 {path} = Path to cross/cargo executable
CROSS=$1
# $1 {string} = <Target Triple>
TARGET_TRIPLE=$2
# $3 {boolean} = Whether or not building for release or not.
RELEASE_BUILD=$3

required_arg "$CROSS" 'CROSS'
required_arg "$TARGET_TRIPLE" '<Target Triple>'

if [ -z "$RELEASE_BUILD" ]; then
    $CROSS build --target "$TARGET_TRIPLE"
    $CROSS build --target "$TARGET_TRIPLE" --all-features
else
    $CROSS build --target "$TARGET_TRIPLE" --all-features --release
fi


================================================
FILE: ci/common.bash
================================================
required_arg() {
    if [ -z "$1" ]; then
        echo "Required argument $2 missing"
        exit 1
    fi
}


================================================
FILE: ci/set_rust_version.bash
================================================
#!/usr/bin/env bash
set -e
rustup default "$1"
rustup target add "$2"


================================================
FILE: ci/test.bash
================================================
#!/usr/bin/env bash
# Script for building your rust projects.
set -e

source ci/common.bash

# $1 {path} = Path to cross/cargo executable
CROSS=$1
# $1 {string} = <Target Triple>
TARGET_TRIPLE=$2

required_arg "$CROSS" 'CROSS'
required_arg "$TARGET_TRIPLE" '<Target Triple>'

$CROSS test --target "$TARGET_TRIPLE"
$CROSS build --target "$TARGET_TRIPLE" --all-features


================================================
FILE: fuzz/.gitignore
================================================

target
corpus
artifacts


================================================
FILE: fuzz/Cargo.toml
================================================

[package]
name = "tokei-fuzz"
version = "0.0.1"
authors = ["Michael Macnair"]
publish = false
edition = "2018"

[package.metadata]
cargo-fuzz = true

[dependencies]
libfuzzer-sys = "0.4"
arbitrary = { version = "1.0.0", features = ["derive"] }

[dependencies.tokei]
path = ".."

# Prevent this from interfering with workspaces
[workspace]
members = ["."]

[[bin]]
name = "parse_from_slice_total"
path = "fuzz_targets/parse_from_slice_total.rs"
test = false
doc = false

[[bin]]
name = "parse_from_slice_panic"
path = "fuzz_targets/parse_from_slice_panic.rs"
test = false
doc = false


================================================
FILE: fuzz/README.md
================================================
## Fuzzing Tokei

Tokei can be fuzzed using libFuzzer, via [cargo-fuzz](https://github.com/rust-fuzz/cargo-fuzz/).

First install cargo-fuzz: `cargo install cargo-fuzz`.

To launch a fuzzing job: `cargo +nightly fuzz run <target>` - it will run until you kill it with ctrl-c.

To use multiple cores: `cargo +nightly fuzz run <target> --jobs=6`

To speed things up (at the expense of missing bugs that only manifest in larger files):
`cargo +nightly fuzz run <target> -- -max_len=200`

Available fuzz targets:

- `parse_from_slice_panic` - checks that all of the LanguageType instances' `parse_from_slice` function doesn't panic.
- `parse_from_slice_total` - checks that the language stats pass a basic test of reporting no more total lines than
  there are new lines in the file. At the time of writing there are low-hanging bugs here.

With the two `parse_from_slice` fuzz targets, it makes sense to share a common corpus directory as they have identical
input formats, e.g.: `cargo +nightly fuzz run parse_from_slice_{panic,total} fuzz/corpus/common`

Potential improvements:

- Build the fuzz harnesses in CI, so they don't rot.
- Do some coverage analysis to check if we're missing any code we would benefit from fuzzing (once it's
  [integrated into cargo-fuzz](https://github.com/rust-fuzz/cargo-fuzz/pull/248))
- Tighten the `parse_from_slice_total` fuzz target to check the total lines exactly matches the number of lines in the
  file. Only once any bugs found with the current fuzzer are fixed.
- Check in a minimized corpus, and run regression over it in CI.


================================================
FILE: fuzz/fuzz_targets/parse_from_slice.rs
================================================
use arbitrary::Arbitrary;
use std::str;

use tokei::{Config, LanguageType};

#[derive(Arbitrary, Debug)]
pub struct FuzzInput<'a> {
    lang: LanguageType,
    treat_doc_strings_as_comments: bool,
    data: &'a [u8],
}

// The first byte of data is used to select a language; remaining input is parsed
// If check_total is true, asserts that the parsed stats pass a basic sanity test
pub fn parse_from_slice(input: FuzzInput, check_total: bool) {
    let config = &Config {
        treat_doc_strings_as_comments: Some(input.treat_doc_strings_as_comments),

        // these options don't impact the behaviour of parse_from_slice:
        columns: None,
        hidden: None,
        no_ignore: None,
        no_ignore_parent: None,
        no_ignore_dot: None,
        no_ignore_vcs: None,
        sort: None,
        types: None,
        for_each_fn: None,
    };

    // check that parsing doesn't panic
    let stats = input.lang.parse_from_slice(input.data, config);

    if check_total {
        // verify that the parsed total lines is not more than the total occurrences of \n and \r\n.
        // if/when all of the current discrepancies are fixed, we could make this stronger by checking it is equal.
        if let Ok(s) = str::from_utf8(input.data) {
            assert!(
            stats.lines() <= s.lines().count(),
            "{} got more total lines ({}) than str::lines ({}). Code: {}, Comments: {}, Blanks: {}. treat_doc_strings_as_comments: {}. File contents (as UTF-8):\n{}",
            input.lang.name(),
            stats.lines(),
            s.lines().count(),
            stats.code,
            stats.comments,
            input.treat_doc_strings_as_comments,
            stats.blanks,
            s
        )
        };
    }
}


================================================
FILE: fuzz/fuzz_targets/parse_from_slice_panic.rs
================================================
#![no_main]
use libfuzzer_sys::fuzz_target;

mod parse_from_slice;
use parse_from_slice::{parse_from_slice, FuzzInput};

fuzz_target!(|data: FuzzInput| {
    parse_from_slice(data, false);
});


================================================
FILE: fuzz/fuzz_targets/parse_from_slice_total.rs
================================================
#![no_main]
use libfuzzer_sys::fuzz_target;

mod parse_from_slice;
use parse_from_slice::{parse_from_slice, FuzzInput};

fuzz_target!(|data: FuzzInput| {
    parse_from_slice(data, true);
});


================================================
FILE: languages.json
================================================
{
  "languages": {
    "Abap": {
      "name": "ABAP",
      "line_comment": ["*", "\\\""],
      "extensions": ["abap"]
    },
    "ABNF": {
      "line_comment": [";"],
      "extensions": ["abnf"]
    },
    "ActionScript": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["as"]
    },
    "Ada": {
      "line_comment": ["--"],
      "extensions": ["ada", "adb", "ads", "pad"]
    },
    "Agda": {
      "nested": true,
      "line_comment": ["--"],
      "multi_line_comments": [["{-", "-}"]],
      "extensions": ["agda"]
    },
    "Alex": {
      "extensions": ["x"]
    },
    "Alloy": {
      "line_comment": ["--", "//"],
      "multi_line_comments": [["/*", "*/"]],
      "extensions": ["als"]
    },
    "Apl": {
      "name": "APL",
      "line_comment": ["⍝"],
      "extensions": ["apl", "aplf", "apls"],
      "quotes": [["'", "'"]]
    },
    "Arduino": {
      "name": "Arduino C++",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["ino"]
    },
    "ArkTS": {
      "name": "Ark TypeScript",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"], ["`", "`"]],
      "extensions": ["ets"]
    },
    "Arturo": {
      "line_comment": [";"],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["art"]
    },
    "AsciiDoc": {
      "line_comment": ["//"],
      "multi_line_comments": [["////", "////"]],
      "extensions": ["adoc", "asciidoc"]
    },
    "Asn1": {
      "name": "ASN.1",
      "line_comment": ["--"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "multi_line_comments": [["/*", "*/"]],
      "extensions": ["asn1"]
    },
    "Asp": {
      "name": "ASP",
      "line_comment": ["'", "REM"],
      "extensions": ["asa", "asp"]
    },
    "AspNet": {
      "name": "ASP.NET",
      "multi_line_comments": [["<!--", "-->"], ["<%--", "-->"]],
      "extensions": [
        "asax",
        "ascx",
        "asmx",
        "aspx",
        "master",
        "sitemap",
        "webinfo"
      ]
    },
    "Assembly": {
      "line_comment": [";"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["asm"]
    },
    "AssemblyGAS": {
      "name": "GNU Style Assembly",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["s"]
    },
    "Astro": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"], ["<!--", "-->"]],
      "extensions": ["astro"]
    },
    "Ats": {
      "name": "ATS",
      "line_comment": ["//"],
      "multi_line_comments": [["(*", "*)"], ["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": [
        "dats",
        "hats",
        "sats",
        "atxt"
      ]
    },
    "Autoconf": {
      "line_comment": ["#", "dnl"],
      "extensions": ["in"]
    },
    "Autoit": {
      "line_comment": [";"],
      "multi_line_comments": [["#comments-start", "#comments-end"], ["#cs", "#ce"]],
      "extensions": ["au3"]
    },
    "AutoHotKey": {
      "line_comment": [";"],
      "multi_line_comments": [["/*", "*/"]],
      "extensions": ["ahk"]
    },
    "Automake": {
      "line_comment": ["#"],
      "extensions": ["am"]
    },
    "AvaloniaXaml": {
      "name": "AXAML",
      "multi_line_comments": [["<!--", "-->"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["axaml"]
    },
    "AWK": {
      "line_comment": ["#"],
      "shebangs": ["#!/bin/awk -f"],
      "extensions": ["awk"]
    },
    "Ballerina": {
      "line_comment": ["//", "#"],
      "quotes": [
        ["\\\"", "\\\""],
        ["`", "`"]
      ],
      "extensions": ["bal"]
    },
    "Bash": {
      "name": "BASH",
      "shebangs": ["#!/bin/bash"],
      "line_comment": ["#"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "env": ["bash"],
      "extensions": ["bash"]
    },
    "Batch": {
      "line_comment": ["REM", "::"],
      "extensions": ["bat", "btm", "cmd"]
    },
    "Bazel": {
      "line_comment": ["#"],
      "doc_quotes": [["\\\"\\\"\\\"", "\\\"\\\"\\\""], ["'''", "'''"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["bzl", "bazel", "bzlmod"],
      "filenames": ["build", "workspace", "module"]
    },
    "Bean": {
      "line_comment": [";"],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["bean", "beancount"]
    },
    "Bicep" : {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["'", "'"], ["'''", "'''"]],
      "extensions": ["bicep", "bicepparam"]
    },
    "Bitbake": {
      "name": "Bitbake",
      "line_comment": ["#"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["bb", "bbclass", "bbappend", "inc"]
    },
    "Bqn": {
      "name": "BQN",
      "line_comment": ["#"],
      "extensions": ["bqn"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]]
    },
    "BrightScript": {
      "quotes": [["\\\"", "\\\""]],
      "line_comment": ["'", "REM"],
      "extensions": ["brs"]
    },
    "C": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["c", "ec", "pgc"]
    },
    "C3": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["c3"]
    },
    "Cabal": {
      "nested": true,
      "line_comment": ["--"],
      "multi_line_comments": [["{-", "-}"]],
      "extensions": ["cabal"]
    },
    "Cairo": {
      "line_comment": ["//"],
      "extensions": ["cairo"],
      "quotes": [
        ["\\\"", "\\\""],
        ["'", "'"]
      ]
    },
    "Cangjie": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "nested": true,
      "quotes": [["\\\"", "\\\""],["\\\"\\\"\\\"", "\\\"\\\"\\\""]],
      "verbatim_quotes": [["#\\\"", "\\\"#"],["##\\\"", "\\\"##"],["###\\\"", "\\\"###"],
        ["#'", "'#"],["##'", "'##"],["###'", "'###"]],
      "extensions": ["cj"]
    },
    "Cassius": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["cassius"]
    },
    "Ceylon": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["\\\"\\\"\\\"", "\\\"\\\"\\\""]],
      "extensions": ["ceylon"]
    },
    "Chapel": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["chpl"]
    },
    "CHeader": {
      "name": "C Header",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["h"]
    },
    "Cil": {
      "name": "CIL (SELinux)",
      "line_comment": [";"],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["cil"]
    },
    "Circom": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "extensions": ["circom"]
    },
    "Clojure": {
      "line_comment": [";"],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["clj"]
    },
    "ClojureC": {
      "line_comment": [";"],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["cljc"]
    },
    "ClojureScript": {
      "line_comment": [";"],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["cljs"]
    },
    "CMake": {
      "line_comment": ["#"],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["cmake"],
      "filenames": ["cmakelists.txt"]
    },
    "Cobol": {
      "name": "COBOL",
      "line_comment": ["*"],
      "extensions": ["cob", "cbl", "ccp", "cobol", "cpy"]
    },
    "CodeQL": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["ql", "qll"]
    },
    "CoffeeScript": {
      "line_comment": ["#"],
      "multi_line_comments": [["###", "###"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["coffee", "cjsx"]
    },
    "Cogent": {
      "line_comment": ["--"],
      "extensions": ["cogent"]
    },
    "ColdFusion": {
      "multi_line_comments": [["<!---", "--->"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["cfm"]
    },
    "ColdFusionScript": {
      "name": "ColdFusion CFScript",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["cfc"]
    },
    "Coq": {
      "quotes": [["\\\"", "\\\""]],
      "multi_line_comments": [["(*", "*)"]],
      "extensions": ["v"]
    },
    "Cpp": {
      "name": "C++",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "verbatim_quotes": [["R\\\"(", ")\\\""]],
      "extensions": ["cc", "cpp", "cxx", "c++", "pcc", "tpp"]
    },
    "CppHeader": {
      "name": "C++ Header",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["hh", "hpp", "hxx", "inl", "ipp"]
    },
    "CppModule": {
      "name": "C++ Module",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "verbatim_quotes": [["R\\\"(", ")\\\""]],
      "extensions": ["cppm", "ixx", "ccm", "mpp", "mxx", "cxxm", "hppm", "hxxm"]
    },
    "Crystal": {
      "line_comment": ["#"],
      "shebangs": ["#!/usr/bin/crystal"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "env": ["crystal"],
      "extensions": ["cr"]
    },
    "CSharp": {
      "name": "C#",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "verbatim_quotes": [["@\\\"", "\\\""]],
      "extensions": ["cs", "csx"]
    },
    "CShell": {
      "name": "C Shell",
      "shebangs": ["#!/bin/csh"],
      "line_comment": ["#"],
      "env": ["csh"],
      "extensions": ["csh"]
    },
    "Css": {
      "name": "CSS",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "mime": ["text/css"],
      "extensions": ["css"]
    },
    "Cuda": {
      "name": "CUDA",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["cu"]
    },
    "Cue": {
      "name": "CUE",
      "line_comment": ["//"],
      "quotes": [
        ["\\\"", "\\\""],
        ["'", "'"],
        ["\\\"\\\"\\\"", "\\\"\\\"\\\""]
      ],
      "verbatim_quotes": [["#\\\"", "\\\"#"]],
      "extensions": ["cue"]
    },
    "Cython": {
      "line_comment": ["#"],
      "doc_quotes": [["\\\"\\\"\\\"", "\\\"\\\"\\\""], ["'''", "'''"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "env": ["cython"],
      "extensions": ["pyx", "pxd", "pxi"]
    },
    "D": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "nested_comments": [["/+", "+/"]],
      "extensions": ["d"]
    },
    "D2": {
      "line_comment": ["#"],
      "multi_line_comments": [["\\\"\\\"\\\"", "\\\"\\\"\\\""]],
      "extensions": ["d2"]
    },
    "Daml": {
      "name": "DAML",
      "nested": true,
      "line_comment": ["-- "],
      "multi_line_comments": [["{-", "-}"]],
      "extensions": ["daml"]
    },
    "Dart": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [
        ["\\\"", "\\\""],
        ["'", "'"],
        ["\\\"\\\"\\\"", "\\\"\\\"\\\""],
        ["'''", "'''"]
      ],
      "extensions": ["dart"]
    },
    "DeviceTree": {
      "name": "Device Tree",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["dts", "dtsi"]
    },
    "Dhall":{
      "nested": true,
      "line_comment": ["--"],
      "multi_line_comments": [["{-", "-}"]],
      "quotes": [["\\\"", "\\\""], ["''", "''"]],
      "extensions": ["dhall"]
    },
    "Djot": {
      "literate": true,
      "important_syntax": ["```"],
      "extensions": ["dj", "djot"]
    },
    "Dockerfile": {
      "line_comment": ["#"],
      "extensions": ["dockerfile", "dockerignore"],
      "filenames": ["dockerfile"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]]
    },
    "DotNetResource": {
      "name": ".NET Resource",
      "multi_line_comments": [["<!--", "-->"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["resx"]
    },
    "DreamMaker": {
      "name": "Dream Maker",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "nested": true,
      "extensions": ["dm", "dme"],
      "quotes": [["\\\"", "\\\""], ["{\\\"", "\\\"}"], ["'", "'"]]
    },
    "Dust": {
      "name": "Dust.js",
      "multi_line_comments": [["{!", "!}"]],
      "extensions": ["dust"]
    },
    "Ebuild": {
      "line_comment": ["#"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["ebuild", "eclass"]
    },
    "EdgeQL": {
      "name": "EdgeQL",
      "line_comment": ["#"],
      "quotes": [["'", "'"], ["\\\"", "\\\""], ["$", "$"]],
      "extensions": ["edgeql"]
    },
    "ESDL": {
      "name": "EdgeDB Schema Definition",
      "line_comment": ["#"],
      "quotes": [["'", "'"], ["\\\"", "\\\""]],
      "extensions": ["esdl"]
    },
    "Edn": {
      "line_comment": [";"],
      "extensions": ["edn"]
    },
    "Eighth": {
      "name": "8th",
      "line_comment": ["\\\\ ", "-- "],
      "multi_line_comments": [["(*", "*)"]],
      "nested": true,
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["8th"]
    },
    "Elisp": {
      "name": "Emacs Lisp",
      "line_comment": [";"],
      "extensions": ["el"]
    },
    "Elixir": {
      "line_comment": ["#"],
      "quotes": [
        ["\\\"\\\"\\\"", "\\\"\\\"\\\""],
        ["\\\"", "\\\""],
        ["'''", "'''"],
        ["'", "'"]
      ],
      "extensions": ["ex", "exs"]
    },
    "Elm": {
      "nested": true,
      "line_comment": ["--"],
      "multi_line_comments": [["{-", "-}"]],
      "extensions": ["elm"]
    },
    "Elvish": {
      "line_comment": ["#"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "env": ["elvish"],
      "extensions": ["elv"]
    },
    "EmacsDevEnv": {
      "name": "Emacs Dev Env",
      "line_comment": [";"],
      "extensions": ["ede"]
    },
    "Emojicode": {
      "line_comment": ["💭"],
      "multi_line_comments": [["💭🔜", "🔚💭"], ["📗", "📗"], ["📘", "📘"]],
      "quotes": [["❌🔤", "❌🔤"]],
      "extensions": ["emojic", "🍇"]
    },
    "Erlang": {
      "line_comment": ["%"],
      "extensions": ["erl", "hrl"]
    },
    "Factor": {
        "line_comment": ["!", "#!"],
        "multi_line_comments": [["/*", "*/"]],
        "extensions": ["factor"]
    },
    "FEN": {
      "name": "FEN",
      "blank": true,
      "extensions": ["fen"]
    },
    "Fennel" : {
      "line_comment": [";", ";;"],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["fnl", "fnlm"]
    },
    "Fish": {
      "shebangs": ["#!/bin/fish"],
      "line_comment": ["#"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "env": ["fish"],
      "extensions": ["fish"]
    },
    "FlatBuffers": {
      "name": "FlatBuffers Schema",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["fbs"]
    },
    "ForgeConfig": {
      "name": "Forge Config",
      "line_comment": ["#", "~"],
      "extensions": ["cfg"]
    },
    "Forth": {
      "line_comment": ["\\\\"],
      "multi_line_comments": [["( ", ")"]],
      "extensions": [
        "4th",
        "forth",
        "fr",
        "frt",
        "fth",
        "f83",
        "fb",
        "fpm",
        "e4",
        "rx",
        "ft"
      ]
    },
    "FortranLegacy": {
      "name": "FORTRAN Legacy",
      "line_comment": ["c", "C", "!", "*"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["f", "for", "ftn", "f77", "pfo"]
    },
    "FortranModern": {
      "name": "FORTRAN Modern",
      "line_comment": ["!"],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["f03", "f08", "f90", "f95", "fpp"]
    },
    "FreeMarker": {
      "multi_line_comments": [["<#--", "-->"]],
      "extensions": ["ftl", "ftlh", "ftlx"]
    },
    "FSharp": {
      "name": "F#",
      "line_comment": ["//"],
      "multi_line_comments": [["(*", "*)"]],
      "quotes": [["\\\"", "\\\""]],
      "verbatim_quotes": [["@\\\"", "\\\""]],
      "extensions": ["fs", "fsi", "fsx", "fsscript"]
    },
    "Fstar": {
      "name": "F*",
      "quotes": [["\\\"", "\\\""]],
      "line_comment": ["//"],
      "multi_line_comments": [["(*", "*)"]],
      "extensions": ["fst", "fsti"]
    },
    "Futhark": {
      "line_comment": ["--"],
      "extensions": ["fut"]
    },
    "GDB": {
      "name": "GDB Script",
      "line_comment": ["#"],
      "extensions": ["gdb"]
    },
    "GdScript": {
      "name": "GDScript",
      "line_comment": ["#"],
      "quotes": [
        ["\\\"", "\\\""],
        ["'", "'"],
        ["\\\"\\\"\\\"", "\\\"\\\"\\\""]
      ],
      "extensions": ["gd"]
    },
    "Gherkin": {
      "name": "Gherkin (Cucumber)",
      "line_comment": ["#"],
      "extensions": ["feature"]
    },
    "Gleam": {
      "name": "Gleam",
      "line_comment": ["//", "///", "////"],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["gleam"]
    },
    "GlimmerJs": {
      "name": "Glimmer JS",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"], ["<!--", "-->"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"], ["`", "`"]],
      "important_syntax": ["<template", "<style"],
      "extensions": ["gjs"]
    },
    "GlimmerTs": {
      "name": "Glimmer TS",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"], ["<!--", "-->"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"], ["`", "`"]],
      "important_syntax": ["<template", "<style"],
      "extensions": ["gts"]
    },
    "Glsl": {
      "name": "GLSL",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["vert", "tesc", "tese", "geom", "frag", "comp", "mesh", "task", "rgen", "rint", "rahit", "rchit", "rmiss", "rcall", "glsl"]
    },
    "Gml": {
      "name": "Gml",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["gml"]
    },
    "Go": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["go"]
    },
    "Gohtml": {
      "name": "Go HTML",
      "multi_line_comments": [["<!--", "-->"], ["{{/*", "*/}}"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["gohtml"]
    },
    "Graphql": {
      "name": "GraphQL",
      "quotes": [["\\\"", "\\\""], ["\\\"\\\"\\\"", "\\\"\\\"\\\""]],
      "line_comment": ["#"],
      "extensions": ["gql", "graphql"]
    },
    "Groovy": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "env": ["groovy"],
      "extensions": ["groovy", "grt", "gtpl", "gvy"]
    },
    "Gwion": {
      "line_comment": ["#!"],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["gw"]
    },
    "Haml": {
      "line_comment": ["-#"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["haml"]
    },
    "Hamlet": {
      "multi_line_comments": [["<!--", "-->"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["hamlet"]
    },
    "Happy": {
      "extensions": ["y", "ly"]
    },
    "Handlebars": {
      "multi_line_comments": [["<!--", "-->"], ["{{!", "}}"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["hbs", "handlebars"]
    },
    "Haskell": {
      "nested": true,
      "line_comment": ["--"],
      "multi_line_comments": [["{-", "-}"]],
      "extensions": ["hs"]
    },
    "Haxe": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["hx"]
    },
    "Hcl": {
      "name": "HCL",
      "line_comment": ["#", "//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["hcl", "tf", "tfvars"]
    },
    "Headache": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["ha"]
    },
    "Hex": {
      "name": "HEX",
      "blank": true,
      "extensions": ["hex"]
    },
    "Hex0": {
      "extensions": ["hex0"],
      "line_comment": ["#", ";"]
    },
    "Hex1": {
      "extensions": ["hex1"],
      "line_comment": ["#", ";"]
    },
    "Hex2": {
      "extensions": ["hex2"],
      "line_comment": ["#", ";"]
    },
    "HiCad": {
      "name": "HICAD",
      "line_comment": ["REM", "rem"],
      "extensions": ["MAC", "mac"]
    },
    "Hlsl": {
      "name": "HLSL",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["hlsl", "fx", "fxsub"]
    },
    "HolyC": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["HC", "hc","ZC","zc"]
    },
    "Html": {
      "name": "HTML",
      "multi_line_comments": [["<!--", "-->"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "kind": "html",
      "important_syntax": ["<script", "<style"],
      "mime": ["text/html"],
      "extensions": ["html", "htm"]
    },
    "Hy": {
      "line_comment": [";"],
      "extensions": ["hy"]
    },
    "Idris": {
      "line_comment": ["--"],
      "multi_line_comments": [["{-", "-}"]],
      "quotes": [["\\\"", "\\\""], ["\\\"\\\"\\\"", "\\\"\\\"\\\""]],
      "extensions": ["idr", "lidr"],
      "nested": true
    },
    "Ini": {
      "name": "INI",
      "line_comment": [";", "#"],
      "extensions": ["ini"]
    },
    "IntelHex": {
      "name": "Intel HEX",
      "blank": true,
      "extensions": ["ihex"]
    },
    "Isabelle": {
      "line_comment": ["--"],
      "multi_line_comments": [
        ["{*", "*}"],
        ["(*", "*)"],
        ["‹", "›"],
        ["\\\\<open>", "\\\\<close>"]
      ],
      "quotes": [["''", "''"]],
      "extensions": ["thy"]
    },
    "Jai": {
      "name": "JAI",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["jai"],
      "nested": true
    },
    "Janet": {
      "line_comment": ["#"],
      "quotes": [["\\\"", "\\\""], ["'", "'"], ["`", "`"]],
      "extensions": ["janet"]
    },
    "Java": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["java"]
    },
    "JavaScript": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"], ["`", "`"]],
      "mime": [
          "application/javascript",
          "application/ecmascript",
          "application/x-ecmascript",
          "application/x-javascript",
          "text/javascript",
          "text/ecmascript",
          "text/javascript1.0",
          "text/javascript1.1",
          "text/javascript1.2",
          "text/javascript1.3",
          "text/javascript1.4",
          "text/javascript1.5",
          "text/jscript",
          "text/livescript",
          "text/x-ecmascript",
          "text/x-javascript"
      ],
      "extensions": ["cjs", "js", "mjs"]
    },
    "Jinja2": {
      "name": "Jinja2",
      "blank": true,
      "extensions": ["j2", "jinja"],
      "multi_line_comments": [["{#", "#}"]]
    },
    "Jq": {
      "name": "jq",
      "line_comment": ["#"],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["jq"]
    },
    "JSLT": {
      "name": "JSLT",
      "line_comment": ["//"],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["jslt"]
    },
    "Json": {
      "name": "JSON",
      "blank": true,
      "mime": ["application/json", "application/manifest+json"],
      "extensions": ["json"]
    },
    "Jsonnet": {
      "line_comment": ["//", "#"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["jsonnet", "libsonnet"]
    },
    "Jsx": {
      "name": "JSX",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"], ["`", "`"]],
      "extensions": ["jsx"]
    },
    "Julia": {
      "line_comment": ["#"],
      "multi_line_comments": [["#=", "=#"]],
      "quotes": [["\\\"", "\\\""], ["\\\"\\\"\\\"", "\\\"\\\"\\\""]],
      "nested": true,
      "extensions": ["jl"]
    },
    "Julius": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"], ["`", "`"]],
      "extensions": ["julius"]
    },
    "Jupyter": {
      "name": "Jupyter Notebooks",
      "extensions": ["ipynb"]
    },
    "Just": {
      "shebangs": ["#!/usr/bin/env just --justfile"],
      "env": ["just"],
      "line_comment": ["#"],
      "extensions": ["just"],
      "filenames": ["justfile"]
    },
    "K": {
      "name": "K",
      "nested": true,
      "line_comment": ["/"],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["k"]
    },
    "KakouneScript": {
      "name": "Kakoune script",
      "line_comment": ["#"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["kak"]
    },
    "Kaem": {
      "name": "Kaem",
      "line_comment": ["#"],
      "extensions": ["kaem"]
    },
    "Koka": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "nested": true,
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["kk"]
    },
    "Kotlin": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "nested": true,
      "quotes": [["\\\"", "\\\""], ["\\\"\\\"\\\"", "\\\"\\\"\\\""]],
      "extensions": ["kt", "kts"]
    },
    "Ksh": {
      "name": "Korn shell",
      "shebangs": ["#!/bin/ksh"],
      "line_comment": ["#"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "env": ["ksh"],
      "extensions": ["ksh"]
    },
    "Lalrpop": {
      "name": "LALRPOP",
      "line_comment": ["//"],
      "extensions": ["lalrpop"],
      "quotes": [["\\\"", "\\\""], ["#\\\"", "\\\"#"]],
      "verbatim_quotes": [["r##\\\"", "\\\"##"], ["r#\\\"", "\\\"#"]]
    },
    "KvLanguage": {
      "name":"KV Language",
      "line_comment": ["# "],
      "doc_quotes": [["\\\"\\\"\\\"", "\\\"\\\"\\\""], ["'''", "'''"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["kv"]
    },
    "Lean": {
      "line_comment": ["--"],
      "multi_line_comments": [["/-", "-/"]],
      "nested": true,
      "extensions": ["lean", "hlean"]
    },
    "Hledger": {
      "name": "hledger",
      "line_comment": [";", "#"],
      "multi_line_comments": [["comment", "end comment"]],
      "nested": false,
      "extensions": ["hledger"]
    },
    "Less": {
      "name": "LESS",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "extensions": ["less"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]]
    },
    "Lex": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "extensions": ["l", "lex"]
    },
    "Liquid": {
      "name": "Liquid",
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["liquid"],
      "multi_line_comments": [["<!--", "-->"], ["{% comment %}", "{% endcomment %}"]]
    },
    "LinguaFranca": {
      "name": "Lingua Franca",
      "line_comment": ["//", "#"],
      "important_syntax": ["{="],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "nested": true,
      "extensions": ["lf"]
    },
    "LinkerScript": {
      "name": "LD Script",
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["ld", "lds"]
    },
    "Lisp": {
      "name": "Common Lisp",
      "line_comment": [";"],
      "multi_line_comments": [["#|", "|#"]],
      "nested": true,
      "extensions": ["lisp", "lsp", "asd"]
    },
    "LiveScript": {
      "line_comment": ["#"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["ls"]
    },
    "LLVM": {
      "line_comment": [";"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["ll"]
    },
    "Logtalk": {
      "line_comment": ["%"],
      "quotes": [["\\\"", "\\\""]],
      "multi_line_comments": [["/*", "*/"]],
      "extensions": ["lgt", "logtalk"]
    },
    "LolCode": {
      "name": "LOLCODE",
      "line_comment": ["BTW"],
      "quotes": [["\\\"", "\\\""]],
      "multi_line_comments": [["OBTW", "TLDR"]],
      "extensions": ["lol"]
    },
    "Lua": {
      "line_comment": ["--"],
      "multi_line_comments": [["--[[", "]]"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["lua", "luau"]
    },
    "Lucius": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["lucius"]
    },
    "M1Assembly": {
      "name": "M1 Assembly",
      "extensions": ["m1"],
      "line_comment": ["#", ";"],
      "quotes": [["\\\"", "\\\""]]
    },
    "M4": {
      "extensions": ["m4"],
      "line_comment": ["#", "dnl"],
      "quotes": [["`", "'"]]
    },
    "Madlang": {
      "extensions": ["mad"],
      "line_comment": ["#"],
      "multi_line_comments": [["{#", "#}"]]
    },
    "Makefile": {
      "line_comment": ["#"],
      "extensions": ["makefile", "mak", "mk"],
      "filenames": ["gnumakefile", "makefile"]
    },
    "Markdown": {
      "literate": true,
      "important_syntax": ["```"],
      "extensions": ["md", "markdown"]
    },
    "Max": {
      "extensions": ["maxpat"]
    },
    "Mdx": {
      "name": "MDX",
      "literate": true,
      "important_syntax": ["```"],
      "extensions": ["mdx"]
    },
    "Menhir": {
      "nested": true,
      "quotes": [["\\\"", "\\\""]],
      "line_comment": ["//"],
      "multi_line_comments": [
        ["(*", "*)"],
        ["/*", "*/"]
      ],
      "extensions": ["mll", "mly", "vy"]
    },
    "Meson": {
      "line_comment": ["#"],
      "quotes": [["'", "'"], ["'''", "'''"]],
      "filenames": ["meson.build", "meson_options.txt"]
    },
    "Metal": {
      "name": "Metal Shading Language",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["metal"]
    },
    "Mint": {
      "blank": true,
      "extensions": ["mint"]
    },
    "Mlatu": {
      "line_comment": ["//"],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["mlt"]
    },
    "Modelica": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["mo", "mos"]
    },
    "ModuleDef": {
      "name": "Module-Definition",
      "extensions": ["def"],
      "line_comment": [";"]
    },
    "Mojo": {
      "line_comment": ["#"],
      "doc_quotes": [["\\\"\\\"\\\"", "\\\"\\\"\\\""], ["'''", "'''"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["mojo", "🔥"]
    },
    "MonkeyC": {
      "name": "Monkey C",
      "extensions": ["mc"],
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]]
    },
    "MoonBit": {
      "line_comment": ["//"],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["mbt", "mbti"]
    },
    "MoonScript": {
      "line_comment": ["--"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["moon"]
    },
    "MsBuild": {
      "name": "MSBuild",
      "multi_line_comments": [["<!--", "-->"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["csproj", "vbproj", "fsproj", "props", "targets"]
    },
    "Mustache": {
      "multi_line_comments": [["{{!", "}}"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["mustache"]
    },
    "Nextflow": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["nextflow", "nf"]
    },
    "Nim": {
      "line_comment": ["#"],
      "quotes": [["\\\"", "\\\""], ["\\\"\\\"\\\"", "\\\"\\\"\\\""]],
      "extensions": ["nim"]
    },
    "Nix": {
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "line_comment": ["#"],
      "extensions": ["nix"]
    },
    "NotQuitePerl": {
      "name": "Not Quite Perl",
      "line_comment": ["#"],
      "multi_line_comments": [["=begin", "=end"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["nqp"]
    },
    "NuGetConfig": {
      "name": "NuGet Config",
      "multi_line_comments": [["<!--", "-->"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "filenames": ["nuget.config", "packages.config", "nugetdefaults.config"]
    },
    "Nushell": {
      "line_comment": ["#"],
      "quotes": [
        ["\\\"", "\\\""],
        ["'", "'"]
      ],
      "extensions": ["nu"]
    },
    "ObjectiveC": {
      "name": "Objective-C",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["m"]
    },
    "ObjectiveCpp": {
      "name": "Objective-C++",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["mm"]
    },
    "OCaml": {
      "quotes": [["\\\"", "\\\""]],
      "multi_line_comments": [["(*", "*)"]],
      "extensions": ["ml", "mli", "re", "rei"]
    },
    "Odin": {
      "extensions": ["odin"],
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]]
    },
    "OpenScad": {
      "name": "OpenSCAD",
      "extensions": ["scad"],
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]]
    },
    "OpenPolicyAgent": {
      "name": "Open Policy Agent",
      "line_comment": ["#"],
      "quotes": [["\\\"","\\\""], ["`", "`"]],
      "extensions": ["rego"]
    },
    "OpenCL": {
      "name": "OpenCL",
      "multi_line_comments": [["/*", "*/"]],
      "extensions": ["cl", "ocl"]
    },
    "OpenQasm": {
      "name": "OpenQASM",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "extensions": ["qasm"]
    },
    "OpenType": {
      "name": "OpenType Feature File",
      "line_comment": ["#"],
      "extensions": ["fea"]
    },
    "Org": {
      "line_comment": ["# "],
      "extensions": ["org"]
    },
    "Oz": {
      "line_comment": ["%"],
      "quotes": [["\\\"", "\\\""]],
      "multi_line_comments": [["/*", "*/"]],
      "extensions": ["oz"]
    },
    "PacmanMakepkg": {
      "name": "Pacman's makepkg",
      "line_comment": ["#"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "filenames": ["pkgbuild"]
    },
    "Pan": {
      "line_comment": ["#"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["pan", "tpl"]
    },
    "Pascal": {
      "nested": true,
      "line_comment": ["//"],
      "multi_line_comments": [["{", "}"], ["(*", "*)"]],
      "quotes": [["'", "'"]],
      "extensions": ["pas"]
    },
    "Perl": {
      "shebangs": ["#!/usr/bin/perl"],
      "line_comment": ["#"],
      "multi_line_comments": [["=pod", "=cut"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["pl", "pm"]
    },
    "Pest": {
      "line_comment": ["//"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["pest"]
    },
    "Phix": {
      "line_comment": ["--", "//", "#!"],
      "multi_line_comments": [["/*", "*/"], ["--/*", "--*/"]],
      "nested": true,
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "verbatim_quotes": [["\\\"\\\"\\\"", "\\\"\\\"\\\""], ["`", "`"]],
      "extensions": ["e","exw"]
    },
    "Php": {
      "name": "PHP",
      "line_comment": ["#", "//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["php"]
    },
    "PlantUml": {
      "name": "PlantUML",
      "line_comment": ["'"],
      "multi_line_comments": [["/'", "'/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["puml"]
    },
    "Po": {
        "name": "PO File",
        "line_comment": ["#"],
        "extensions": ["po", "pot"]
    },
    "Poke": {
      "multi_line_comments": [["/*", "*/"]],
      "extensions": ["pk"]
    },
    "Polly": {
      "multi_line_comments": [["<!--", "-->"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["polly"]
    },
    "Pony": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "doc_quotes": [["\\\"\\\"\\\"", "\\\"\\\"\\\""]],
      "extensions": ["pony"]
    },
    "PostCss": {
      "name": "PostCSS",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["pcss", "sss"]
    },
    "PowerShell": {
      "line_comment": ["#"],
      "multi_line_comments": [["<#", "#>"]],
      "quotes": [
        ["\\\"", "\\\""],
        ["'", "'"],
        ["\\\"@", "@\\\""],
        ["@'", "'@"]
      ],
      "extensions": ["ps1", "psm1", "psd1", "ps1xml", "cdxml", "pssc", "psc1"]
    },
    "PRACTICE": {
      "name": "Lauterbach PRACTICE Script",
      "line_comment": [";", "//"],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["cmm"]
    },
    "Processing": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["pde"]
    },
    "Prolog": {
      "line_comment": ["%"],
      "quotes": [["\\\"", "\\\""]],
      "multi_line_comments": [["/*", "*/"]],
      "extensions": ["p", "pro"]
    },
    "PSL": {
      "name": "PSL Assertion",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["psl"]
    },
    "Protobuf": {
      "name": "Protocol Buffers",
      "line_comment": ["//"],
      "extensions": ["proto"]
    },
    "Pug" : {
      "line_comment": ["//", "//-"],
      "quotes": [
        ["#{\\\"", "\\\"}"],
        ["#{'", "'}"],
        ["#{`", "`}"]
      ],
      "extensions": ["pug"]
    },
    "Puppet": {
      "line_comment": ["#"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["pp"]
    },
    "PureScript": {
      "nested": true,
      "line_comment": ["--"],
      "multi_line_comments": [["{-", "-}"]],
      "extensions": ["purs"]
    },
    "Pyret": {
      "line_comment": ["#"],
      "multi_line_comments": [["#|", "|#"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["arr"],
      "nested": true
    },
    "Python": {
      "line_comment": ["#"],
      "doc_quotes": [["\\\"\\\"\\\"", "\\\"\\\"\\\""], ["'''", "'''"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "env": ["python", "python2", "python3"],
      "mime": ["text/x-python"],
      "extensions": ["py", "pyw", "pyi"]
    },
    "PRQL": {
      "line_comment": ["#"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "mime": ["application/prql"],
      "extensions": ["prql"]
    },
    "Q": {
      "name": "Q",
      "nested": true,
      "line_comment": ["/"],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["q"]
    },
    "Qcl": {
      "name": "QCL",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["qcl"]
    },
    "Qml": {
      "name": "QML",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["qml"]
    },
    "R": {
      "line_comment": ["#"],
      "extensions": ["r"]
    },
    "Racket": {
      "line_comment": [";"],
      "multi_line_comments": [["#|", "|#"]],
      "nested": true,
      "env": ["racket"],
      "extensions": ["rkt", "scrbl"]
    },
    "Rakefile": {
      "line_comment": ["#"],
      "multi_line_comments": [["=begin", "=end"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "filenames": ["rakefile"],
      "extensions": ["rake"]
    },
    "Raku": {
      "shebangs": ["#!/usr/bin/raku", "#!/usr/bin/perl6"],
      "line_comment": ["#"],
      "multi_line_comments": [
        ["#`(", ")"],
        ["#`[", "]"],
        ["#`{", "}"],
        ["#`「", "」"]
      ],
      "nested": true,
      "quotes": [["\\\"", "\\\""] , ["'", "'"]],
      "verbatim_quotes": [["「", "」"]],
      "doc_quotes": [
        ["#|{", "}"],
        ["#={", "}"],
        ["#|(", ")"],
        ["#=(", ")"],
        ["#|[", "]"],
        ["#=[", "]"],
        ["#|「", "」"],
        ["#=「", "」"],
        ["=begin pod", "=end pod"],
        ["=begin code", "=end code"],
        ["=begin head", "=end head"],
        ["=begin item", "=end item"],
        ["=begin table", "=end table"],
        ["=begin defn", "=end defn"],
        ["=begin para", "=end para"],
        ["=begin comment", "=end comment"],
        ["=begin data", "=end data"],
        ["=begin DESCRIPTION", "=end DESCRIPTION"],
        ["=begin SYNOPSIS", "=end SYNOPSIS"],
        ["=begin ", "=end "]
      ],
      "env": ["raku", "perl6"],
      "extensions": ["raku", "rakumod", "rakutest", "pm6", "pl6", "p6"]
    },
    "Razor": {
      "line_comment": ["//"],
      "multi_line_comments": [["<!--", "-->"], ["@*", "*@"], ["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "verbatim_quotes": [["@\\\"", "\\\""]],
      "extensions": ["cshtml", "razor"]
    },
    "Redscript": {
      "name": "Redscript",
      "line_comment": ["//", "///"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "nested": true,
      "extensions": ["reds"]
    },
    "Renpy": {
      "name": "Ren'Py",
      "line_comment": ["#"],
      "quotes": [["\\\"", "\\\""], ["'", "'"], ["`", "`"]],
      "extensions": ["rpy"]
    },
    "ReScript": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["res", "resi"]
    },
    "ReStructuredText": {
      "blank": true,
      "extensions": ["rst"]
    },
    "Roc": {
      "line_comment": ["#"],
      "quotes": [
        ["\\\"", "\\\""],
        ["'", "'"]
      ],
      "doc_quotes": [["\\\"\\\"\\\"", "\\\"\\\"\\\""]],
      "extensions": ["roc"]
    },
    "RON": {
      "name": "Rusty Object Notation",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "nested": true,
      "extensions": ["ron"]
    },
    "RPMSpecfile": {
      "name": "RPM Specfile",
      "line_comment": ["#"],
      "extensions": ["spec"]
    },
    "Ruby": {
      "line_comment": ["#"],
      "multi_line_comments": [["=begin", "=end"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "env": ["ruby"],
      "extensions": ["rb"]
    },
    "RubyHtml": {
      "name": "Ruby HTML",
      "multi_line_comments": [["<!--", "-->"]],
      "important_syntax": ["<script", "<style"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["rhtml", "erb"]
    },
    "Rust": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "nested": true,
      "important_syntax": ["///", "//!"],
      "extensions": ["rs"],
      "quotes": [["\\\"", "\\\""], ["#\\\"", "\\\"#"]],
      "verbatim_quotes": [["r##\\\"", "\\\"##"], ["r#\\\"", "\\\"#"]]
    },
    "Sass": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["sass", "scss"]
    },
    "Scala": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["sc", "scala"]
    },
    "Scheme": {
      "line_comment": [";"],
      "multi_line_comments": [["#|", "|#"]],
      "nested": true,
      "extensions": ["scm", "ss"]
    },
    "Scons": {
      "line_comment": ["#"],
      "quotes": [
        ["\\\"", "\\\""],
        ["'", "'"],
        ["\\\"\\\"\\\"", "\\\"\\\"\\\""],
        ["'''", "'''"]
      ],
      "filenames": ["sconstruct", "sconscript"]
    },
    "Sh": {
      "name": "Shell",
      "shebangs": ["#!/bin/sh"],
      "line_comment": ["#"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "env": ["sh"],
      "extensions": ["sh"]
    },
    "ShaderLab": {
      "name": "ShaderLab",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["shader", "cginc"]
    },
    "SIL": {
      "name": "SIL",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"], ["/+", "+/"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"], ["`", "`"]],
      "extensions": ["sil"]
    },
    "Slang": {
      "name": "Slang",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["slang"]
    },
    "Sml": {
      "name": "Standard ML (SML)",
      "quotes": [["\\\"", "\\\""]],
      "multi_line_comments": [["(*", "*)"]],
      "extensions": ["sml"]
    },
    "Smalltalk": {
      "name": "Smalltalk",
      "quotes": [["'", "'"]],
      "multi_line_comments": [["\\\"", "\\\""]],
      "extensions": ["cs.st", "pck.st"]
    },
    "Snakemake": {
      "line_comment": ["#"],
      "doc_quotes": [["\\\"\\\"\\\"", "\\\"\\\"\\\""], ["'''", "'''"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["smk", "rules"],
      "filenames": ["snakefile"]
    },
    "Solidity": {
      "name": "Solidity",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["sol"]
    },
    "SpecmanE": {
      "name": "Specman e",
      "line_comment": ["--", "//"],
      "multi_line_comments": [["'>", "<'"]],
      "extensions": ["e"]
    },
    "Spice": {
      "name": "Spice Netlist",
      "line_comment": ["*"],
      "extensions": ["ckt"]
    },
    "Sql": {
      "name": "SQL",
      "line_comment": ["--"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["'", "'"]],
      "extensions": ["sql"]
    },
    "Sqf": {
      "name": "SQF",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["sqf"]
    },
    "SRecode": {
      "name": "SRecode Template",
      "line_comment": [";;"],
      "extensions": ["srt"]
    },
    "Stan": {
      "line_comment": ["//", "#"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["stan"]
    },
    "Stata": {
      "line_comment": ["//", "*"],
      "multi_line_comments": [["/*", "*/"]],
      "extensions": ["do"]
    },
    "Stratego": {
      "name": "Stratego/XT",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["$[", "]"], ["$<", ">"], ["${", "}"]],
      "extensions": ["str"]
    },
    "Stylus": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["styl"]
    },
    "Svelte": {
      "multi_line_comments": [["<!--", "-->"]],
      "important_syntax": ["<script", "<style"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["svelte"]
    },
    "Svg": {
      "name": "SVG",
      "multi_line_comments": [["<!--", "-->"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "mime": ["image/svg+xml"],
      "extensions": ["svg"]
    },
    "Swift": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "nested": true,
      "extensions": ["swift"]
    },
    "Swig": {
      "name": "SWIG",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "nested": true,
      "extensions": ["swg", "i"]
    },
    "SystemVerilog": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["sv", "svh"]
    },
    "Slint": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["slint"]
    },
    "Tact": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["tact"]
    },
    "Tcl": {
      "name": "TCL",
      "line_comment": ["#"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["tcl"]
    },
    "Tera": {
      "multi_line_comments": [["<!--", "-->"], ["{#", "#}"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["tera"]
    },
    "Templ": {
      "name": "Templ",
      "line_comment": ["//"],
      "multi_line_comments": [["<!--", "-->"], ["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"], ["`", "`"]],
      "important_syntax": ["templ", "script", "css"],
      "extensions": ["templ", "tmpl"]
    },
    "Tex": {
      "name": "TeX",
      "line_comment": ["%"],
      "extensions": ["tex", "sty"]
    },
    "Text": {
      "name": "Plain Text",
      "literate": true,
      "mime": ["text/plain"],
      "extensions": ["text", "txt"]
    },
    "Thrift": {
      "line_comment": ["#", "//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["thrift"]
    },
    "Toml": {
      "name": "TOML",
      "line_comment": ["#"],
      "quotes": [
        ["\\\"", "\\\""],
        ["'", "'"],
        ["\\\"\\\"\\\"", "\\\"\\\"\\\""],
        ["'''", "'''"]
      ],
      "extensions": ["toml"]
    },
    "Tsx": {
      "name": "TSX",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"], ["`", "`"]],
      "extensions": ["tsx"]
    },
    "Ttcn": {
      "name": "TTCN-3",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["ttcn", "ttcn3", "ttcnpp"]
    },
    "Twig": {
      "name": "Twig",
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["twig"],
      "multi_line_comments": [["<!--", "-->"], ["{#", "#}"]]
    },
    "TypeScript": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"], ["`", "`"]],
      "extensions": ["ts", "mts", "cts"]
    },
    "Typst": {
      "nested": true,
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["typ"]
    },
    "Uiua": {
      "line_comment": ["#"],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["ua"]
    },
    "UMPL": {
      "line_comment": ["!"],
      "quotes": [["`", "`"]],
      "extensions": ["umpl"]
    },
    "Unison": {
      "nested": true,
      "line_comment": ["--"],
      "multi_line_comments": [["{-", "-}"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["u"]
    },
    "UnrealDeveloperMarkdown": {
      "name": "Unreal Markdown",
      "important_syntax": ["```"],
      "extensions": ["udn"]
    },
    "UnrealPlugin": {
      "name": "Unreal Plugin",
      "blank": true,
      "extensions": ["uplugin"]
    },
    "UnrealProject": {
      "name": "Unreal Project",
      "blank": true,
      "extensions": ["uproject"]
    },
    "UnrealScript": {
      "name": "Unreal Script",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["uc", "uci", "upkg"]
    },
    "UnrealShader": {
      "name": "Unreal Shader",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["usf"]
    },
    "UnrealShaderHeader": {
      "name": "Unreal Shader Header",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["ush"]
    },
    "UrWeb": {
      "name": "Ur/Web",
      "quotes": [["\\\"", "\\\""]],
      "multi_line_comments": [["(*", "*)"]],
      "extensions": ["ur", "urs"]
    },
    "UrWebProject": {
      "name": "Ur/Web Project",
      "line_comment": ["#"],
      "extensions": ["urp"]
    },
    "Vala": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["vala"]
    },
    "VB6": {
      "name": "VB6/VBA",
      "line_comment": ["'"],
      "extensions": ["frm", "bas", "cls", "ctl", "dsr"]
    },
    "VBScript": {
      "name": "VBScript",
      "line_comment": ["'", "REM"],
      "extensions": ["vbs"]
    },
    "Velocity": {
      "name": "Apache Velocity",
      "line_comment": ["##"],
      "multi_line_comments": [["#*", "*#"]],
      "extensions": ["vm"],
      "quotes": [["'", "'"], ["\\\"", "\\\""]]
    },
    "Verilog": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["vg", "vh"]
    },
    "VerilogArgsFile": {
      "name": "Verilog Args File",
      "extensions": ["irunargs", "xrunargs"]
    },
    "Vhdl": {
      "name": "VHDL",
      "line_comment": ["--"],
      "multi_line_comments": [["/*", "*/"]],
      "extensions": ["vhd", "vhdl"]
    },
    "Virgil": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["v3"]
    },
    "VisualBasic": {
      "name": "Visual Basic",
      "quotes": [["\\\"", "\\\""]],
      "line_comment": ["'"],
      "extensions": ["vb"]
    },
    "VisualStudioProject": {
      "name": "Visual Studio Project",
      "multi_line_comments": [["<!--", "-->"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["vcproj", "vcxproj"]
    },
    "VisualStudioSolution": {
      "name": "Visual Studio Solution",
      "blank": true,
      "extensions": ["sln"]
    },
    "VimScript": {
      "name": "Vim Script",
      "line_comment": ["\\\""],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["vim"]
    },
    "Vue": {
      "name": "Vue",
      "line_comment": ["//"],
      "multi_line_comments": [["<!--", "-->"], ["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"], ["`", "`"]],
      "important_syntax": ["<script", "<style", "<template"],
      "extensions": ["vue"]
    },
    "WebAssembly": {
      "line_comment": [";;"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["wat", "wast"]
    },
    "WenYan":{
      "name":"The WenYan Programming Language",
      "multi_line_comments":[["批曰。","。"],["疏曰。","。"]],
      "extensions":["wy"]
    },
    "WGSL": {
      "name": "WebGPU Shader Language",
      "line_comment": ["//"],
      "extensions": ["wgsl"]
    },
    "Wolfram": {
      "quotes": [["\\\"", "\\\""]],
      "multi_line_comments": [["(*", "*)"]],
      "extensions": ["nb", "wl"]
    },
    "Xaml": {
      "name": "XAML",
      "multi_line_comments": [["<!--", "-->"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["xaml"]
    },
    "XcodeConfig": {
      "name": "Xcode Config",
      "line_comment": ["//"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["xcconfig"]
    },
    "Xml": {
      "name": "XML",
      "multi_line_comments": [["<!--", "-->"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["xml"]
    },
    "XSL": {
      "name": "XSL",
      "multi_line_comments": [["<!--", "-->"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["xsl", "xslt"]
    },
    "Xtend": {
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"], ["'''", "'''"]],
      "extensions": ["xtend"]
    },
    "Yaml": {
      "name": "YAML",
      "line_comment": ["#"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["yaml", "yml"]
    },
    "ZenCode": {
      "line_comment": ["//", "#"],
      "multi_line_comments": [["/*", "*/"]],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "verbatim_quotes": [["@\\\"", "\\\""], ["@'", "'"]],
      "extensions": ["zs"]
    },
    "Zig": {
      "line_comment": ["//"],
      "quotes": [["\\\"", "\\\""]],
      "extensions": ["zig"]
    },
    "Zokrates": {
      "name": "ZoKrates",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "extensions": ["zok"]
    },
    "Zsh": {
      "shebangs": ["#!/bin/zsh"],
      "line_comment": ["#"],
      "quotes": [["\\\"", "\\\""], ["'", "'"]],
      "extensions": ["zsh"]
    },
    "GdShader": {
      "name": "GDShader",
      "line_comment": ["//"],
      "multi_line_comments": [["/*", "*/"]],
      "extensions": ["gdshader"]
    }
  }
}


================================================
FILE: src/cli.rs
================================================
use std::{process, str::FromStr};

use clap::{crate_description, value_parser, Arg, ArgAction, ArgMatches};
use colored::Colorize;
use tokei::{Config, LanguageType, Sort};

use crate::{
    cli_utils::{crate_version, parse_or_exit, NumberFormatStyle},
    consts::{
        BLANKS_COLUMN_WIDTH, CODE_COLUMN_WIDTH, COMMENTS_COLUMN_WIDTH, LANGUAGE_COLUMN_WIDTH,
        LINES_COLUMN_WIDTH, PATH_COLUMN_WIDTH,
    },
    input::Format,
};

/// Used for sorting languages.
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub enum Streaming {
    /// simple lines.
    Simple,
    /// Json outputs.
    Json,
}

impl std::str::FromStr for Streaming {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(match s.to_lowercase().as_ref() {
            "simple" => Streaming::Simple,
            "json" => Streaming::Json,
            s => return Err(format!("Unsupported streaming option: {}", s)),
        })
    }
}

#[derive(Debug)]
pub struct Cli {
    matches: ArgMatches,
    pub columns: Option<usize>,
    pub files: bool,
    pub hidden: bool,
    pub no_ignore: bool,
    pub no_ignore_parent: bool,
    pub no_ignore_dot: bool,
    pub no_ignore_vcs: bool,
    pub output: Option<Format>,
    pub streaming: Option<Streaming>,
    pub print_languages: bool,
    pub sort: Option<Sort>,
    pub sort_reverse: bool,
    pub types: Option<Vec<LanguageType>>,
    pub compact: bool,
    pub number_format: num_format::CustomFormat,
}

impl Cli {
    pub fn from_args() -> Self {
        let matches = clap::Command::new("tokei")
            .version(crate_version())
            .author("Erin P. <xampprocky@gmail.com> + Contributors")
            .styles(clap_cargo::style::CLAP_STYLING)
            .about(concat!(
                crate_description!(),
                "\n",
                "Support this project on GitHub Sponsors: https://github.com/sponsors/XAMPPRocky"
            ))
            .arg(
                Arg::new("columns")
                    .long("columns")
                    .short('c')
                    .value_parser(value_parser!(usize))
                    .conflicts_with("output")
                    .help(
                        "Sets a strict column width of the output, only available for \
                        terminal output.",
                    ),
            )
            .arg(
                Arg::new("exclude")
                    .long("exclude")
                    .short('e')
                    .action(ArgAction::Append)
                    .help("Ignore all files & directories matching the pattern."),
            )
            .arg(
                Arg::new("files")
                    .long("files")
                    .short('f')
                    .action(ArgAction::SetTrue)
                    .help("Will print out statistics on individual files."),
            )
            .arg(
                Arg::new("file_input")
                    .long("input")
                    .short('i')
                    .help(
                        "Gives statistics from a previous tokei run. Can be given a file path, \
                        or \"stdin\" to read from stdin.",
                    ),
            )
            .arg(
                Arg::new("hidden")
                    .long("hidden")
                    .action(ArgAction::SetTrue)
                    .help("Count hidden files."),
            )
            .arg(
                Arg::new("input")
                    .num_args(1..)
                    .conflicts_with("languages")
                    .help("The path(s) to the file or directory to be counted. (default current directory)"),
            )
            .arg(
                Arg::new("languages")
                    .long("languages")
                    .short('l')
                    .action(ArgAction::SetTrue)
                    .conflicts_with("input")
                    .help("Prints out supported languages and their extensions."),
            )
            .arg(Arg::new("no_ignore")
                .long("no-ignore")
                .action(ArgAction::SetTrue)
                .help(
                    "\
                        Don't respect ignore files (.gitignore, .ignore, etc.). This implies \
                        --no-ignore-parent, --no-ignore-dot, and --no-ignore-vcs.\
                    ",
                ))
            .arg(Arg::new("no_ignore_parent")
                .long("no-ignore-parent")
                .action(ArgAction::SetTrue)
                .help(
                    "\
                        Don't respect ignore files (.gitignore, .ignore, etc.) in parent \
                        directories.\
                    ",
                ))
            .arg(Arg::new("no_ignore_dot")
                .long("no-ignore-dot")
                .action(ArgAction::SetTrue)
                .help(
                    "\
                        Don't respect .ignore and .tokeignore files, including those in \
                        parent directories.\
                    ",
                ))
            .arg(Arg::new("no_ignore_vcs")
                .long("no-ignore-vcs")
                .action(ArgAction::SetTrue)
                .help(
                    "\
                        Don't respect VCS ignore files (.gitignore, .hgignore, etc.) including \
                        those in parent directories.\
                    ",
                ))
            .arg(
                Arg::new("output")
                    .long("output")
                    .short('o')
                    .value_parser(Format::from_str)
                    .help(
                        "Outputs Tokei in a specific format. Compile with additional features for \
                        more format support.",
                    ),
            )
            .arg(
                Arg::new("streaming")
                    .long("streaming")
                    .value_parser(["simple", "json"])
                    .ignore_case(true)
                    .help(
                        "prints the (language, path, lines, blanks, code, comments) records as \
                        simple lines or as Json for batch processing",
                    ),
            )
            .arg(
                Arg::new("sort")
                    .long("sort")
                    .short('s')
                    .value_parser(["files", "lines", "blanks", "code", "comments"])
                    .ignore_case(true)
                    .conflicts_with("rsort")
                    .help("Sort languages based on column"),
            )
            .arg(
                Arg::new("rsort")
                    .long("rsort")
                    .short('r')
                    .value_parser(["files", "lines", "blanks", "code", "comments"])
                    .ignore_case(true)
                    .conflicts_with("sort")
                    .help("Reverse sort languages based on column"),
            )
            .arg(
                Arg::new("types")
                    .long("types")
                    .short('t')
                    .action(ArgAction::Append)
                    .help(
                        "Filters output by language type, separated by a comma. i.e. \
                        -t=Rust,Markdown",
                    ),
            )
            .arg(
                Arg::new("compact")
                    .long("compact")
                    .short('C')
                    .action(ArgAction::SetTrue)
                    .help("Do not print statistics about embedded languages."),
            )
            .arg(
                Arg::new("num_format_style")
                    .long("num-format")
                    .short('n')
                    .value_parser(["commas", "dots", "plain", "underscores"])
                    .conflicts_with("output")
                    .help(
                        "Format of printed numbers, i.e., plain (1234, default), \
                        commas (1,234), dots (1.234), or underscores (1_234). Cannot be \
                        used with --output.",
                    ),
            )
            .arg(
                Arg::new("verbose")
                    .long("verbose")
                    .short('v')
                    .action(ArgAction::Count)
                    .help(
                        "Set log output level:
                        1: to show unknown file extensions,
                        2: reserved for future debugging,
                        3: enable file level trace. Not recommended on multiple files",
                    ),
            )
            .get_matches();

        let columns = matches.get_one::<usize>("columns").cloned();
        let files = matches.get_flag("files");
        let hidden = matches.get_flag("hidden");
        let no_ignore = matches.get_flag("no_ignore");
        let no_ignore_parent = matches.get_flag("no_ignore_parent");
        let no_ignore_dot = matches.get_flag("no_ignore_dot");
        let no_ignore_vcs = matches.get_flag("no_ignore_vcs");
        let print_languages = matches.get_flag("languages");
        let verbose = matches.get_count("verbose") as u64;
        let compact = matches.get_flag("compact");
        let types = matches.get_many("types").map(|e| {
            e.flat_map(|x: &String| {
                x.split(',')
                    .map(str::parse::<LanguageType>)
                    .filter_map(Result::ok)
                    .collect::<Vec<_>>()
            })
            .collect()
        });

        let num_format_style = matches
            .get_one::<String>("num_format_style")
            .map(parse_or_exit::<NumberFormatStyle>)
            .unwrap_or_default();

        let number_format = match num_format_style.get_format() {
            Ok(format) => format,
            Err(e) => {
                eprintln!("Error:\n{}", e);
                process::exit(1);
            }
        };

        let sort = matches.get_one::<String>("sort");
        let rsort = matches.get_one::<String>("rsort");
        let sort = sort.or(rsort).map(parse_or_exit);
        let sort_reverse = rsort.is_some();

        // Format category is overly accepting by clap (so the user knows what
        // is supported) but this will fail if support is not compiled in and
        // give a useful error to the user.
        let output = matches.get_one("output").cloned();
        let streaming = matches.get_one::<String>("streaming").map(parse_or_exit);

        crate::cli_utils::setup_logger(verbose);

        let cli = Cli {
            matches,
            columns,
            files,
            hidden,
            no_ignore,
            no_ignore_parent,
            no_ignore_dot,
            no_ignore_vcs,
            output,
            streaming,
            print_languages,
            sort,
            sort_reverse,
            types,
            compact,
            number_format,
        };

        debug!("CLI Config: {:#?}", cli);

        cli
    }

    pub fn file_input(&self) -> Option<&String> {
        self.matches.get_one("file_input")
    }

    pub fn ignored_directories(&self) -> Vec<&str> {
        let mut ignored_directories: Vec<&str> = Vec::new();
        if let Some(user_ignored) = self.matches.get_many::<String>("exclude") {
            ignored_directories.extend(user_ignored.map(|x| x.as_str()));
        }
        ignored_directories
    }

    pub fn input(&self) -> Vec<&str> {
        match self.matches.get_many::<String>("input") {
            Some(vs) => vs.map(|x| x.as_str()).collect(),
            None => vec!["."],
        }
    }

    pub fn print_supported_languages() -> Result<(), Box<dyn std::error::Error>> {
        use table_formatter::table::*;
        use table_formatter::{cell, table};
        let term_width = term_size::dimensions().map(|(w, _)| w).unwrap_or(75) - 8;
        let (lang_w, suffix_w) = if term_width <= 80 {
            (term_width / 2, term_width / 2)
        } else {
            (40, term_width - 40)
        };

        let header = vec![
            cell!(
                "Language",
                align = Align::Left,
                padding = Padding::NONE,
                width = Some(lang_w)
            )
            .with_formatter(vec![table_formatter::table::FormatterFunc::Normal(
                Colorize::bold,
            )]),
            cell!(
                "Extensions",
                align = Align::Left,
                padding = Padding::new(3, 0),
                width = Some(suffix_w)
            )
            .with_formatter(vec![table_formatter::table::FormatterFunc::Normal(
                Colorize::bold,
            )]),
        ];
        let content = LanguageType::list()
            .iter()
            .map(|(key, ext)| {
                vec![
                    // table::TableCell::new(table::Cell::TextCell(key.name().to_string()))
                    //     .with_width(lang_w),
                    cell!(key.name()).with_width(Some(lang_w)),
                    cell!(
                        if matches!(key, LanguageType::Emojicode) {
                            ext.join(", ") + "\u{200b}"
                        } else if ext.is_empty() {
                            "<None>".to_string()
                        } else {
                            ext.join(", ")
                        },
                        align = Align::Left,
                        padding = Padding::new(3, 0),
                        width = Some(suffix_w)
                    ),
                ]
            })
            .collect();
        let t = table!(header - content with Border::ALL);

        let mut render_result = Vec::new();
        t.render(&mut render_result)?;
        println!("{}", String::from_utf8(render_result)?);
        Ok(())
    }

    /// Overrides the shared options (See `tokei::Config` for option
    /// descriptions) between the CLI and the config files. CLI flags have
    /// higher precedence than options present in config files.
    ///
    /// #### Shared options
    /// * `hidden`
    /// * `no_ignore`
    /// * `no_ignore_parent`
    /// * `no_ignore_dot`
    /// * `no_ignore_vcs`
    /// * `types`
    pub fn override_config(&mut self, mut config: Config) -> Config {
        config.hidden = if self.hidden {
            Some(true)
        } else {
            config.hidden
        };

        config.no_ignore = if self.no_ignore {
            Some(true)
        } else {
            config.no_ignore
        };

        config.no_ignore_parent = if self.no_ignore_parent {
            Some(true)
        } else {
            config.no_ignore_parent
        };

        config.no_ignore_dot = if self.no_ignore_dot {
            Some(true)
        } else {
            config.no_ignore_dot
        };

        config.no_ignore_vcs = if self.no_ignore_vcs {
            Some(true)
        } else {
            config.no_ignore_vcs
        };

        config.for_each_fn = match self.streaming {
            Some(Streaming::Json) => Some(|l: LanguageType, e| {
                println!("{}", serde_json::json!({"language": l.name(), "stats": e}));
            }),
            Some(Streaming::Simple) => Some(|l: LanguageType, e| {
                println!(
                    "{:>LANGUAGE_COLUMN_WIDTH$} {:<PATH_COLUMN_WIDTH$} {:>LINES_COLUMN_WIDTH$} {:>CODE_COLUMN_WIDTH$} {:>COMMENTS_COLUMN_WIDTH$} {:>BLANKS_COLUMN_WIDTH$}",
                    l.name(),
                    e.name.to_string_lossy().to_string(),
                    e.stats.lines(),
                    e.stats.code,
                    e.stats.comments,
                    e.stats.blanks
                );
            }),
            _ => None,
        };

        config.types = self.types.take().or(config.types);

        config
    }

    pub fn print_input_parse_failure(input_filename: &str) {
        eprintln!("Error:\n Failed to parse input file: {}", input_filename);

        let not_supported = Format::not_supported();
        if !not_supported.is_empty() {
            eprintln!(
                "
This version of tokei was compiled without serialization support for the following formats:

    {not_supported}

You may want to install any comma separated combination of {all:?}:

    cargo install tokei --features {all:?}

Or use the 'all' feature:

    cargo install tokei --features all
    \n",
                not_supported = not_supported.join(", "),
                // no space after comma to ease copypaste
                all = self::Format::all_feature_names().join(",")
            );
        }
    }
}


================================================
FILE: src/cli_utils.rs
================================================
use std::{
    borrow::Cow,
    fmt,
    io::{self, Write},
    process,
    str::FromStr,
};

use clap::crate_version;
use colored::Colorize;
use num_format::ToFormattedString;

use crate::input::Format;
use tokei::{find_char_boundary, CodeStats, Language, LanguageType, Report};

use crate::consts::{
    BLANKS_COLUMN_WIDTH, CODE_COLUMN_WIDTH, COMMENTS_COLUMN_WIDTH, FILES_COLUMN_WIDTH,
    LINES_COLUMN_WIDTH,
};

const NO_LANG_HEADER_ROW_LEN: usize = 69;
const NO_LANG_ROW_LEN: usize = 63;
const NO_LANG_ROW_LEN_NO_SPACES: usize = 56;
const IDENT_INACCURATE: &str = "(!)";

pub fn crate_version() -> String {
    if Format::supported().is_empty() {
        format!(
            "{} compiled without serialization formats.",
            crate_version!()
        )
    } else {
        format!(
            "{} compiled with serialization support: {}",
            crate_version!(),
            Format::supported().join(", ")
        )
    }
}

pub fn setup_logger(verbose_option: u64) {
    use log::LevelFilter;

    let mut builder = env_logger::Builder::new();

    let filter_level = match verbose_option {
        1 => LevelFilter::Warn,
        2 => LevelFilter::Debug,
        3 => LevelFilter::Trace,
        _ => LevelFilter::Error,
    };

    builder.filter(None, filter_level);
    builder.init();
}

pub fn parse_or_exit<T>(s: impl AsRef<str>) -> T
where
    T: FromStr,
    T::Err: fmt::Display,
{
    T::from_str(s.as_ref()).unwrap_or_else(|e| {
        eprintln!("Error:\n{}", e);
        process::exit(1);
    })
}

#[non_exhaustive]
#[derive(Debug, Copy, Clone)]
pub enum NumberFormatStyle {
    // 1234 (Default)
    Plain,
    // 1,234
    Commas,
    // 1.234
    Dots,
    // 1_234
    Underscores,
}

impl Default for NumberFormatStyle {
    fn default() -> Self {
        Self::Plain
    }
}

impl FromStr for NumberFormatStyle {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "plain" => Ok(Self::Plain),
            "commas" => Ok(Self::Commas),
            "dots" => Ok(Self::Dots),
            "underscores" => Ok(Self::Underscores),
            _ => Err(format!(
                "Expected 'plain', 'commas', 'underscores', or 'dots' for num-format, but got '{}'",
                s,
            )),
        }
    }
}

impl NumberFormatStyle {
    fn separator(self) -> &'static str {
        match self {
            Self::Plain => "",
            Self::Commas => ",",
            Self::Dots => ".",
            Self::Underscores => "_",
        }
    }

    pub fn get_format(self) -> Result<num_format::CustomFormat, num_format::Error> {
        num_format::CustomFormat::builder()
            .grouping(num_format::Grouping::Standard)
            .separator(self.separator())
            .build()
    }
}

pub struct Printer<W> {
    writer: W,
    columns: usize,
    path_length: usize,
    row: String,
    subrow: String,
    list_files: bool,
    number_format: num_format::CustomFormat,
}

impl<W> Printer<W> {
    pub fn new(
        columns: usize,
        list_files: bool,
        writer: W,
        number_format: num_format::CustomFormat,
    ) -> Self {
        Self {
            columns,
            list_files,
            path_length: columns - NO_LANG_ROW_LEN_NO_SPACES,
            writer,
            row: "━".repeat(columns),
            subrow: "─".repeat(columns),
            number_format,
        }
    }
}

impl<W: Write> Printer<W> {
    pub fn print_header(&mut self) -> io::Result<()> {
        self.print_row()?;

        let files_column_width: usize = FILES_COLUMN_WIDTH + 6;
        writeln!(
            self.writer,
            " {:<6$} {:>files_column_width$} {:>LINES_COLUMN_WIDTH$} {:>CODE_COLUMN_WIDTH$} {:>COMMENTS_COLUMN_WIDTH$} {:>BLANKS_COLUMN_WIDTH$}",
            "Language".bold().blue(),
            "Files".bold().blue(),
            "Lines".bold().blue(),
            "Code".bold().blue(),
            "Comments".bold().blue(),
            "Blanks".bold().blue(),
            self.columns - NO_LANG_HEADER_ROW_LEN
        )?;
        self.print_row()
    }

    pub fn print_inaccuracy_warning(&mut self) -> io::Result<()> {
        writeln!(
            self.writer,
            "Note: results can be inaccurate for languages marked with '{}'",
            IDENT_INACCURATE
        )
    }

    pub fn print_language(&mut self, language: &Language, name: &str) -> io::Result<()>
    where
        W: Write,
    {
        self.print_language_name(language.inaccurate, name, None)?;
        write!(self.writer, " ")?;
        writeln!(
            self.writer,
            "{:>FILES_COLUMN_WIDTH$} {:>LINES_COLUMN_WIDTH$} {:>CODE_COLUMN_WIDTH$} {:>COMMENTS_COLUMN_WIDTH$} {:>BLANKS_COLUMN_WIDTH$}",
            language
                .reports
                .len()
                .to_formatted_string(&self.number_format),
            language.lines().to_formatted_string(&self.number_format),
            language.code.to_formatted_string(&self.number_format),
            language.comments.to_formatted_string(&self.number_format),
            language.blanks.to_formatted_string(&self.number_format),
        )
    }

    fn print_language_in_print_total(&mut self, language: &Language) -> io::Result<()>
    where
        W: Write,
    {
        self.print_language_name(language.inaccurate, "Total", None)?;
        write!(self.writer, " ")?;
        writeln!(
            self.writer,
            "{:>FILES_COLUMN_WIDTH$} {:>LINES_COLUMN_WIDTH$} {:>CODE_COLUMN_WIDTH$} {:>COMMENTS_COLUMN_WIDTH$} {:>BLANKS_COLUMN_WIDTH$}",
            language
                .children
                .values()
                .map(Vec::len)
                .sum::<usize>()
                .to_formatted_string(&self.number_format)
                .blue(),
            language
                .lines()
                .to_formatted_string(&self.number_format)
                .blue(),
            language
                .code
                .to_formatted_string(&self.number_format)
                .blue(),
            language
                .comments
                .to_formatted_string(&self.number_format)
                .blue(),
            language
                .blanks
                .to_formatted_string(&self.number_format)
                .blue(),
        )
    }

    pub fn print_language_name(
        &mut self,
        inaccurate: bool,
        name: &str,
        prefix: Option<&str>,
    ) -> io::Result<()> {
        let mut lang_section_len = self.columns - NO_LANG_ROW_LEN - prefix.map_or(0, str::len);
        if inaccurate {
            lang_section_len -= IDENT_INACCURATE.len();
        }

        if let Some(prefix) = prefix {
            write!(self.writer, "{}", prefix)?;
        }
        // truncate and replace the last char with a `|` if the name is too long
        if lang_section_len < name.len() {
            write!(self.writer, " {:.len$}", name, len = lang_section_len - 1)?;
            write!(self.writer, "|")?;
        } else {
            write!(
                self.writer,
                " {:<len$}",
                name.bold().magenta(),
                len = lang_section_len
            )?;
        }
        if inaccurate {
            write!(self.writer, "{}", IDENT_INACCURATE)?;
        };

        Ok(())
    }

    fn print_code_stats(
        &mut self,
        language_type: LanguageType,
        stats: &[CodeStats],
    ) -> io::Result<()> {
        self.print_language_name(false, &language_type.to_string(), Some(" |-"))?;
        let mut code = 0;
        let mut comments = 0;
        let mut blanks = 0;

        for stats in stats.iter().map(tokei::CodeStats::summarise) {
            code += stats.code;
            comments += stats.comments;
            blanks += stats.blanks;
        }

        if stats.is_empty() {
            Ok(())
        } else {
            writeln!(
                self.writer,
                " {:>FILES_COLUMN_WIDTH$} {:>LINES_COLUMN_WIDTH$} {:>CODE_COLUMN_WIDTH$} {:>COMMENTS_COLUMN_WIDTH$} {:>BLANKS_COLUMN_WIDTH$}",
                stats.len().to_formatted_string(&self.number_format),
                (code + comments + blanks).to_formatted_string(&self.number_format),
                code.to_formatted_string(&self.number_format),
                comments.to_formatted_string(&self.number_format),
                blanks.to_formatted_string(&self.number_format),
            )
        }
    }

    fn print_language_total(&mut self, parent: &Language) -> io::Result<()> {
        for (language, reports) in &parent.children {
            self.print_code_stats(
                *language,
                &reports
                    .iter()
                    .map(|r| r.stats.summarise())
                    .collect::<Vec<_>>(),
            )?;
        }
        let mut subtotal = tokei::Report::new("(Total)".into());
        let summary = parent.summarise();
        subtotal.stats.code += summary.code;
        subtotal.stats.comments += summary.comments;
        subtotal.stats.blanks += summary.blanks;
        self.print_report_with_name(&subtotal)?;

        Ok(())
    }

    pub fn print_results<'a, I>(
        &mut self,
        languages: I,
        compact: bool,
        is_sorted: bool,
    ) -> io::Result<()>
    where
        I: Iterator<Item = (&'a LanguageType, &'a Language)>,
    {
        let (a, b): (Vec<_>, Vec<_>) = languages
            .filter(|(_, v)| !v.is_empty())
            .partition(|(_, l)| compact || l.children.is_empty());
        let mut first = true;

        for languages in &[&a, &b] {
            for &(name, language) in *languages {
                let has_children = !(compact || language.children.is_empty());
                if first {
                    first = false;
                } else if has_children || self.list_files {
                    self.print_subrow()?;
                }

                self.print_language(language, name.name())?;
                if has_children {
                    self.print_language_total(language)?;
                }

                if self.list_files {
                    self.print_subrow()?;
                    let mut reports: Vec<&Report> = language.reports.iter().collect();
                    if !is_sorted {
                        reports.sort_by(|&a, &b| a.name.cmp(&b.name));
                    }
                    if compact {
                        for &report in &reports {
                            writeln!(self.writer, "{:1$}", report, self.path_length)?;
                        }
                    } else {
                        let (a, b): (Vec<&Report>, Vec<&Report>) =
                            reports.iter().partition(|&r| r.stats.blobs.is_empty());
                        for reports in &[&a, &b] {
                            let mut first = true;
                            for report in reports.iter() {
                                if report.stats.blobs.is_empty() {
                                    writeln!(self.writer, "{:1$}", report, self.path_length)?;
                                } else {
                                    if first && a.is_empty() {
                                        writeln!(self.writer, " {}", report.name.display())?;
                                        first = false;
                                    } else {
                                        writeln!(
                                            self.writer,
                                            "-- {} {}",
                                            report.name.display(),
                                            "-".repeat(
                                                self.columns
                                                    - 4
                                                    - report.name.display().to_string().len()
                                            )
                                        )?;
                                    }
                                    let mut new_report = (*report).clone();
                                    new_report.name = name.to_string().into();
                                    writeln!(
                                        self.writer,
                                        " |-{:1$}",
                                        new_report,
                                        self.path_length - 3
                                    )?;
                                    self.print_report_total(report, language.inaccurate)?;
                                }
                            }
                        }
                    }
                }
            }
        }

        Ok(())
    }

    fn print_row(&mut self) -> io::Result<()> {
        writeln!(self.writer, "{}", self.row)
    }

    fn print_subrow(&mut self) -> io::Result<()> {
        writeln!(self.writer, "{}", self.subrow.dimmed())
    }

    fn print_report(
        &mut self,
        language_type: LanguageType,
        stats: &CodeStats,
        inaccurate: bool,
    ) -> io::Result<()> {
        self.print_language_name(inaccurate, &language_type.to_string(), Some(" |-"))?;

        writeln!(
            self.writer,
            " {:>FILES_COLUMN_WIDTH$} {:>LINES_COLUMN_WIDTH$} {:>CODE_COLUMN_WIDTH$} {:>COMMENTS_COLUMN_WIDTH$} {:>BLANKS_COLUMN_WIDTH$}",
            " ",
            stats.lines().to_formatted_string(&self.number_format),
            stats.code.to_formatted_string(&self.number_format),
            stats.comments.to_formatted_string(&self.number_format),
            stats.blanks.to_formatted_string(&self.number_format),
        )
    }

    fn print_report_total(&mut self, report: &Report, inaccurate: bool) -> io::Result<()> {
        if report.stats.blobs.is_empty() {
            return Ok(());
        }

        let mut subtotal = tokei::Report::new("|- (Total)".into());
        subtotal.stats.code += report.stats.code;
        subtotal.stats.comments += report.stats.comments;
        subtotal.stats.blanks += report.stats.blanks;

        for (language_type, stats) in &report.stats.blobs {
            self.print_report(*language_type, stats, inaccurate)?;
            subtotal.stats += stats.summarise();
        }

        self.print_report_with_name(report)?;

        Ok(())
    }

    fn print_report_with_name(&mut self, report: &Report) -> io::Result<()> {
        let name = report.name.to_string_lossy();
        let name_length = name.len();

        if name_length > self.path_length {
            let mut formatted = String::from("|");
            // Add 1 to the index to account for the '|' we add to the output string
            let from = find_char_boundary(&name, name_length + 1 - self.path_length);
            formatted.push_str(&name[from..]);
        }
        self.print_report_total_formatted(name, self.path_length, report)?;

        Ok(())
    }

    fn print_report_total_formatted(
        &mut self,
        name: Cow<'_, str>,
        max_len: usize,
        report: &Report,
    ) -> io::Result<()> {
        let lines_column_width: usize = FILES_COLUMN_WIDTH + 6;
        writeln!(
            self.writer,
            " {: <max$} {:>lines_column_width$} {:>CODE_COLUMN_WIDTH$} {:>COMMENTS_COLUMN_WIDTH$} {:>BLANKS_COLUMN_WIDTH$}",
            name,
            report
                .stats
                .lines()
                .to_formatted_string(&self.number_format),
            report.stats.code.to_formatted_string(&self.number_format),
            report
                .stats
                .comments
                .to_formatted_string(&self.number_format),
            report.stats.blanks.to_formatted_string(&self.number_format),
            max = max_len
        )
    }

    pub fn print_total(&mut self, languages: &tokei::Languages) -> io::Result<()> {
        let total = languages.total();
        self.print_row()?;
        self.print_language_in_print_total(&total)?;
        self.print_row()
    }
}


================================================
FILE: src/config.rs
================================================
use std::{env, fs, path::PathBuf};

use etcetera::BaseStrategy;

use crate::language::LanguageType;
use crate::sort::Sort;
use crate::stats::Report;

/// A configuration struct for how [`Languages::get_statistics`] searches and
/// counts languages.
///
/// ```
/// use tokei::Config;
///
/// let config = Config {
///     treat_doc_strings_as_comments: Some(true),
///     ..Config::default()
/// };
/// ```
///
/// [`Languages::get_statistics`]: struct.Languages.html#method.get_statistics
#[derive(Debug, Default, Deserialize)]
pub struct Config {
    /// Width of columns to be printed to the terminal. _This option is ignored
    /// in the library._ *Default:* Auto detected width of the terminal.
    pub columns: Option<usize>,
    /// Count hidden files and directories. *Default:* `false`.
    pub hidden: Option<bool>,
    /// Don't respect ignore files (.gitignore, .ignore, etc.). This implies --no-ignore-parent,
    /// --no-ignore-dot, and --no-ignore-vcs. *Default:* `false`.
    pub no_ignore: Option<bool>,
    /// Don't respect ignore files (.gitignore, .ignore, etc.) in parent directories.
    /// *Default:* `false`.
    pub no_ignore_parent: Option<bool>,
    /// Don't respect .ignore and .tokeignore files, including those in parent directories.
    /// *Default:* `false`.
    pub no_ignore_dot: Option<bool>,
    /// Don't respect VCS ignore files (.gitignore, .hgignore, etc.), including those in
    /// parent directories. *Default:* `false`.
    pub no_ignore_vcs: Option<bool>,
    /// Whether to treat doc strings in languages as comments.  *Default:*
    /// `false`.
    pub treat_doc_strings_as_comments: Option<bool>,
    /// Sort languages. *Default:* `None`.
    pub sort: Option<Sort>,
    /// Filters languages searched to just those provided. E.g. A directory
    /// containing `C`, `Cpp`, and `Rust` with a `Config.types` of `[Cpp, Rust]`
    /// will count only `Cpp` and `Rust`. *Default:* `None`.
    pub types: Option<Vec<LanguageType>>,
    // /// A map of individual language configuration.
    // pub languages: Option<HashMap<LanguageType, LanguageConfig>>,
    /// Whether to output only the paths for downstream batch processing
    /// *Default:* false
    #[serde(skip)]
    /// Adds a closure for each function, e.g., print the result
    pub for_each_fn: Option<fn(LanguageType, Report)>,
}

impl Config {
    /// Constructs a new `Config` from either `$base/tokei.toml` or
    /// `$base/.tokeirc`. `tokei.toml` takes precedence over `.tokeirc`
    /// as the latter is a hidden file on Unix and not an idiomatic
    /// filename on Windows.
    fn get_config(base: PathBuf) -> Option<Self> {
        fs::read_to_string(base.join("tokei.toml"))
            .ok()
            .or_else(|| fs::read_to_string(base.join(".tokeirc")).ok())
            .and_then(|s| toml::from_str(&s).ok())
    }

    /// Creates a `Config` from three configuration files if they are available.
    /// Files can have two different names `tokei.toml` and `.tokeirc`.
    /// Firstly it will attempt to find a config in the configuration directory
    /// (see below), secondly from the home directory, `$HOME/`,
    /// and thirdly from the current directory, `./`.
    /// The current directory's configuration will take priority over the configuration
    /// directory.
    ///
    /// |Platform | Value                                 | Example                        |
    /// | ------- | ------------------------------------- | ------------------------------ |
    /// | Linux   | `$XDG_CONFIG_HOME` or `$HOME`/.config | /home/alice/.config            |
    /// | macOS   | `$XDG_CONFIG_HOME` or `$HOME`/.config | /Users/alice/.config           |
    /// | Windows | `{FOLDERID_RoamingAppData}`           | C:\Users\Alice\AppData\Roaming |
    ///
    /// # Example
    /// ```toml
    /// columns = 80
    /// types = ["Python"]
    /// treat_doc_strings_as_comments = true
    // ///
    // /// [[languages.Python]]
    // /// extensions = ["py3"]
    /// ```
    pub fn from_config_files() -> Self {
        let conf_dir = etcetera::choose_base_strategy()
            .ok()
            .map(|basedirs| basedirs.config_dir())
            .and_then(Self::get_config)
            .unwrap_or_default();

        let home_dir = etcetera::home_dir()
            .ok()
            .and_then(Self::get_config)
            .unwrap_or_default();

        let current_dir = env::current_dir()
            .ok()
            .and_then(Self::get_config)
            .unwrap_or_default();

        #[allow(clippy::or_fun_call)]
        Config {
            columns: current_dir
                .columns
                .or(home_dir.columns.or(conf_dir.columns)),
            hidden: current_dir.hidden.or(home_dir.hidden.or(conf_dir.hidden)),
            //languages: current_dir.languages.or(conf_dir.languages),
            treat_doc_strings_as_comments: current_dir.treat_doc_strings_as_comments.or(home_dir
                .treat_doc_strings_as_comments
                .or(conf_dir.treat_doc_strings_as_comments)),
            sort: current_dir.sort.or(home_dir.sort.or(conf_dir.sort)),
            types: current_dir.types.or(home_dir.types.or(conf_dir.types)),
            for_each_fn: current_dir
                .for_each_fn
                .or(home_dir.for_each_fn.or(conf_dir.for_each_fn)),
            no_ignore: current_dir
                .no_ignore
                .or(home_dir.no_ignore.or(conf_dir.no_ignore)),
            no_ignore_parent: current_dir
                .no_ignore_parent
                .or(home_dir.no_ignore_parent.or(conf_dir.no_ignore_parent)),
            no_ignore_dot: current_dir
                .no_ignore_dot
                .or(home_dir.no_ignore_dot.or(conf_dir.no_ignore_dot)),
            no_ignore_vcs: current_dir
                .no_ignore_vcs
                .or(home_dir.no_ignore_vcs.or(conf_dir.no_ignore_vcs)),
        }
    }
}

/*
/// Configuration for an individual [`LanguageType`].
///
/// ```
/// use std::collections::HashMap;
/// use tokei::{Config, LanguageConfig, LanguageType};
///
/// let config = Config {
///     languages: {
///         let cpp_conf = LanguageConfig {
///             extensions: vec![String::from("c")],
///         };
///
///         let mut languages_config = HashMap::new();
///         languages_config.insert(LanguageType::Cpp, cpp_conf);
///
///         Some(languages_config)
///     },
///
///     ..Config::default()
/// };
///
/// ```
///
/// [`LanguageType`]: enum.LanguageType.html
#[derive(Debug, Default, Deserialize)]
pub struct LanguageConfig {
    /// Additional extensions for a language. Any extensions that overlap with
    /// already defined extensions from `tokei` will be ignored.
    pub extensions: Vec<String>,
}

impl LanguageConfig {
    /// Creates a new empty configuration. By default this will not change
    /// anything from the default.
    pub fn new() -> Self {
        Self::default()
    }

    /// Accepts a `Vec<String>` representing additional extensions for a
    /// language. Any extensions that overlap with already defined extensions
    /// from `tokei` will be ignored.
    pub fn extensions(&mut self, extensions: Vec<String>) {
        self.extensions = extensions;
    }
}
*/


================================================
FILE: src/consts.rs
================================================
// Set of common pub consts.

/// Fallback row length
pub const FALLBACK_ROW_LEN: usize = 81;

// Column widths used for console printing.

/// Language column width
pub const LANGUAGE_COLUMN_WIDTH: usize = 10;

/// Path column width
pub const PATH_COLUMN_WIDTH: usize = 80;

/// Files column width
pub const FILES_COLUMN_WIDTH: usize = 8;

/// Lines column width
pub const LINES_COLUMN_WIDTH: usize = 12;

/// Code column width
pub const CODE_COLUMN_WIDTH: usize = 12;

/// Comments column width
pub const COMMENTS_COLUMN_WIDTH: usize = 12;

/// Blanks column width
pub const BLANKS_COLUMN_WIDTH: usize = 12;


================================================
FILE: src/input.rs
================================================
use serde::{Deserialize, Serialize};
use std::{collections::BTreeMap, error::Error, str::FromStr};

use tokei::{Language, LanguageType, Languages};

type LanguageMap = BTreeMap<LanguageType, Language>;

#[derive(Deserialize, Serialize, Debug)]
struct Output {
    #[serde(flatten)]
    languages: LanguageMap,
    #[serde(rename = "Total")]
    totals: Language,
}

macro_rules! supported_formats {
    ($(
        ($name:ident, $feature:expr, $variant:ident [$($krate:ident),+]) =>
            $parse_kode:expr,
            $print_kode:expr,
    )+) => (
        $( // for each format
            $( // for each required krate
                #[cfg(feature = $feature)] extern crate $krate;
            )+
        )+

        /// Supported serialization formats.
        ///
        /// To enable all formats compile with the `all` feature.
        #[cfg_attr(test, derive(strum_macros::EnumIter))]
        #[derive(Debug, Clone)]
        pub enum Format {
            Json,
            $(
                #[cfg(feature = $feature)] $variant
            ),+
            // TODO: Allow adding format at runtime when used as a lib?
        }

        impl Format {
            pub fn supported() -> &'static [&'static str] {
                &[
                    "json",
                    $(
                        #[cfg(feature = $feature)] stringify!($name)
                    ),+
                ]
            }

            pub fn all() -> &'static [&'static str] {
                &[
                    $( stringify!($name) ),+
                ]
            }

            pub fn all_feature_names() -> &'static [&'static str] {
                &[
                    $( $feature ),+
                ]
            }

            pub fn not_supported() -> &'static [&'static str] {
                &[
                    $(
                        #[cfg(not(feature = $feature))] stringify!($name)
                    ),+
                ]
            }

            pub fn parse(input: &str) -> Option<LanguageMap> {
                if input.is_empty() {
                    return None
                }

                if let Ok(Output { languages, .. }) = serde_json::from_str::<Output>(input) {
                    return Some(languages);
                }

                $(
                    // attributes are not yet allowed on `if` expressions
                    #[cfg(feature = $feature)]
                    {
                        let parse = &{ $parse_kode };

                        if let Ok(Output { languages, .. }) = parse(input) {
                            return Some(languages)
                        }
                    }
                )+

                // Didn't match any of the compiled serialization formats
                None
            }

            pub fn print(&self, languages: &Languages) -> Result<String, Box<dyn Error>> {
                let output = Output {
                    languages: (*languages).to_owned(),
                    totals: languages.total()
                };

                match *self {
                    Format::Json => Ok(serde_json::to_string(&output)?),
                    $(
                        #[cfg(feature = $feature)] Format::$variant => {
                            let print= &{ $print_kode };
                            Ok(print(&output)?)
                        }
                    ),+
                }
            }
        }

        impl FromStr for Format {
            type Err = String;

            fn from_str(format: &str) -> Result<Self, Self::Err> {
                match format {
                    "json" => Ok(Format::Json),
                    $(
                        stringify!($name) => {
                            #[cfg(feature = $feature)]
                            return Ok(Format::$variant);

                            #[cfg(not(feature = $feature))]
                            return Err(format!(
"This version of tokei was compiled without \
any '{format}' serialization support, to enable serialization, \
reinstall tokei with the features flag.

    cargo install tokei --features {feature}

If you want to enable all supported serialization formats, you can use the 'all' feature.

    cargo install tokei --features all\n",
                                format = stringify!($name),
                                feature = $feature)
 
Download .txt
gitextract_x6tby1jr/

├── .git-blame-ignore-revs
├── .gitattributes
├── .github/
│   ├── FUNDING.yml
│   └── workflows/
│       ├── mean_bean_ci.yml
│       ├── mean_bean_deploy.yml
│       ├── publish_image.yaml
│       └── release-plz.yaml
├── .gitignore
├── .mailmap
├── .tokeignore
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Cargo.toml
├── Earthfile
├── LICENCE-APACHE
├── LICENCE-MIT
├── README.md
├── benchmark.sh
├── build.rs
├── ci/
│   ├── build.bash
│   ├── common.bash
│   ├── set_rust_version.bash
│   └── test.bash
├── fuzz/
│   ├── .gitignore
│   ├── Cargo.toml
│   ├── README.md
│   └── fuzz_targets/
│       ├── parse_from_slice.rs
│       ├── parse_from_slice_panic.rs
│       └── parse_from_slice_total.rs
├── languages.json
├── src/
│   ├── cli.rs
│   ├── cli_utils.rs
│   ├── config.rs
│   ├── consts.rs
│   ├── input.rs
│   ├── language/
│   │   ├── embedding.rs
│   │   ├── language_type.rs
│   │   ├── language_type.tera.rs
│   │   ├── languages.rs
│   │   ├── mod.rs
│   │   └── syntax.rs
│   ├── lib.rs
│   ├── main.rs
│   ├── sort.rs
│   ├── stats.rs
│   └── utils/
│       ├── ext.rs
│       ├── fs.rs
│       ├── macros.rs
│       └── mod.rs
├── tests/
│   ├── accuracy.rs
│   ├── data/
│   │   ├── Daml.daml
│   │   ├── Dockerfile
│   │   ├── MSBuild.csproj
│   │   ├── Makefile
│   │   ├── Modelica.mo
│   │   ├── NuGet.Config
│   │   ├── PKGBUILD
│   │   ├── Rakefile
│   │   ├── SConstruct
│   │   ├── Snakefile
│   │   ├── Tera.tera
│   │   ├── abnf.abnf
│   │   ├── alloy.als
│   │   ├── apl.apl
│   │   ├── arduino.ino
│   │   ├── arturo.art
│   │   ├── asciidoc.adoc
│   │   ├── asn1.asn1
│   │   ├── ats.dats
│   │   ├── awk.awk
│   │   ├── ballerina.bal
│   │   ├── bazel.bzl
│   │   ├── bean.bean
│   │   ├── bicep.bicep
│   │   ├── bitbake.bb
│   │   ├── bqn.bqn
│   │   ├── brightscript.brs
│   │   ├── c.c
│   │   ├── c3.c3
│   │   ├── cairo.cairo
│   │   ├── cangjie.cj
│   │   ├── chapel.chpl
│   │   ├── cil.cil
│   │   ├── circom.circom
│   │   ├── clojure.clj
│   │   ├── clojurec.cljc
│   │   ├── clojurescript.cljs
│   │   ├── cmake.cmake
│   │   ├── codeql.ql
│   │   ├── cogent.cogent
│   │   ├── cpp.cpp
│   │   ├── cppm.cppm
│   │   ├── crystal.cr
│   │   ├── csharp.cs
│   │   ├── cuda.cu
│   │   ├── cue.cue
│   │   ├── cython.pyx
│   │   ├── d.d
│   │   ├── d2.d2
│   │   ├── dhall.dhall
│   │   ├── dreammaker.dm
│   │   ├── dust.dust
│   │   ├── ebuild.ebuild
│   │   ├── edgeql.edgeql
│   │   ├── edn.edn
│   │   ├── eight.8th
│   │   ├── elvish.elv
│   │   ├── emacs_dev_env.ede
│   │   ├── emacs_lisp.el
│   │   ├── emojicode.🍇
│   │   ├── esdl.esdl
│   │   ├── example.umpl
│   │   ├── factor.factor
│   │   ├── fennel.fnl
│   │   ├── flatbuffers.fbs
│   │   ├── forgecfg.cfg
│   │   ├── fsharp.fs
│   │   ├── fstar.fst
│   │   ├── ftl.ftl
│   │   ├── futhark.fut
│   │   ├── gas.S
│   │   ├── gdb.gdb
│   │   ├── gdshader.gdshader
│   │   ├── gherkin.feature
│   │   ├── gleam.gleam
│   │   ├── glimmer_js.gjs
│   │   ├── glimmer_ts.gts
│   │   ├── gml.gml
│   │   ├── go.go
│   │   ├── gohtml.gohtml
│   │   ├── graphql.gql
│   │   ├── gwion.gw
│   │   ├── haml.haml
│   │   ├── hcl.tf
│   │   ├── headache.ha
│   │   ├── hex0.hex0
│   │   ├── hex1.hex1
│   │   ├── hex2.hex2
│   │   ├── hicad.mac
│   │   ├── hledger.hledger
│   │   ├── hpp.hpp
│   │   ├── html.html
│   │   ├── janet.janet
│   │   ├── java.java
│   │   ├── javascript.js
│   │   ├── jinja2.j2
│   │   ├── jq.jq
│   │   ├── jslt.jslt
│   │   ├── jsonnet.jsonnet
│   │   ├── jupyter.ipynb
│   │   ├── justfile
│   │   ├── k.k
│   │   ├── kaem.kaem
│   │   ├── kakoune_script.kak
│   │   ├── koka.kk
│   │   ├── ksh.ksh
│   │   ├── kvlanguage.kv
│   │   ├── lalrpop.lalrpop
│   │   ├── linguafranca.lf
│   │   ├── liquid.liquid
│   │   ├── livescript.ls
│   │   ├── llvm.ll
│   │   ├── logtalk.lgt
│   │   ├── lolcode.lol
│   │   ├── m1.m1
│   │   ├── m4.m4
│   │   ├── menhir.mly
│   │   ├── meson.build
│   │   ├── metal.metal
│   │   ├── mlatu.mlt
│   │   ├── moduledef.def
│   │   ├── mojo.mojo
│   │   ├── monkeyc.mc
│   │   ├── nextflow.nf
│   │   ├── nqp.nqp
│   │   ├── odin.odin
│   │   ├── open_policy_agent.rego
│   │   ├── openscad.scad
│   │   ├── opentype.fea
│   │   ├── org_mode.org
│   │   ├── pan.pan
│   │   ├── pcss.pcss
│   │   ├── pest.pest
│   │   ├── phix.e
│   │   ├── plantuml.puml
│   │   ├── pofile.po
│   │   ├── pofile_pot.pot
│   │   ├── poke.pk
│   │   ├── pony.pony
│   │   ├── postcss.sss
│   │   ├── powershell.ps1
│   │   ├── pug.pug
│   │   ├── puppet.pp
│   │   ├── pyret.arr
│   │   ├── python.py
│   │   ├── q.q
│   │   ├── qml.qml
│   │   ├── racket.rkt
│   │   ├── raku.raku
│   │   ├── razor.cshtml
│   │   ├── razorcomponent.razor
│   │   ├── redscript.reds
│   │   ├── renpy.rpy
│   │   ├── roc.roc
│   │   ├── ron.ron
│   │   ├── rpmspec.spec
│   │   ├── ruby.rb
│   │   ├── ruby_env
│   │   ├── ruby_html.erb
│   │   ├── rust.rs
│   │   ├── scheme.scm
│   │   ├── shaderlab.shader
│   │   ├── slang.slang
│   │   ├── slint.slint
│   │   ├── solidity.sol
│   │   ├── sql.sql
│   │   ├── srecode.srt
│   │   ├── stan.stan
│   │   ├── stata.do
│   │   ├── stratego.str
│   │   ├── stylus.styl
│   │   ├── svelte.svelte
│   │   ├── swift.swift
│   │   ├── swig.i
│   │   ├── tact.tact
│   │   ├── templ.templ
│   │   ├── thrift.thrift
│   │   ├── tsx.tsx
│   │   ├── ttcn.ttcn3
│   │   ├── twig.twig
│   │   ├── typescript.ts
│   │   ├── typst.typ
│   │   ├── uiua.ua
│   │   ├── unison.u
│   │   ├── urweb.ur
│   │   ├── urweb_urp.urp
│   │   ├── urweb_urs.urs
│   │   ├── vb6_bas.bas
│   │   ├── vb6_cls.cls
│   │   ├── vb6_frm.frm
│   │   ├── vbscript.vbs
│   │   ├── velocity.vm
│   │   ├── vhdl.vhd
│   │   ├── visualbasic.vb
│   │   ├── vqe.qasm
│   │   ├── vue.vue
│   │   ├── webassembly.wat
│   │   ├── wenyan.wy
│   │   ├── wgsl.wgsl
│   │   ├── xsl.xsl
│   │   ├── xtend.xtend
│   │   ├── yaml.yaml
│   │   ├── zencode.zs
│   │   ├── zig.zig
│   │   └── zokrates.zok
│   └── embedding/
│       └── file_triggeringprincipal_frame_1.html
└── tokei.example.toml
Download .txt
SYMBOL INDEX (235 symbols across 29 files)

FILE: build.rs
  function main (line 13) | fn main() -> Result<(), Box<dyn error::Error>> {
  function generate_languages (line 21) | fn generate_languages(out_dir: &OsStr) -> Result<(), Box<dyn error::Erro...
  function compare_json_str_len (line 59) | fn compare_json_str_len(a: &Value, b: &Value) -> cmp::Ordering {
  function generate_tests (line 69) | fn generate_tests(out_dir: &OsStr) -> Result<(), Box<dyn error::Error>> {
  function generate_tests_batch (line 80) | fn generate_tests_batch(

FILE: fuzz/fuzz_targets/parse_from_slice.rs
  type FuzzInput (line 7) | pub struct FuzzInput<'a> {
  function parse_from_slice (line 15) | pub fn parse_from_slice(input: FuzzInput, check_total: bool) {

FILE: src/cli.rs
  type Streaming (line 18) | pub enum Streaming {
    type Err (line 26) | type Err = String;
    method from_str (line 28) | fn from_str(s: &str) -> Result<Self, Self::Err> {
  type Cli (line 38) | pub struct Cli {
    method from_args (line 58) | pub fn from_args() -> Self {
    method file_input (line 309) | pub fn file_input(&self) -> Option<&String> {
    method ignored_directories (line 313) | pub fn ignored_directories(&self) -> Vec<&str> {
    method input (line 321) | pub fn input(&self) -> Vec<&str> {
    method print_supported_languages (line 328) | pub fn print_supported_languages() -> Result<(), Box<dyn std::error::E...
    method override_config (line 399) | pub fn override_config(&mut self, mut config: Config) -> Config {
    method print_input_parse_failure (line 453) | pub fn print_input_parse_failure(input_filename: &str) {

FILE: src/cli_utils.rs
  constant NO_LANG_HEADER_ROW_LEN (line 21) | const NO_LANG_HEADER_ROW_LEN: usize = 69;
  constant NO_LANG_ROW_LEN (line 22) | const NO_LANG_ROW_LEN: usize = 63;
  constant NO_LANG_ROW_LEN_NO_SPACES (line 23) | const NO_LANG_ROW_LEN_NO_SPACES: usize = 56;
  constant IDENT_INACCURATE (line 24) | const IDENT_INACCURATE: &str = "(!)";
  function crate_version (line 26) | pub fn crate_version() -> String {
  function setup_logger (line 41) | pub fn setup_logger(verbose_option: u64) {
  function parse_or_exit (line 57) | pub fn parse_or_exit<T>(s: impl AsRef<str>) -> T
  type NumberFormatStyle (line 70) | pub enum NumberFormatStyle {
    method separator (line 105) | fn separator(self) -> &'static str {
    method get_format (line 114) | pub fn get_format(self) -> Result<num_format::CustomFormat, num_format...
  method default (line 82) | fn default() -> Self {
  type Err (line 88) | type Err = String;
  method from_str (line 90) | fn from_str(s: &str) -> Result<Self, Self::Err> {
  type Printer (line 122) | pub struct Printer<W> {
  function new (line 133) | pub fn new(
  function print_header (line 152) | pub fn print_header(&mut self) -> io::Result<()> {
  function print_inaccuracy_warning (line 170) | pub fn print_inaccuracy_warning(&mut self) -> io::Result<()> {
  function print_language (line 178) | pub fn print_language(&mut self, language: &Language, name: &str) -> io:...
  function print_language_in_print_total (line 198) | fn print_language_in_print_total(&mut self, language: &Language) -> io::...
  function print_language_name (line 233) | pub fn print_language_name(
  function print_code_stats (line 266) | fn print_code_stats(
  function print_language_total (line 297) | fn print_language_total(&mut self, parent: &Language) -> io::Result<()> {
  function print_results (line 317) | pub fn print_results<'a, I>(
  function print_row (line 399) | fn print_row(&mut self) -> io::Result<()> {
  function print_subrow (line 403) | fn print_subrow(&mut self) -> io::Result<()> {
  function print_report (line 407) | fn print_report(
  function print_report_total (line 426) | fn print_report_total(&mut self, report: &Report, inaccurate: bool) -> i...
  function print_report_with_name (line 446) | fn print_report_with_name(&mut self, report: &Report) -> io::Result<()> {
  function print_report_total_formatted (line 461) | fn print_report_total_formatted(
  function print_total (line 486) | pub fn print_total(&mut self, languages: &tokei::Languages) -> io::Resul...

FILE: src/config.rs
  type Config (line 23) | pub struct Config {
    method get_config (line 64) | fn get_config(base: PathBuf) -> Option<Self> {
    method from_config_files (line 94) | pub fn from_config_files() -> Self {

FILE: src/consts.rs
  constant FALLBACK_ROW_LEN (line 4) | pub const FALLBACK_ROW_LEN: usize = 81;
  constant LANGUAGE_COLUMN_WIDTH (line 9) | pub const LANGUAGE_COLUMN_WIDTH: usize = 10;
  constant PATH_COLUMN_WIDTH (line 12) | pub const PATH_COLUMN_WIDTH: usize = 80;
  constant FILES_COLUMN_WIDTH (line 15) | pub const FILES_COLUMN_WIDTH: usize = 8;
  constant LINES_COLUMN_WIDTH (line 18) | pub const LINES_COLUMN_WIDTH: usize = 12;
  constant CODE_COLUMN_WIDTH (line 21) | pub const CODE_COLUMN_WIDTH: usize = 12;
  constant COMMENTS_COLUMN_WIDTH (line 24) | pub const COMMENTS_COLUMN_WIDTH: usize = 12;
  constant BLANKS_COLUMN_WIDTH (line 27) | pub const BLANKS_COLUMN_WIDTH: usize = 12;

FILE: src/input.rs
  type LanguageMap (line 6) | type LanguageMap = BTreeMap<LanguageType, Language>;
  type Output (line 9) | struct Output {
  function add_input (line 167) | pub fn add_input(input: &str, languages: &mut Languages) -> bool {
  function convert_input (line 203) | fn convert_input(contents: &str) -> Option<LanguageMap> {
  function formatting_print_matches_parse (line 217) | fn formatting_print_matches_parse() {

FILE: src/language/embedding.rs
  type Capture (line 28) | pub struct Capture<'a> {
  function start (line 35) | fn start(&self) -> usize {
  function end (line 39) | pub fn end(&self) -> usize {
  function as_bytes (line 43) | pub fn as_bytes(&self) -> &[u8] {
  function fmt (line 49) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  type RegexCache (line 58) | pub(crate) struct RegexCache<'a> {
  type RegexFamily (line 65) | pub(crate) enum RegexFamily<'a> {
  type HtmlLike (line 72) | pub(crate) struct HtmlLike<'a> {
  type SimpleCapture (line 78) | pub(crate) struct SimpleCapture<'a> {
  function start_script_in_range (line 83) | pub fn start_script_in_range<'this>(
  function start_style_in_range (line 91) | pub fn start_style_in_range<'this>(
  function start_template_in_range (line 99) | pub fn start_template_in_range<'this>(
  function starts_in_range (line 109) | pub fn starts_in_range<'this>(
  function make_capture (line 117) | fn make_capture(
  function filter_range (line 135) | fn filter_range<'dataset, 'cap>(
  function family (line 157) | pub(crate) fn family(&self) -> Option<&RegexFamily> {
  function build (line 164) | pub(crate) fn build(lang: LanguageType, lines: &'a [u8], start: usize, e...
  function save_captures (line 202) | fn save_captures<'a>(

FILE: src/language/language_type.rs
  method serialize (line 28) | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
  method parse (line 39) | pub fn parse(self, path: PathBuf, config: &Config) -> Result<Report, (io...
  method parse_from_str (line 62) | pub fn parse_from_str<A: AsRef<str>>(self, text: A, config: &Config) -> ...
  method parse_from_slice (line 67) | pub fn parse_from_slice<A: AsRef<[u8]>>(self, text: A, config: &Config) ...
  method parse_lines (line 136) | fn parse_lines(
  method parse_jupyter (line 217) | fn parse_jupyter(&self, json: &[u8], config: &Config) -> Option<CodeStat...
  method find_lf_target_language (line 288) | fn find_lf_target_language(&self, bytes: &[u8]) -> Option<LanguageType> {
  function rust_allows_nested (line 316) | fn rust_allows_nested() {
  function assert_stats (line 320) | fn assert_stats(stats: &CodeStats, blanks: usize, code: usize, comments:...
  function jupyter_notebook_has_correct_totals (line 331) | fn jupyter_notebook_has_correct_totals() {
  function lf_embedded_language_is_counted (line 343) | fn lf_embedded_language_is_counted() {

FILE: src/language/language_type.tera.rs
  type LanguageType (line 11) | pub enum LanguageType {
  constant READ_LIMIT (line 389) | const READ_LIMIT: usize = 128;
  function fmt (line 454) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  function from (line 461) | fn from(from: LanguageType) -> Self {
  function from (line 467) | fn from(from: &'a LanguageType) -> Self {

FILE: src/language/languages.rs
  type Languages (line 21) | pub struct Languages {
    method serialize (line 26) | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    method deserialize (line 35) | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    method from_previous (line 46) | fn from_previous(map: BTreeMap<LanguageType, Language>) -> Self {
    method get_statistics (line 79) | pub fn get_statistics<A: AsRef<Path>>(
    method new (line 97) | pub fn new() -> Self {
    method total (line 103) | pub fn total(self: &Languages) -> Language {
    method add_assign (line 145) | fn add_assign(&mut self, rhs: BTreeMap<LanguageType, Language>) {
  type Item (line 118) | type Item = <BTreeMap<LanguageType, Language> as IntoIterator>::Item;
  type IntoIter (line 119) | type IntoIter = <BTreeMap<LanguageType, Language> as IntoIterator>::Into...
  method into_iter (line 121) | fn into_iter(self) -> Self::IntoIter {
  type Item (line 127) | type Item = (&'a LanguageType, &'a Language);
  type IntoIter (line 128) | type IntoIter = btree_map::Iter<'a, LanguageType, Language>;
  method into_iter (line 130) | fn into_iter(self) -> Self::IntoIter {
  type Item (line 136) | type Item = (&'a LanguageType, &'a mut Language);
  type IntoIter (line 137) | type IntoIter = btree_map::IterMut<'a, LanguageType, Language>;
  method into_iter (line 139) | fn into_iter(self) -> Self::IntoIter {
  type Target (line 155) | type Target = BTreeMap<LanguageType, Language>;
  method deref (line 157) | fn deref(&self) -> &Self::Target {
  method deref_mut (line 163) | fn deref_mut(&mut self) -> &mut BTreeMap<LanguageType, Language> {

FILE: src/language/mod.rs
  type Language (line 14) | pub struct Language {
    method new (line 37) | pub fn new() -> Self {
    method lines (line 44) | pub fn lines(&self) -> usize {
    method add_report (line 50) | pub fn add_report(&mut self, report: Report) {
    method mark_inaccurate (line 63) | pub fn mark_inaccurate(&mut self) {
    method summarise (line 72) | pub fn summarise(&self) -> Language {
    method total (line 103) | pub fn total(&mut self) {
    method is_empty (line 129) | pub fn is_empty(&self) -> bool {
    method sort_by (line 150) | pub fn sort_by(&mut self, category: Sort) {
  method add_assign (line 168) | fn add_assign(&mut self, mut rhs: Self) {

FILE: src/language/syntax.rs
  type SyntaxCounter (line 28) | pub(crate) struct SyntaxCounter {
    method new (line 134) | pub(crate) fn new(language: LanguageType) -> Self {
    method is_plain_mode (line 146) | pub(crate) fn is_plain_mode(&self) -> bool {
    method _is_string_mode (line 151) | pub(crate) fn _is_string_mode(&self) -> bool {
    method _is_comment_mode (line 156) | pub(crate) fn _is_comment_mode(&self) -> bool {
    method get_lf_target_language (line 160) | pub(crate) fn get_lf_target_language(&self) -> LanguageType {
    method parse_line_comment (line 167) | pub(crate) fn parse_line_comment(&self, window: &[u8]) -> bool {
    method try_perform_single_line_analysis (line 185) | pub(crate) fn try_perform_single_line_analysis(
    method perform_multi_line_analysis (line 219) | pub(crate) fn perform_multi_line_analysis(
    method line_is_comment (line 301) | pub(crate) fn line_is_comment(
    method parse_context (line 361) | pub(crate) fn parse_context(
    method parse_quote (line 556) | pub(crate) fn parse_quote(&mut self, window: &[u8]) -> Option<usize> {
    method parse_end_of_quote (line 604) | pub(crate) fn parse_end_of_quote(&mut self, window: &[u8]) -> Option<u...
    method parse_multi_line_comment (line 629) | pub(crate) fn parse_multi_line_comment(&mut self, window: &[u8]) -> Op...
    method parse_end_of_multi_line (line 662) | pub(crate) fn parse_end_of_multi_line(&mut self, window: &[u8]) -> Opt...
  type FileContext (line 38) | pub(crate) struct FileContext {
    method new (line 45) | pub fn new(language: LanguageContext, end: usize, stats: CodeStats) ->...
  type LanguageContext (line 55) | pub(crate) enum LanguageContext {
  type SharedMatchers (line 68) | pub(crate) struct SharedMatchers {
    method new (line 86) | pub fn new(language: LanguageType) -> Arc<Self> {
    method init (line 96) | pub fn init(language: LanguageType) -> Self {
  type AnalysisReport (line 126) | pub(crate) enum AnalysisReport {

FILE: src/main.rs
  function main (line 23) | fn main() -> Result<(), Box<dyn Error>> {

FILE: src/sort.rs
  type Sort (line 7) | pub enum Sort {
    method deserialize (line 41) | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
  type Err (line 21) | type Err = String;
  method from_str (line 23) | fn from_str(s: &str) -> Result<Self, Self::Err> {
  function from (line 52) | fn from(from: Sort) -> Self {
  function from (line 58) | fn from(from: &'a Sort) -> Self {

FILE: src/stats.rs
  type CodeStats (line 10) | pub struct CodeStats {
    method new (line 24) | pub fn new() -> Self {
    method lines (line 30) | pub fn lines(&self) -> usize {
    method summarise (line 37) | pub fn summarise(&self) -> Self {
    method add_assign (line 53) | fn add_assign(&mut self, rhs: Self) {
    method add_assign (line 59) | fn add_assign(&mut self, rhs: &'_ CodeStats) {
  type Report (line 73) | pub struct Report {
    method new (line 85) | pub fn new(name: PathBuf) -> Self {
    method add_assign (line 94) | fn add_assign(&mut self, rhs: CodeStats) {
    method fmt (line 126) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  function find_char_boundary (line 101) | pub fn find_char_boundary(s: &str, index: usize) -> usize {

FILE: src/utils/ext.rs
  type AsciiExt (line 3) | pub(crate) trait AsciiExt {
    method is_whitespace (line 4) | fn is_whitespace(&self) -> bool;
    method is_line_ending_whitespace (line 5) | fn is_line_ending_whitespace(&self) -> bool;
    method is_whitespace (line 9) | fn is_whitespace(&self) -> bool {
    method is_line_ending_whitespace (line 13) | fn is_line_ending_whitespace(&self) -> bool {
  type SliceExt (line 18) | pub(crate) trait SliceExt {
    method trim_first_and_last_line_of_whitespace (line 19) | fn trim_first_and_last_line_of_whitespace(&self) -> &Self;
    method trim_start (line 20) | fn trim_start(&self) -> &Self;
    method trim (line 21) | fn trim(&self) -> &Self;
    method contains_slice (line 22) | fn contains_slice(&self, needle: &Self) -> bool;
    method trim_first_and_last_line_of_whitespace (line 26) | fn trim_first_and_last_line_of_whitespace(&self) -> &Self {
    method trim_start (line 54) | fn trim_start(&self) -> &Self {
    method trim (line 69) | fn trim(&self) -> &Self {
    method contains_slice (line 89) | fn contains_slice(&self, needle: &Self) -> bool {
  function is_whitespace (line 116) | fn is_whitespace() {
  function trim (line 123) | fn trim() {
  function contains (line 136) | fn contains() {
  function trim_first_and_last_line_of_whitespace_edge_cases (line 145) | fn trim_first_and_last_line_of_whitespace_edge_cases() {

FILE: src/utils/fs.rs
  constant IGNORE_FILE (line 12) | const IGNORE_FILE: &str = ".tokeignore";
  function get_all_files (line 14) | pub fn get_all_files<A: AsRef<Path>>(
  function get_extension (line 119) | pub(crate) fn get_extension(path: &Path) -> Option<String> {
  function get_filename (line 123) | pub(crate) fn get_filename(path: &Path) -> Option<String> {
  constant FILE_CONTENTS (line 139) | const FILE_CONTENTS: &[u8] = b"fn main() {}";
  constant FILE_NAME (line 140) | const FILE_NAME: &str = "main.rs";
  constant IGNORE_PATTERN (line 141) | const IGNORE_PATTERN: &str = "*.rs";
  constant LANGUAGE (line 142) | const LANGUAGE: &LanguageType = &LanguageType::Rust;
  function ignore_directory_with_extension (line 145) | fn ignore_directory_with_extension() {
  function hidden (line 163) | fn hidden() {
  function no_ignore_implies_dot (line 192) | fn no_ignore_implies_dot() {
  function no_ignore_implies_vcs_gitignore (line 222) | fn no_ignore_implies_vcs_gitignore() {
  function no_ignore_parent (line 254) | fn no_ignore_parent() {
  function no_ignore_dot (line 288) | fn no_ignore_dot() {
  function no_ignore_dot_still_vcs_gitignore (line 318) | fn no_ignore_dot_still_vcs_gitignore() {
  function no_ignore_dot_includes_custom_ignore (line 341) | fn no_ignore_dot_includes_custom_ignore() {
  function no_ignore_vcs_gitignore (line 371) | fn no_ignore_vcs_gitignore() {
  function no_ignore_vcs_gitignore_still_dot (line 403) | fn no_ignore_vcs_gitignore_still_dot() {
  function no_ignore_vcs_gitexclude (line 424) | fn no_ignore_vcs_gitexclude() {
  function custom_ignore (line 456) | fn custom_ignore() {

FILE: tests/accuracy.rs
  function treating_comments_as_code (line 63) | fn treating_comments_as_code() {

FILE: tests/data/c.c
  function main (line 4) | int main(void) {
  function foo (line 11) | void foo() {
  function foobar (line 37) | void foobar() {
  type Point (line 46) | struct Point {

FILE: tests/data/cpp.cpp
  function bubble_sort (line 6) | void bubble_sort(int a[10], int n) {
  function main (line 26) | int main() {

FILE: tests/data/csharp.cs
  class Cls (line 9) | public class Cls
    method MyTest (line 13) | [Fact]

FILE: tests/data/go.go
  function main (line 11) | func main() {
  function Foo (line 26) | func Foo(

FILE: tests/data/hpp.hpp
  function print_value (line 15) | void print_value(T& t)

FILE: tests/data/java.java
  class Test (line 6) | public class Test
    method main (line 9) | public static void main(String[] args)
  class Foo (line 17) | class Foo
    method bar (line 19) | public void bar()
  class BackSlash (line 26) | public class BackSlash {
    method run (line 27) | public void run()

FILE: tests/data/javascript.js
  class Rectangle (line 15) | class Rectangle {
    method constructor (line 16) | constructor(width, height) {
    method area (line 21) | get area() {
    method calcArea (line 25) | calcArea() {

FILE: tests/data/python.py
  function add (line 4) | def add(x, y):

FILE: tests/data/rust.rs
  function main (line 11) | fn main() {
  function foo (line 22) | fn foo<'a, 'b>(name: &'b str) {
  function foobar (line 32) | fn foobar() {
  function foo (line 43) | fn foo() {

FILE: tests/data/typescript.ts
  class Person (line 10) | class Person {
    method constructor (line 15) | constructor(age: number, name: string, height: number) {
Condensed preview — 258 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (591K chars).
[
  {
    "path": ".git-blame-ignore-revs",
    "chars": 96,
    "preview": "# Format JSON\nd7c548537cd5828b2d58e09f3207ddacc517b227\nf356d27ab21e0f93839da90393c0edf9225740c2\n"
  },
  {
    "path": ".gitattributes",
    "chars": 36,
    "preview": "tests/data/* linguist-documentation\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 66,
    "preview": "# These are supported funding model platforms\n\ngithub: XAMPPRocky\n"
  },
  {
    "path": ".github/workflows/mean_bean_ci.yml",
    "chars": 5638,
    "preview": "name: Mean Bean CI\n\non:\n  push:\n    branches:\n      - master\n  pull_request:\n\njobs:\n  # This job downloads and stores `c"
  },
  {
    "path": ".github/workflows/mean_bean_deploy.yml",
    "chars": 6574,
    "preview": "on:\n  workflow_run:\n    workflows: [\"Release-plz\"]\n    branches: [master]\n    types: \n      - completed\n\nname: Mean Bean"
  },
  {
    "path": ".github/workflows/publish_image.yaml",
    "chars": 1172,
    "preview": "name: Publish Docker Images\n\non:\n  push:\n    branches:\n      - master\n    tags:\n      - v*\n\njobs:\n  image:\n    concurren"
  },
  {
    "path": ".github/workflows/release-plz.yaml",
    "chars": 596,
    "preview": "name: Release-plz\n\npermissions:\n  pull-requests: write\n  contents: write\n\non:\n  push:\n    branches:\n      - master\n\njobs"
  },
  {
    "path": ".gitignore",
    "chars": 593,
    "preview": "# Created by https://www.toptal.com/developers/gitignore/api/rust\n# Edit at https://www.toptal.com/developers/gitignore?"
  },
  {
    "path": ".mailmap",
    "chars": 280,
    "preview": "Erin Power <xampprocky@gmail.com> <theaaronepower@gmail.com>\nErin Power <xampprocky@gmail.com> <Aaronepower@users.norepl"
  },
  {
    "path": ".tokeignore",
    "chars": 21,
    "preview": "tests/data\nresources\n"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 40212,
    "preview": "# Changelog\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Changel"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 3221,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 5077,
    "preview": "# Contributing to Tokei\n\n- [Language Addition](#language-addition)\n- [Bug Reports](#bug-reports)\n\n# Language Addition\n\nC"
  },
  {
    "path": "Cargo.toml",
    "chars": 2119,
    "preview": "[package]\nauthors = [\"Erin Power <xampprocky@gmail.com>\"]\nbuild = \"build.rs\"\ncategories = [\"command-line-utilities\", \"de"
  },
  {
    "path": "Earthfile",
    "chars": 496,
    "preview": "VERSION 0.6\nFROM alpine:3.19\nWORKDIR /src\n\nbuild:\n    FROM rust:alpine3.19\n    RUN apk update \\\n        && apk add \\\n   "
  },
  {
    "path": "LICENCE-APACHE",
    "chars": 551,
    "preview": "Copyright 2016 Erin Power\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file exc"
  },
  {
    "path": "LICENCE-MIT",
    "chars": 1073,
    "preview": "MIT License (MIT)\n\nCopyright (c) 2016 Erin Power\n\nPermission is hereby granted, free of charge, to any person obtaining "
  },
  {
    "path": "README.md",
    "chars": 13643,
    "preview": "# Tokei ([時計](https://en.wiktionary.org/wiki/%E6%99%82%E8%A8%88))\n[![Mean Bean CI](https://github.com/XAMPPRocky/tokei/w"
  },
  {
    "path": "benchmark.sh",
    "chars": 997,
    "preview": "#!/usr/bin/env bash\nset -e\n\nif [ \"$1\" = \"--full\" ]; then\n    FILE=$2\n    FULL=true\n    else\n    FILE=$1\n    FULL=false\nf"
  },
  {
    "path": "build.rs",
    "chars": 5034,
    "preview": "extern crate ignore;\nextern crate json5;\nextern crate serde_json;\n\nuse std::ffi::OsStr;\nuse std::fs;\nuse std::path::Path"
  },
  {
    "path": "ci/build.bash",
    "chars": 564,
    "preview": "#!/usr/bin/env bash\n# Script for building your rust projects.\nset -e\n\nsource ci/common.bash\n\n# $1 {path} = Path to cross"
  },
  {
    "path": "ci/common.bash",
    "chars": 110,
    "preview": "required_arg() {\n    if [ -z \"$1\" ]; then\n        echo \"Required argument $2 missing\"\n        exit 1\n    fi\n}\n"
  },
  {
    "path": "ci/set_rust_version.bash",
    "chars": 70,
    "preview": "#!/usr/bin/env bash\nset -e\nrustup default \"$1\"\nrustup target add \"$2\"\n"
  },
  {
    "path": "ci/test.bash",
    "chars": 368,
    "preview": "#!/usr/bin/env bash\n# Script for building your rust projects.\nset -e\n\nsource ci/common.bash\n\n# $1 {path} = Path to cross"
  },
  {
    "path": "fuzz/.gitignore",
    "chars": 25,
    "preview": "\ntarget\ncorpus\nartifacts\n"
  },
  {
    "path": "fuzz/Cargo.toml",
    "chars": 584,
    "preview": "\n[package]\nname = \"tokei-fuzz\"\nversion = \"0.0.1\"\nauthors = [\"Michael Macnair\"]\npublish = false\nedition = \"2018\"\n\n[packag"
  },
  {
    "path": "fuzz/README.md",
    "chars": 1570,
    "preview": "## Fuzzing Tokei\n\nTokei can be fuzzed using libFuzzer, via [cargo-fuzz](https://github.com/rust-fuzz/cargo-fuzz/).\n\nFirs"
  },
  {
    "path": "fuzz/fuzz_targets/parse_from_slice.rs",
    "chars": 1757,
    "preview": "use arbitrary::Arbitrary;\nuse std::str;\n\nuse tokei::{Config, LanguageType};\n\n#[derive(Arbitrary, Debug)]\npub struct Fuzz"
  },
  {
    "path": "fuzz/fuzz_targets/parse_from_slice_panic.rs",
    "chars": 193,
    "preview": "#![no_main]\nuse libfuzzer_sys::fuzz_target;\n\nmod parse_from_slice;\nuse parse_from_slice::{parse_from_slice, FuzzInput};\n"
  },
  {
    "path": "fuzz/fuzz_targets/parse_from_slice_total.rs",
    "chars": 192,
    "preview": "#![no_main]\nuse libfuzzer_sys::fuzz_target;\n\nmod parse_from_slice;\nuse parse_from_slice::{parse_from_slice, FuzzInput};\n"
  },
  {
    "path": "languages.json",
    "chars": 57666,
    "preview": "{\n  \"languages\": {\n    \"Abap\": {\n      \"name\": \"ABAP\",\n      \"line_comment\": [\"*\", \"\\\\\\\"\"],\n      \"extensions\": [\"abap\"]"
  },
  {
    "path": "src/cli.rs",
    "chars": 16642,
    "preview": "use std::{process, str::FromStr};\n\nuse clap::{crate_description, value_parser, Arg, ArgAction, ArgMatches};\nuse colored:"
  },
  {
    "path": "src/cli_utils.rs",
    "chars": 16010,
    "preview": "use std::{\n    borrow::Cow,\n    fmt,\n    io::{self, Write},\n    process,\n    str::FromStr,\n};\n\nuse clap::crate_version;\n"
  },
  {
    "path": "src/config.rs",
    "chars": 7250,
    "preview": "use std::{env, fs, path::PathBuf};\n\nuse etcetera::BaseStrategy;\n\nuse crate::language::LanguageType;\nuse crate::sort::Sor"
  },
  {
    "path": "src/consts.rs",
    "chars": 610,
    "preview": "// Set of common pub consts.\n\n/// Fallback row length\npub const FALLBACK_ROW_LEN: usize = 81;\n\n// Column widths used for"
  },
  {
    "path": "src/input.rs",
    "chars": 7134,
    "preview": "use serde::{Deserialize, Serialize};\nuse std::{collections::BTreeMap, error::Error, str::FromStr};\n\nuse tokei::{Language"
  },
  {
    "path": "src/language/embedding.rs",
    "chars": 6847,
    "preview": "#![allow(clippy::trivial_regex)]\n\nuse crate::LanguageType;\nuse once_cell::sync::Lazy;\nuse regex::bytes::Regex;\n\npub stat"
  },
  {
    "path": "src/language/language_type.rs",
    "chars": 12648,
    "preview": "use std::{\n    borrow::Cow,\n    fmt,\n    fs::File,\n    io::{self, Read},\n    path::{Path, PathBuf},\n    str::FromStr,\n};"
  },
  {
    "path": "src/language/language_type.tera.rs",
    "chars": 16569,
    "preview": "use arbitrary::Arbitrary;\n\n/// Represents a individual programming language. Can be used to provide\n/// information abou"
  },
  {
    "path": "src/language/languages.rs",
    "chars": 4569,
    "preview": "use std::{\n    collections::{btree_map, BTreeMap},\n    iter::IntoIterator,\n    ops::{AddAssign, Deref, DerefMut},\n    pa"
  },
  {
    "path": "src/language/mod.rs",
    "chars": 5348,
    "preview": "mod embedding;\npub mod language_type;\npub mod languages;\nmod syntax;\n\nuse std::{collections::BTreeMap, mem, ops::AddAssi"
  },
  {
    "path": "src/language/syntax.rs",
    "chars": 24307,
    "preview": "use std::sync::Arc;\n\nuse aho_corasick::AhoCorasick;\nuse dashmap::DashMap;\nuse grep_searcher::LineStep;\nuse log::Level::T"
  },
  {
    "path": "src/lib.rs",
    "chars": 1693,
    "preview": "//! # Tokei: Count your code quickly.\n//!\n//! A simple, efficient library for counting code in directories. This\n//! fun"
  },
  {
    "path": "src/main.rs",
    "chars": 3960,
    "preview": "#[macro_use]\nextern crate log;\n\nmod cli;\nmod cli_utils;\nmod consts;\nmod input;\n\nuse std::{error::Error, io, process};\n\nu"
  },
  {
    "path": "src/sort.rs",
    "chars": 1519,
    "preview": "use std::{borrow::Cow, str::FromStr};\n\nuse serde::de::{self, Deserialize, Deserializer};\n\n/// Used for sorting languages"
  },
  {
    "path": "src/stats.rs",
    "chars": 4038,
    "preview": "use crate::consts::{\n    BLANKS_COLUMN_WIDTH, CODE_COLUMN_WIDTH, COMMENTS_COLUMN_WIDTH, LINES_COLUMN_WIDTH,\n};\nuse crate"
  },
  {
    "path": "src/utils/ext.rs",
    "chars": 4332,
    "preview": "//! Various extensions to Rust std types.\n\npub(crate) trait AsciiExt {\n    fn is_whitespace(&self) -> bool;\n    fn is_li"
  },
  {
    "path": "src/utils/fs.rs",
    "chars": 14082,
    "preview": "use std::{collections::BTreeMap, path::Path};\n\nuse ignore::{overrides::OverrideBuilder, DirEntry, WalkBuilder, WalkState"
  },
  {
    "path": "src/utils/macros.rs",
    "chars": 2138,
    "preview": "#![allow(unused_macros)]\n\nmacro_rules! opt_warn {\n    ($option:expr, $message:expr) => {\n        match $option {\n       "
  },
  {
    "path": "src/utils/mod.rs",
    "chars": 57,
    "preview": "#[macro_use]\nmod macros;\npub(crate) mod ext;\npub mod fs;\n"
  },
  {
    "path": "tests/accuracy.rs",
    "chars": 2486,
    "preview": "extern crate ignore;\nextern crate regex;\nextern crate tokei;\n\nuse std::fs;\n\nuse once_cell::sync::Lazy;\nuse regex::Regex;"
  },
  {
    "path": "tests/data/Daml.daml",
    "chars": 1122,
    "preview": "-- ! 42 lines 24 code 9 comments 9 blanks\n\n{-\nThis code is derived from https://github.com/digital-asset/ex-secure-daml-"
  },
  {
    "path": "tests/data/Dockerfile",
    "chars": 331,
    "preview": "# 17 lines 7 code 3 comments 7 blanks\n\nFROM netbsd:7.0.2\n\nMAINTAINER Somebody version: 2.2\n\nRUN curl -sSf https://static"
  },
  {
    "path": "tests/data/MSBuild.csproj",
    "chars": 356,
    "preview": "<!-- 12 lines 10 code 1 comments 1 blanks -->\n<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup>\n    <OutputType>Exe</O"
  },
  {
    "path": "tests/data/Makefile",
    "chars": 374,
    "preview": "# 24 lines 11 code 5 comments 8 blanks\n\n##\t\t\t\t     ##\n## IMPORTANT COMMENT ##\n##\t\t\t\t\t ##\n\nall: hello\n\nhello: main.o fact"
  },
  {
    "path": "tests/data/Modelica.mo",
    "chars": 386,
    "preview": "// 21 lines 13 code 5 comments 3 blanks\nblock Add \"Output the sum of the two inputs\"\n  extends Interfaces.SI2SO;\n\n/* \npa"
  },
  {
    "path": "tests/data/NuGet.Config",
    "chars": 1181,
    "preview": "<!-- 24 lines 13 code 8 comments 3 blanks -->\n\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<configuration>\n    <!-- defaultPu"
  },
  {
    "path": "tests/data/PKGBUILD",
    "chars": 802,
    "preview": "# 24 lines 19 code 3 comments 2 blanks\n# Maintainer: \t  Andy 'Blocktronics' Herbert <blocktronics.org>\n# Aur Maintainer:"
  },
  {
    "path": "tests/data/Rakefile",
    "chars": 144,
    "preview": "# 10 lines 4 code 2 comments 4 blanks\n\n# this is a rakefile\n\ntask default: %w[test]\n\ntask :test do # not counted\n  ruby "
  },
  {
    "path": "tests/data/SConstruct",
    "chars": 181,
    "preview": "#!python\n# 10 lines 3 code 3 comments 4 blanks\n\n# this is a comment\n\nProgram('cpp.cpp') # this is a line-ending comment\n"
  },
  {
    "path": "tests/data/Snakefile",
    "chars": 1369,
    "preview": "# 67 lines 50 code 4 comments 13 blanks\n\"\"\"\nA sample Snakefile for testing line counting\n\"\"\"\n\nSAMPLES = [\"A\", \"B\"]\n\n\n# T"
  },
  {
    "path": "tests/data/Tera.tera",
    "chars": 946,
    "preview": "{# 42 lines 26 code 11 comments 5 blanks #}\n<!DOCTYPE html>\n<html>\n    <head>\n        <meta charset=\"utf-8\" />\n        <"
  },
  {
    "path": "tests/data/abnf.abnf",
    "chars": 268,
    "preview": "; 11 lines 3 code 5 comments 3 blanks\n; comment line 0\n; comment line 1\n\nALPHA          =  %x41-5A / %x61-7A   ; A-Z / a"
  },
  {
    "path": "tests/data/alloy.als",
    "chars": 302,
    "preview": "// 18 lines 10 code 3 comments 5 blanks\n\nsig Node {\n    edge: set Node\n}\n\n----------------------------------------------"
  },
  {
    "path": "tests/data/apl.apl",
    "chars": 153,
    "preview": "⍝ 10 lines 3 code 3 comments 4 blanks\n\n\n256=2*8\n\n⍝ Comment\n⊃¨ ' '(≠⊆⊢) 'A Programming Language'\n\n⍝ A magic square of len"
  },
  {
    "path": "tests/data/arduino.ino",
    "chars": 364,
    "preview": "// 23 lines 13 code 6 comments 4 blanks\n\nint led = 13;\n\nvoid setup() {\n    // setup println()\n    Serial.begin(155200);\n"
  },
  {
    "path": "tests/data/arturo.art",
    "chars": 138,
    "preview": "; 8 lines 3 code 3 comments 2 blanks\n; this is a comment\n; this is another comment\n\na1: 2\na2: 3.14 ; pi\n\na3: 213213     "
  },
  {
    "path": "tests/data/asciidoc.adoc",
    "chars": 234,
    "preview": "// 20 lines 5 code 8 comments 7 blanks\n\n= AsciiDoc title\n\nA simple paragraph.\n\n// single line comment\n\nThat should end b"
  },
  {
    "path": "tests/data/asn1.asn1",
    "chars": 787,
    "preview": "-- 34 lines 16 code 11 comments 7 blanks\nPKCS-12 {\n    iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-12(12)\n"
  },
  {
    "path": "tests/data/ats.dats",
    "chars": 942,
    "preview": "//! 42 lines 25 code 9 comments 8 blanks\n\n(*************\n    Reference:\n    https://github.com/ats-lang/ats-lang.github."
  },
  {
    "path": "tests/data/awk.awk",
    "chars": 85,
    "preview": "#!/bin/awk -f\n# 5 lines 1 code 3 comments 1 blanks\n\n# This is a comment\n{ print $0 }\n"
  },
  {
    "path": "tests/data/ballerina.bal",
    "chars": 1180,
    "preview": "// 40 lines 29 code 6 comments 5 blanks\n\n# Returns Bob's response to someone talking to him.\n#\n# + input - whatever is s"
  },
  {
    "path": "tests/data/bazel.bzl",
    "chars": 323,
    "preview": "# 18 lines 13 code 3 comments 2 blanks\n\n# build hello-greet\ncc_library(\n    name = \"hello-greet\",\n    srcs = [\"hello-gre"
  },
  {
    "path": "tests/data/bean.bean",
    "chars": 626,
    "preview": "; 27 lines 13 code 6 comments 8 blanks\n\noption \"operating_currency\" \"EUR\"\n\n2002-01-01 commodity EUR\n    name: \"Euro\"\n   "
  },
  {
    "path": "tests/data/bicep.bicep",
    "chars": 1339,
    "preview": "//! 50 lines 35 code 8 comments 7 blanks\n/*\nBicep is a declarative language, which means the elements can appear in any "
  },
  {
    "path": "tests/data/bitbake.bb",
    "chars": 524,
    "preview": "# 23 lines 13 code 5 comments 5 blanks\n#\n# This file was derived from the 'Hello World!' example recipe in the\n# Yocto P"
  },
  {
    "path": "tests/data/bqn.bqn",
    "chars": 152,
    "preview": "# 10 lines 3 code 3 comments 4 blanks\n\n\n256=2⋆8\n\n# Comment\n<⟜'a'⊸/\"Big Questions Notation\"\n\n# A magic square of length ⊢"
  },
  {
    "path": "tests/data/brightscript.brs",
    "chars": 575,
    "preview": "' 26 lines 10 code 13 comments 3 blanks\n' /**\n'  * @member difference\n'  * @memberof module:rodash\n'  * @instance\n'  * @"
  },
  {
    "path": "tests/data/c.c",
    "chars": 873,
    "preview": "// 50 lines 33 code 8 comments 9 blanks\r\n\r\n/* /* we can't nest block comments in c, but we can start one */\r\nint main(vo"
  },
  {
    "path": "tests/data/c3.c3",
    "chars": 189,
    "preview": "/* 8 lines 6 code 1 comments 1 blanks */\n\nfn int main() {\n    int x = 5; /* Multline line comment */\n    io::printn(\"Hel"
  },
  {
    "path": "tests/data/cairo.cairo",
    "chars": 895,
    "preview": "//! 51 lines 32 code 13 comments 6 blanks\n//! ```rust\n//! fn main () {\n//!     // Comment\n//!\n//!     println!(\"Hello Wo"
  },
  {
    "path": "tests/data/cangjie.cj",
    "chars": 965,
    "preview": "/* 50 lines 34 code 8 comments 8 blanks */\n\n/* /* we can nest block*/ comments in cangjie */\nmain(): Unit {\n    let star"
  },
  {
    "path": "tests/data/chapel.chpl",
    "chars": 411,
    "preview": "// chapel 24 lines 9 code 9 comments 6 blanks\n\n// Tidy line comment\n\n/* Tidy block\n   comment.\n*/\n\n// Cheeky line commen"
  },
  {
    "path": "tests/data/cil.cil",
    "chars": 890,
    "preview": "; 20 lines 15 code 3 comments 2 blanks\n;============= etcd_t ==============\n(allow etcd_t proc_sysctl_t (dir (search)))\n"
  },
  {
    "path": "tests/data/circom.circom",
    "chars": 673,
    "preview": "// 34 lines 23 code 7 comments 4 blanks\npragma circom 2.0.8;\n\n/*\n * Sum an array of non-zero values.\n */\nfunction sum(va"
  },
  {
    "path": "tests/data/clojure.clj",
    "chars": 287,
    "preview": "; 19 lines 13 code 3 comments 3 blanks\n\n(ns clojure)\n\n; Below is a function\n(defn a-fn\n  \"Docstring with a column ;\"\n  ["
  },
  {
    "path": "tests/data/clojurec.cljc",
    "chars": 287,
    "preview": "; 19 lines 13 code 3 comments 3 blanks\n\n(ns clojure)\n\n; Below is a function\n(defn a-fn\n  \"Docstring with a column ;\"\n  ["
  },
  {
    "path": "tests/data/clojurescript.cljs",
    "chars": 287,
    "preview": "; 19 lines 13 code 3 comments 3 blanks\n\n(ns clojure)\n\n; Below is a function\n(defn a-fn\n  \"Docstring with a column ;\"\n  ["
  },
  {
    "path": "tests/data/cmake.cmake",
    "chars": 933,
    "preview": "# 25 lines 16 code 3 comments 6 blanks\n\nSET(_POSSIBLE_XYZ_INCLUDE include include/xyz)\nSET(_POSSIBLE_XYZ_EXECUTABLE xyz)"
  },
  {
    "path": "tests/data/codeql.ql",
    "chars": 754,
    "preview": "//! 40 lines 17 code 15 comments 8 blanks\n\n/** \n * @name fu \n * @description bar \n *\n * Rerum similique consequatur non "
  },
  {
    "path": "tests/data/cogent.cogent",
    "chars": 87,
    "preview": "-- 7 lines 2 code 2 comments 3 blanks\n\ntype A -- uncounted comment\n\n-- comment\n\ntype B\n"
  },
  {
    "path": "tests/data/cpp.cpp",
    "chars": 711,
    "preview": "/* 46 lines 37 code 3 comments 6 blanks */\n\n#include <stdio.h>\n\n// bubble_sort_function\nvoid bubble_sort(int a[10], int "
  },
  {
    "path": "tests/data/cppm.cppm",
    "chars": 711,
    "preview": "/* 46 lines 37 code 3 comments 6 blanks */\n\n#include <stdio.h>\n\n// bubble_sort_function\nvoid bubble_sort(int a[10], int "
  },
  {
    "path": "tests/data/crystal.cr",
    "chars": 217,
    "preview": "# 20 lines 14 code 2 comments 4 blanks\nx = 3\nif x < 2\n  p = \"Smaller\"\nelse\n  p = \"Bigger\"\nend\n\nmultiline_string = \"first"
  },
  {
    "path": "tests/data/csharp.cs",
    "chars": 368,
    "preview": "// 26 lines 14 code 9 comments 3 blanks\nnamespace Ns\n{\n    /*\n\n    multi-line comment\n\n    */\n    public class Cls\n    {"
  },
  {
    "path": "tests/data/cuda.cu",
    "chars": 163,
    "preview": "/* 7 lines 4 code 2 comments 1 blanks */\n\n// add vector\n__host__ void add(const int* a, const int* b, int* c) {\n    int "
  },
  {
    "path": "tests/data/cue.cue",
    "chars": 236,
    "preview": "// 12 lines 8 code 2 comments 2 blanks\n\n// A documentation comment\nmap: {\n\tnormal: \"normal string\" // inline comment (no"
  },
  {
    "path": "tests/data/cython.pyx",
    "chars": 451,
    "preview": "# 29 lines, 21 code, 3 comments, 5 blanks\n\n\ndef add(x, y):\n    '''\n    Hello World\n    # Real Second line\n    Second lin"
  },
  {
    "path": "tests/data/d.d",
    "chars": 152,
    "preview": "/* 8 lines 5 code 1 comments 2 blanks */\n\nvoid main() {\n    auto x = 5; /+ a /+ nested +/ comment /* +/\n    writefln(\"he"
  },
  {
    "path": "tests/data/d2.d2",
    "chars": 210,
    "preview": "# 15 lines 4 code 6 comments 5 blanks\n\n# Comments start with a hash character and continue until the next newline or EOF"
  },
  {
    "path": "tests/data/dhall.dhall",
    "chars": 230,
    "preview": "-- 16 lines 9 code 5 comments 2 blanks\n{- A comment within the interior of a multi-line literal counts as part of the\n  "
  },
  {
    "path": "tests/data/dreammaker.dm",
    "chars": 329,
    "preview": "// 17 lines 7 code 6 comments 4 blanks\n/*\n * /* Hello! */\n */\n\n/mob\n    // I can rely on this file to exist on disk.\n   "
  },
  {
    "path": "tests/data/dust.dust",
    "chars": 346,
    "preview": "{! 10 lines 2 code 5 comments 3 blanks !}\n\n{! All Dust comments are multiline comments.  And there's no quoting\n   comme"
  },
  {
    "path": "tests/data/ebuild.ebuild",
    "chars": 215,
    "preview": "# 16 lines 9 code 2 comments 5 blanks\n\n# test comment\n\nEAPI=8\n\nDESCRIPTION=\"ebuild file\"\nHOMEPAGE=\"https://foo.example.o"
  },
  {
    "path": "tests/data/edgeql.edgeql",
    "chars": 520,
    "preview": "# 28 lines 21 code 3 comments 4 blanks\n\nselect User {\n    name,\n    friends: {\n        name\n    },\n    has_i := .friends"
  },
  {
    "path": "tests/data/edn.edn",
    "chars": 157,
    "preview": "; 11 lines 6 code 2 comments 3 blanks\n\n; Just some random data\n\n {:a [\n      1]\n\n  :b 1 ; this doesn't count as a commen"
  },
  {
    "path": "tests/data/eight.8th",
    "chars": 331,
    "preview": "\\ 22 lines 9 code 8 comments 5 blanks\n\n(* multiline comments\n  (* a nested \n     comment *)\n *\n *)\n\n-- here's a single l"
  },
  {
    "path": "tests/data/elvish.elv",
    "chars": 240,
    "preview": "# 16 lines, 9 code, 5 blanks, 2 comments\necho \"This is a\nmultiline string\n# with a hash\nin it.\"\n\necho 'This is a single-"
  },
  {
    "path": "tests/data/emacs_dev_env.ede",
    "chars": 285,
    "preview": ";; 16 lines 6 code 7 comments 3 blanks\n\n;; This is an EDE Project file\n\n;; Object ede-proj-project\n;; EDE project file.\n"
  },
  {
    "path": "tests/data/emacs_lisp.el",
    "chars": 508,
    "preview": ";; 21 lines 11 code 6 comments 4 blanks\n\n                                        ; This is a comment line\n;; This too!\n;"
  },
  {
    "path": "tests/data/emojicode.🍇",
    "chars": 270,
    "preview": "💭 24 lines 10 code 10 comments 4 blanks\n\n📘\n  This package is neat.\n📘\n\n💭🔜 Comment! 💭🔜 nested? 🔚💭\n\n📗\n  Simple docstring\n  "
  },
  {
    "path": "tests/data/esdl.esdl",
    "chars": 495,
    "preview": "# 20 lines 13 code 4 comments 3 blanks\n\n# no module block\ntype default::Movie {\n    required property title -> str;\n    "
  },
  {
    "path": "tests/data/example.umpl",
    "chars": 3254,
    "preview": "! 68 lines 58 code 2 comments 8 blanks\r\n\r\ncreate yum with 5\r\ncreate num with ((plus 7 6 6 yum))>\r\n(num)>\r\n((plus 1 num))"
  },
  {
    "path": "tests/data/factor.factor",
    "chars": 288,
    "preview": "! 14 lines, 5 code, 6 comments, 3 blanks\n\n/* we can use some dependencies */\nUSING: math multiline sequences ;\n\n! this i"
  },
  {
    "path": "tests/data/fennel.fnl",
    "chars": 474,
    "preview": ";; 18 lines 8 code 5 comments 5 blanks\n\n; this is a ; single comment\n;;;; this is also a single comment ;;;;;;\n\n        "
  },
  {
    "path": "tests/data/flatbuffers.fbs",
    "chars": 588,
    "preview": "// 34 lines 21 code 6 comments 7 blanks\n\ninclude \"another_schema.fbs\";\n\nnamespace Example;\n\n// one line comment\nenum Pho"
  },
  {
    "path": "tests/data/forgecfg.cfg",
    "chars": 2990,
    "preview": "# 79 lines 20 code 40 comments 19 blanks\n\n# Configuration file\n\n~CONFIG_VERSION: 0.4.0\n\n################################"
  },
  {
    "path": "tests/data/fsharp.fs",
    "chars": 142,
    "preview": "(* 15 lines 6 code 5 comments 4 blanks *)\n\n// Comment\n\nlet foo = (*\n    Comment\n*)\n5\n\nlet bar = \"(*\n    Code\n*)\"\n\nlet ba"
  },
  {
    "path": "tests/data/fstar.fst",
    "chars": 210,
    "preview": "(* 11 lines 3 code 5 comments 3 blanks *)\n\nmodule Hello\n\n(* multi\n   line\n   comment *)\nopen FStar.IO // uncounted comme"
  },
  {
    "path": "tests/data/ftl.ftl",
    "chars": 204,
    "preview": "<#-- 10 lines 5 code 3 comments 2 blanks -->\n<#ftl output_format=\"plainText\"/>\n\n<#-- Define the print macro -->\n<#macro "
  },
  {
    "path": "tests/data/futhark.fut",
    "chars": 125,
    "preview": "-- 8 lines 2 code 3 comments 3 blanks\n\n-- this is a test file\n\n-- add two\nlet f (x: i32) = x + 2\n\nlet main = f -- eta ex"
  },
  {
    "path": "tests/data/gas.S",
    "chars": 1232,
    "preview": "// 67 lines 46 code 10 comments 11 blanks\n#include \"config.h\"\n\n/* BIG FAT WARNING GOES HERE */\n#define dbg(char) \\\n\tmov "
  },
  {
    "path": "tests/data/gdb.gdb",
    "chars": 284,
    "preview": "# 15 lines 7 code 5 comments 3 blanks\n#\n# This is a comment line. We don't have multi-comment lines\n#\n\nmacro define offs"
  },
  {
    "path": "tests/data/gdshader.gdshader",
    "chars": 269,
    "preview": "// 24 lines 6 code 13 comments 5 blanks\n/* \ntest\ntest\ntest\n*/ \n\n/* /** */\n\nvoid fragment() {\n    // there is not any str"
  },
  {
    "path": "tests/data/gherkin.feature",
    "chars": 446,
    "preview": "# 13 lines 8 code 3 comments 2 blanks\nFeature: Guess the word\n\n  # The first example has two steps\n  Scenario: Maker sta"
  },
  {
    "path": "tests/data/gleam.gleam",
    "chars": 578,
    "preview": "//// 34 lines 24 code 4 comments 6 blanks\n\nimport gleam/option.{Option, None}\nimport gleam/io\n\npub type LoadedBool {\n  Y"
  },
  {
    "path": "tests/data/glimmer_js.gjs",
    "chars": 627,
    "preview": "// 27 lines, 18 code, 6 comments, 3 blanks\nimport { helper } from '@ember/component/helper';\nimport { modifier } from 'e"
  },
  {
    "path": "tests/data/glimmer_ts.gts",
    "chars": 418,
    "preview": "// 18 lines, 10 code, 6 comments, 2 blanks\nimport type { TemplateOnlyComponent } from '@glimmer/component';\n\n// A single"
  },
  {
    "path": "tests/data/gml.gml",
    "chars": 215,
    "preview": "/* 17 lines 5 code 9 comments 3 blanks */\n\n/* here's a comment */\n\n/* \n    this is also\n    ...a comment!\n*/ \n\nvar a = 0"
  },
  {
    "path": "tests/data/go.go",
    "chars": 485,
    "preview": "// 37 lines 24 code 6 comments 7 blanks\n\n// Package main is a test file.\npackage main\n\nimport (\n\t\"errors\"\n)\n\n/* /**/\nfun"
  },
  {
    "path": "tests/data/gohtml.gohtml",
    "chars": 790,
    "preview": "<!-- 41 lines 20 code 14 comments 7 blanks -->\n<!DOCTYPE html>\n<html>\n  <head>\n    <meta charset=\"utf-8\" />\n    <meta na"
  },
  {
    "path": "tests/data/graphql.gql",
    "chars": 1427,
    "preview": "# 89 lines 71 code 3 comments 15 blanks\n\n\"\"\"\nA simple GraphQL schema which is well described. This is not a comment.\nSee"
  },
  {
    "path": "tests/data/gwion.gw",
    "chars": 161,
    "preview": "#! 10 lines 8 code 1 comments 1 blanks\nclass C {\n  var int i;\n  var float f;\n  var Object o;\n  operator void @dtor () { "
  },
  {
    "path": "tests/data/haml.haml",
    "chars": 305,
    "preview": "-# 18 lines 11 code 2 comments 5 blanks\n\n%section.container\n\n  - @posts.each do |post|\n    -# Ruby comment\n    %h1= post"
  },
  {
    "path": "tests/data/hcl.tf",
    "chars": 263,
    "preview": "# 22 lines 11 code 7 comments 4 blanks\nvariable \"foo\" \"bar\" {\n  default = \"yes\"\n}\n\n/* We like\n   multiple lines\n*/\n\nloca"
  },
  {
    "path": "tests/data/headache.ha",
    "chars": 338,
    "preview": "// 13 lines 9 code 3 comments 1 blanks\n/* //The Headache cat program */\n// Implementation of Unix Cat in Headache\n\nvoid "
  },
  {
    "path": "tests/data/hex0.hex0",
    "chars": 6429,
    "preview": "# 154 lines 89 code 34 comments 31 blanks\n# SPDX-FileCopyrightText: 2017 Jeremiah Orians <jeremiah@pdp10.guru>\n# SPDX-Fi"
  },
  {
    "path": "tests/data/hex1.hex1",
    "chars": 24812,
    "preview": "# 589 lines 387 code 91 comments 111 blanks\n# SPDX-FileCopyrightText: 2016 Jeremiah Orians <jeremiah@pdp10.guru>\n# SPDX-"
  },
  {
    "path": "tests/data/hex2.hex2",
    "chars": 5510,
    "preview": "# 110 lines 78 code 7 comments 25 blanks\n# SPDX-FileCopyrightText: 2019 Jeremiah Orians <jeremiah@pdp10.guru>\n#\n# SPDX-L"
  },
  {
    "path": "tests/data/hicad.mac",
    "chars": 136,
    "preview": "REM 10 lines 4 code 3 comments 3 blanks\nSTART  59\n\nREM Comment on a line\n%XY:=42\n\nrem This is also a comment\nIF FOO= \"fo"
  },
  {
    "path": "tests/data/hledger.hledger",
    "chars": 751,
    "preview": "# 18 lines 6 code 10 comments 2 blanks\n# a comment\n; another comment\n\n; ^ a blank line\ncomment\naccount assets           "
  },
  {
    "path": "tests/data/hpp.hpp",
    "chars": 249,
    "preview": "/* 21 lines 11 code 5 comments 5 blanks */\n#ifndef TEST_H\n#define TEST_H\n\n#include <iostream>\n\n//Some definitions\nextern"
  },
  {
    "path": "tests/data/html.html",
    "chars": 864,
    "preview": "<!-- 46 lines 23 code 19 comments 4 blanks -->\n<!DOCTYPE html>\n<html>\n    <head>\n        <meta charset=\"utf-8\" />\n      "
  },
  {
    "path": "tests/data/janet.janet",
    "chars": 264,
    "preview": "# 17 lines 12 code 3 comments 2 blanks\n\n# Below is a function\n(defn a-fn\n  \"Docstring with a hash #\"\n  [a b]\n  (+ 1 1))\n"
  },
  {
    "path": "tests/data/java.java",
    "chars": 478,
    "preview": "/* 37 lines 23 code 5 comments 9 blanks */\n\n/*\n * Simple test class\n */\npublic class Test\n{\n    int j = 0; // Not counte"
  },
  {
    "path": "tests/data/javascript.js",
    "chars": 437,
    "preview": "// 33 lines, 14 code, 12 comments, 7 blanks\n\n/*\n * /* Nested comment\n * // single line comment\n * */\n\n/*\n\nfunction add(a"
  },
  {
    "path": "tests/data/jinja2.j2",
    "chars": 76,
    "preview": "{# 5 lines 1 code 2 comments 2 blanks #}\n\n{# test comment #}\n\n{{ testvar }}\n"
  },
  {
    "path": "tests/data/jq.jq",
    "chars": 275,
    "preview": "# 11 lines 3 code 5 comments 3 blanks\n\n# A function to perform arithmetic\ndef add_mul(adder; multiplier):\n  # comment ch"
  },
  {
    "path": "tests/data/jslt.jslt",
    "chars": 2903,
    "preview": "// 126 lines 80 code 20 comments 26 blanks\n\n// https://github.com/schibsted/jslt/blob/master/examples/queens.jslt\n// ==="
  },
  {
    "path": "tests/data/jsonnet.jsonnet",
    "chars": 274,
    "preview": "// 13 lines 7 code 4 comments 2 blanks\n\n/* /**/ */\nlocal func(a, b) = {\n  // very useful\n  a: a,\n  b: b,\n  \n  # you forg"
  },
  {
    "path": "tests/data/jupyter.ipynb",
    "chars": 65054,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Cheat Sheet: Writing Python 2-3 c"
  },
  {
    "path": "tests/data/justfile",
    "chars": 4505,
    "preview": "# 215 lines 154 code 11 comments 50 blanks\nset shell := [\"sh\", \"-c\"]\nset windows-shell := [\"powershell.exe\", \"-NoLogo\", "
  },
  {
    "path": "tests/data/k.k",
    "chars": 290,
    "preview": "// 8 lines 2 code 4 comments 2 blanks\n/suduko solver\n\n/ initial state\nx:.:'\"20037000900920000700100400205000080000800090"
  },
  {
    "path": "tests/data/kaem.kaem",
    "chars": 1728,
    "preview": "# 43 lines 2 code 33 comments 8 blanks \n#! /usr/bin/env bash\n# Mes --- Maxwell Equations of Software\n# Copyright © 2017 "
  },
  {
    "path": "tests/data/kakoune_script.kak",
    "chars": 226,
    "preview": "# 13 lines, 8 code, 2 comments, 3 blanks\nhook global BufCreate (.*/)?(kakrc|.*.kak) %{\n  set-option buffer filetype kak\n"
  },
  {
    "path": "tests/data/koka.kk",
    "chars": 849,
    "preview": "// 29 lines 11 code 12 comments 6 blanks\n\n/*---------------------------------------------------------------------------\n"
  },
  {
    "path": "tests/data/ksh.ksh",
    "chars": 296,
    "preview": "#!/bin/ksh\n# 17 lines, 11 code, 4 comments, 2 blanks\n\n# first comment\nfiles=\"/etc/passwd /etc/group /etc/hosts\"\nfor f in"
  },
  {
    "path": "tests/data/kvlanguage.kv",
    "chars": 527,
    "preview": "# 22 lines 17 code 3 comments 2 blanks\n\n\n#:kivy 2.0.0\n#:import C kivy.utils.get_color_from_hex\n#:import KeypadButton key"
  },
  {
    "path": "tests/data/lalrpop.lalrpop",
    "chars": 860,
    "preview": "// 37 lines 26 code 3 comments 8 blanks\nuse crate::ast::{ExprSymbol, Opcode};\nuse crate::tok9::Tok;\n\ngrammar<'input>(inp"
  },
  {
    "path": "tests/data/linguafranca.lf",
    "chars": 788,
    "preview": "// 36 lines 16 code 9 comments 11 blanks\n\ntarget Rust;\n\n// A C style comment\nimport KeyboardEvents from \"KeyboardEvents."
  },
  {
    "path": "tests/data/liquid.liquid",
    "chars": 837,
    "preview": "{% comment %} 24 lines 19 code 1 comments 4 blanks {% endcomment %}\n\n{% paginate collection.products by 20 %}\n\n<ul id=\"p"
  },
  {
    "path": "tests/data/livescript.ls",
    "chars": 372,
    "preview": "# 28 lines, 10 code, 12 comments, 6 blanks\n\n/*\n * /* Nested comment\n * #  single line comment\n * */\n\n/*\n\nadd = (a, b) ->"
  },
  {
    "path": "tests/data/llvm.ll",
    "chars": 380,
    "preview": "; 21 lines 17 code 1 comments 3 blanks\ndefine i32 @add1(i32 %a, i32 %b) {\nentry:\n  %tmp1 = add i32 %a, %b\n  ret i32 %tmp"
  },
  {
    "path": "tests/data/logtalk.lgt",
    "chars": 1397,
    "preview": "/*\n\tTest file for the Logtalk programming language\n\t(copied by the author from a Logtalk distribution example)\n\n\t65 line"
  },
  {
    "path": "tests/data/lolcode.lol",
    "chars": 399,
    "preview": "BTW 26 lines 11 code 9 comments 6 blanks\nHAI 1.3\n\nBTW TEST!\nI HAS A MSG ITZ \"BYE! OBTW\"\nHOW IZ I PRINT_HELLO\n    I HAS A"
  },
  {
    "path": "tests/data/m1.m1",
    "chars": 7816,
    "preview": "# 280 lines 197 code 47 comments 36 blanks\n## Copyright (C) 2016 Jeremiah Orians\n## This file is part of stage0.\n##\n## s"
  },
  {
    "path": "tests/data/m4.m4",
    "chars": 225,
    "preview": "dnl 7 lines 3 code 1 blanks 3 comments\nThe builtin `dnl' stands for “Discard to Next Line”:\ndnl this line is not emitted"
  },
  {
    "path": "tests/data/menhir.mly",
    "chars": 1037,
    "preview": "// 47 lines 31 code 7 comments 9 blanks\n\n(* Example from the menhir development with instrumented comments.\n * (* Note: "
  },
  {
    "path": "tests/data/meson.build",
    "chars": 202,
    "preview": "# 12 lines 6 code 2 comments 4 blanks\n\nproject('xyz', 'c',\n        meson_version : '>=0.30.0') # not counted\n\nxyz_gen = "
  },
  {
    "path": "tests/data/metal.metal",
    "chars": 449,
    "preview": "/* 32 lines 21 code 5 comments 6 blanks */\n#include <metal_stdlib>\n\n// comment\nstruct Uniforms {\n    float2 extent;\n};\n\n"
  },
  {
    "path": "tests/data/mlatu.mlt",
    "chars": 520,
    "preview": "// 22 lines 14 code 3 comments 5 blanks\n\ndefine divisible (Int, Int -> Bool +Fail) { (%) 0 (=) }\n\n// Here's a random com"
  },
  {
    "path": "tests/data/moduledef.def",
    "chars": 309,
    "preview": "; 17 lines 9 code 6 comments 2 blanks\n;\n; Definition file of KERNEL32.dll\n; Automatic generated by gendef\n; written by K"
  },
  {
    "path": "tests/data/mojo.mojo",
    "chars": 414,
    "preview": "# 21 lines 15 code 3 comments 3 blanks\n\n\n'''\nThis is a docstring.\n# It has multiple lines.\nThis is the end of the docstr"
  },
  {
    "path": "tests/data/monkeyc.mc",
    "chars": 2097,
    "preview": "// 69 lines 41 code 18 comments 10 blanks\n// Slightly modified template from the \"Garmin.monkey-c\" VS Code extension.\nim"
  },
  {
    "path": "tests/data/nextflow.nf",
    "chars": 249,
    "preview": "/* 18 lines 10 code 5 comments 3 blanks */\n\n/*\nNextflow - hello\n*/\n\n// comment\ncheers = Channel.from 'Bonjour', 'Ciao', "
  },
  {
    "path": "tests/data/nqp.nqp",
    "chars": 547,
    "preview": "# 24 lines 14 code 8 comments 2 blanks\n=begin\nRegex methods and functions\n=end\n\n=begin item match\nMatch C<$text> against"
  },
  {
    "path": "tests/data/odin.odin",
    "chars": 542,
    "preview": "// 29 lines 17 code 7 comments 5 blanks\nimport \"core:fmt\"\n\n/*\n * Calculates the next number in the Collatz sequence\n *\n "
  },
  {
    "path": "tests/data/open_policy_agent.rego",
    "chars": 307,
    "preview": "# 13 lines 8 code 3 comments 2 blanks\n\npackage application.authz\n\n# Only owner can update the pet's information\n# Owners"
  },
  {
    "path": "tests/data/openscad.scad",
    "chars": 711,
    "preview": "//! 34 lines 15 code 16 comments 3 blanks\n// https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Commented_Example_Projec"
  },
  {
    "path": "tests/data/opentype.fea",
    "chars": 2064,
    "preview": "# 54 lines 24 code 24 comments 6 blanks\nlanguagesystem DFLT dflt;\nlanguagesystem latn dflt;\nlanguagesystem latn DEU;\nlan"
  },
  {
    "path": "tests/data/org_mode.org",
    "chars": 186,
    "preview": "# 13 lines 7 code 2 comments 4 blanks\n\n#+TITLE: This is the title, not a comment\n\n# This is comment\n\nSome text\n\n* Headin"
  },
  {
    "path": "tests/data/pan.pan",
    "chars": 630,
    "preview": "# 21 lines 11 code 4 comments 6 blanks\n\n# Pan example code, see https://quattor-pan.readthedocs.io/en/stable/pan-book/in"
  },
  {
    "path": "tests/data/pcss.pcss",
    "chars": 212,
    "preview": "/* 14 lines 6 code 5 comments 3 blanks */\n\n.foo {\n  color: #f00;\n\n  &.bar {\n    background: url(\"foobar.jpg\");\n  }\n}\n\n//"
  },
  {
    "path": "tests/data/pest.pest",
    "chars": 259,
    "preview": "// 9 lines 4 code 3 comments 2 blanks\nalpha = { 'a'..'z' | 'A'..'Z' }\ndigit = { '0'..'9' }\n\nident = { (alpha | digit)+ }"
  },
  {
    "path": "tests/data/phix.e",
    "chars": 790,
    "preview": "/* 40 lines 25 code 8 comments 7 blanks */\n\n-- copied from cpp, not necessarily idiomatic Euphoria code\n\ninclude std/seq"
  },
  {
    "path": "tests/data/plantuml.puml",
    "chars": 1027,
    "preview": "' 35 lines 10 code 13 comments 12 blanks\n' plantuml line comments must start at the beginning of a line.\n' plantuml bloc"
  },
  {
    "path": "tests/data/pofile.po",
    "chars": 477,
    "preview": "# 14 lines 6 code 5 comments 3 blanks\n\n#: lib/error.c:116\nmsgid \"Unknown system error\"\nmsgstr \"Error desconegut del sist"
  },
  {
    "path": "tests/data/pofile_pot.pot",
    "chars": 407,
    "preview": "# 17 lines 8 code 5 comments 4 blanks\n\n#: disk-utils/addpart.c:60 disk-utils/delpart.c:61 disk-utils/resizepart.c:101\nms"
  },
  {
    "path": "tests/data/poke.pk",
    "chars": 102,
    "preview": "/* 4 lines 2 code 1 comments 1 blanks */\n\nvar N = 3;\nfun getoff = offset<uint<64>,B>: { return 2#B; }\n"
  },
  {
    "path": "tests/data/pony.pony",
    "chars": 182,
    "preview": "// 12 lines 7 code 3 comments 2 blanks\n\n/* com-\n    -ment */\n\nactor Main\n    \"\"\"\n        Some\n        Docs\n    \"\"\"\n    n"
  },
  {
    "path": "tests/data/postcss.sss",
    "chars": 340,
    "preview": "// 27 lines 18 code 4 comments 5 blanks\n\n/**\nmulti-line\n*/\ndiv {\n  width: calc(99.9% * 1/3 -  (30px - 30px * 1/3)); \n}\n\n"
  },
  {
    "path": "tests/data/powershell.ps1",
    "chars": 167,
    "preview": "# 17 lines 9 code 4 comments 4 blanks\n\n<#\nTest\n#>\n\n'a' + \"b\"\n\nWrite-Host @\"\n    Name: $name\n    Address: $address\n\"@\n\n$t"
  },
  {
    "path": "tests/data/pug.pug",
    "chars": 249,
    "preview": "//- 13 lines, 8 code, 3 comments, 2 blanks\n\ndoctype html\n// this comment will be translated to an HTML comment\n//- this "
  },
  {
    "path": "tests/data/puppet.pp",
    "chars": 306,
    "preview": "# 18 lines 14 code 3 comments 1 blanks\nclass example::class(\n  $param1,\n  $param2=2,\n  $param3=undef,  # pass this one\n)"
  },
  {
    "path": "tests/data/pyret.arr",
    "chars": 268,
    "preview": "# 22 lines 9 code 8 comments 5 blanks\n\nfun single-quote():\n  doc: \"this is a documentation string\"\n  'foo'\nend\n\n#|\n  Hel"
  },
  {
    "path": "tests/data/python.py",
    "chars": 225,
    "preview": "# 15 lines, 10 code, 2 comments, 3 blanks\n\n\ndef add(x, y):\n    \"\"\"\n    Hello World\n    # Real Second line\n    Second lin"
  },
  {
    "path": "tests/data/q.q",
    "chars": 368,
    "preview": "// 14 lines 5 code 5 comments 4 blanks\n\n/calc nav for sets of portfolios,ETFs,indices,..\n\n/one day of ([]time;sym;price)"
  },
  {
    "path": "tests/data/qml.qml",
    "chars": 303,
    "preview": "// 20 lines 11 code 5 comments 4 blanks\n\nimport QtQuick 2.7\nimport QtQuick.Controls 2.0\n\nApplicationWindow {\n    visible"
  },
  {
    "path": "tests/data/racket.rkt",
    "chars": 777,
    "preview": ";;; 40 lines 15 code 14 comments 11 blanks\n#lang racket ; defines the language we are using\n\n;;; Comments\n\n;; Single lin"
  },
  {
    "path": "tests/data/raku.raku",
    "chars": 783,
    "preview": "# 49 lines 37 code 6 comments 6 blanks\n\n=begin pod\n\n=begin DESCRIPTION\n\n=head1 Test file for Tokei\n\n=end DESCRIPTION\n\n=b"
  }
]

// ... and 58 more files (download for full content)

About this extraction

This page contains the full source code of the XAMPPRocky/tokei GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 258 files (525.5 KB), approximately 153.7k tokens, and a symbol index with 235 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!