aboutsummaryrefslogtreecommitdiffstats
path: root/common/files
diff options
context:
space:
mode:
Diffstat (limited to 'common/files')
-rw-r--r--common/files/.licensure.yml186
-rw-r--r--common/files/docs/TODO.1.md54
-rwxr-xr-xcommon/files/init84
-rwxr-xr-xcommon/files/scripts/renew_copyright_header.sh92
-rw-r--r--common/files/shell_line_editor.sh247
-rw-r--r--common/files/treefmt.nix73
6 files changed, 736 insertions, 0 deletions
diff --git a/common/files/.licensure.yml b/common/files/.licensure.yml
new file mode 100644
index 0000000..60ef45c
--- /dev/null
+++ b/common/files/.licensure.yml
@@ -0,0 +1,186 @@
+---
+# Regexes which if matched by a file path will always be excluded from
+# getting a license header
+excludes:
+ - .*lock
+ - \.git/.*
+ - LICENSE.spdx
+ - LICENSE
+ - COPYING
+ - COPYING.LESSER
+ - .*\.(rst|txt|pdf)
+# Definition of the licenses used on this project and to what files
+# they should apply.
+#
+# No default license configuration is provided. This section must be
+# configured by the user.
+licenses:
+ - files: \.tex
+ ident: CC-BY-SA-4.0
+ authors:
+ - name: "%INIT_AUTHOR_NAME"
+ email: "%INIT_AUTHOR_EMAIL"
+
+ template: |
+ %INIT_APPLIACATION_NAME_STYLIZED %INIT_YEAR - [year] (C) by [name of author]
+ SPDX-License-Identifier: CC-BY-SA-4.0
+
+ %INIT_APPLIACATION_NAME_STYLIZED is licensed under a
+ Creative Commons Attribution-ShareAlike 4.0 International License.
+
+ You should have received a copy of the license along with this
+ work. If not, see <https://creativecommons.org/licenses/by-sa/4.0/>.
+
+ unwrap_text: false
+
+ # Either a regex or the string "any" to determine to what files this
+ # license should apply. It is common for projects to have files
+ # under multiple licenses or with multiple copyright holders. This
+ # provides the ability to automatically license files correctly
+ # based on their file paths.
+ #
+ # If "any" is provided all files will match this license.
+ - files: any
+ #
+ # The license identifier, a list of common identifiers can be
+ # found at: https://spdx.org/licenses/ but existence of the ident
+ # in this list it is not enforced unless auto_template is set to
+ # true.
+ ident: GPL-3.0-or-later
+ #
+ # A list of authors who hold copyright over these files
+ authors:
+ # Provide either your full name or company name for copyright purposes
+ - name: "%INIT_AUTHOR_NAME"
+ # Optionally provide email for copyright purposes
+ email: "%INIT_AUTHOR_EMAIL"
+
+ # The template that will be rendered to generate the header before
+ # comment characters are applied. Available variables are:
+ # - [year]: substituted with the current year.
+ # - [name of author]: Substituted with name of the author and email
+ # if provided. If email is provided the output appears as Full
+ # Name <email@example.com>. If multiple authors are provided the
+ # list is concatenated together with commas.
+ template: |
+ Copyright (C) %INIT_YEAR - [year]:
+ [name of author]
+ SPDX-License-Identifier: GPL-3.0-or-later
+
+ This file is part of %INIT_APPLICATION_NAME_STYLIZED.
+
+ %INIT_APPLICATION_NAME_STYLIZED is free software: you can redistribute it and/or modify
+ it under the terms of the Lesser GNU General Public License as
+ published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ and the Lesser GNU General Public License along with this program.
+ If not, see <https://www.gnu.org/licenses/>.
+
+
+ # If auto_template is true then template is ignored and the SPDX
+ # API will be queried with the ident value to automatically
+ # determine the license header template. auto_template works best
+ # with licenses that have a standardLicenseHeader field defined in
+ # their license info JSON, if it is not then we will use the full
+ # licenseText to generate the header which works fine for short
+ # licenses like MIT but can be quite lengthy for other licenses
+ # like BSD-4-Clause. The above default template is valid for most
+ # licenses and is recommended for MIT, and BSD licenses. Common
+ # licenses that work well with the auto_template feature are GPL
+ # variants, and the Apache 2.0 license.
+ #
+ # Important Note: this means the ident must be a valid SPDX identifier
+ # auto_template: true
+
+ # If true try to detect the text wrapping of the template, and unwrap it
+ unwrap_text: false
+
+# Define type of comment characters to apply based on file extensions.
+comments:
+ # The extensions (or singular extension) field defines which file
+ # extensions to apply the commenter to.
+ - extensions:
+ - js
+ - go
+ # The commenter field defines the kind of commenter to
+ # generate. There are two types of commenters: line and block.
+ #
+ # This demonstrates a line commenter configuration. A line
+ # commenter type will apply the comment_char to the beginning of
+ # each line in the license header. It will then apply a number of
+ # empty newlines to the end of the header equal to trailing_lines.
+ #
+ # If trailing_lines is omitted it is assumed to be 0.
+ commenter:
+ type: line
+ comment_char: "//"
+ trailing_lines: 1
+
+ - extensions:
+ - rs
+ - tri
+ - css
+ - cpp
+ - c
+ - h
+ # This demonstrates a block commenter configuration. A block
+ # commenter type will add start_block_char as the first character
+ # in the license header and add end_block_char as the last character
+ # in the license header. If per_line_char is provided each line of
+ # the header between the block start and end characters will be
+ # line commented with the per_line_char
+ #
+ # trailing_lines works the same for both block and line commenter
+ # types
+ commenter:
+ type: block
+ start_block_char: "/*\n"
+ end_block_char: "*/\n"
+ per_line_char: "*"
+ trailing_lines: 1
+
+ - extension:
+ - html
+ - md
+ commenter:
+ type: block
+ start_block_char: "<!--\n"
+ end_block_char: "-->\n"
+ trailing_lines: 1
+
+ - extensions:
+ - el
+ - lisp
+ commenter:
+ type: line
+ comment_char: ";;;"
+ trailing_lines: 1
+
+ - extensions:
+ - tex
+ - bib
+ commenter:
+ type: line
+ comment_char: "%"
+ trailing_lines: 1
+
+ # The extension string "any" is special and so will match any file
+ # extensions. Commenter configurations are always checked in the
+ # order they are defined, so if any is used it should be the last
+ # commenter configuration or else it will override all others.
+ #
+ # In this configuration if we can't match the file extension we fall
+ # back to the popular '#' line comment used in most scripting
+ # languages.
+ - extension: any
+ commenter:
+ type: line
+ comment_char: '#'
+ trailing_lines: 1
diff --git a/common/files/docs/TODO.1.md b/common/files/docs/TODO.1.md
new file mode 100644
index 0000000..15d5072
--- /dev/null
+++ b/common/files/docs/TODO.1.md
@@ -0,0 +1,54 @@
+% %INIT_APPLICATION_NAME_CAPITALIZED(1) %INIT_APPLICATION_NAME %INIT_APPLICATION_VERSION
+% %INIT_AUTHOR_NAME
+% %INIT_CURRENT_DATE
+
+# NAME
+
+%INIT_APPLICATION_NAME - %INIT_DESCRIPTION
+
+# SYNOPSIS
+
+**%INIT_APPLICATION_NAME** \[*--help*|*--version*\]
+
+# DESCRIPTION
+
+TODO
+
+# OPTIONS
+
+**--help**, **-h**
+: Displays a help message and exit.
+
+**--version**, **-v**
+: Displays the software version and exit.
+
+# EXAMPLES
+
+**%INIT_APPLICATION_NAME**
+: TODO. See the Description section for further details.
+
+# FILES
+
+*name.file*
+: This file is important because it does x.
+
+# BUGS
+
+Report bugs to <https://%INIT_REMOTE/%INIT_OWNER/%INIT_REPOSITORY/issues>.
+
+# COPYRIGHT
+
+Copyright (C) %INIT_YEAR %INIT_AUTOHR_NAME
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <https://www.gnu.org/licenses/>.
diff --git a/common/files/init b/common/files/init
new file mode 100755
index 0000000..1b7c86b
--- /dev/null
+++ b/common/files/init
@@ -0,0 +1,84 @@
+#!/usr/bin/env sh
+
+. "$(realpath "$(dirname "$0")")/shell_line_editor.sh"
+
+replacement_file="$(mktemp)"
+
+trap cleanup INT
+trap "cleanup; remove_self" EXIT
+cleanup() {
+ rm "$replacement_file"
+}
+remove_self() {
+ rm "$(realpath "$0")"
+ rm "$(realpath "$(dirname "$0")")/shell_line_editor.sh"
+}
+
+# Prompt the user for a specific variable.
+# ## Args:
+# [1]: Name of the variable to populate the answer to
+# [2]: An optional description
+# [3]: An optionally suggested answer
+# [4]: If this is set, the user is not even asked.
+prompt() {
+ pr_variable_upper="$(echo "$1" | sed 's/\([a-z]\)/\U\1/')"
+ pr_description="$2"
+ pr_suggested_answer="$3"
+ pr_ask="$4"
+
+ if [ -n "$pr_ask" ]; then
+ REPLY="$pr_suggested_answer";
+ else
+ printf "\033[94;1mEnter %s\033[0m" "$pr_variable_upper"
+ if [ -n "$pr_description" ];then
+ printf " (\033[93;1m%s\033[0m):\n" "$pr_description"
+ else
+ printf ":\n"
+ fi
+
+ # LE "> " 0 " " "$pr_suggested_answer" "yes_please_produce_debug_output"
+ LE "> " 0 " " "$pr_suggested_answer" ""
+ fi
+
+ pr_new_variable="$(printf '%s="%s"' "$pr_variable_upper" "$REPLY")"
+
+ eval "$pr_new_variable"
+ printf "%s\n" "$pr_new_variable" >> "$replacement_file"
+}
+
+git init
+
+# necessary meta data
+prompt APPLICATION_NAME "The name of the application" "$(basename "$PWD")"
+prompt APPLICATION_NAME_STYLIZED "The stylized name of the application (for documentation)" "$(echo "$APPLICATION_NAME" | sed 's/\([a-z]\)/\u\1/')"
+prompt APPLICATION_NAME_CAPITALIZED "The capitalized name of the application (for documentation)" "$(echo "$APPLICATION_NAME" | sed 's/\([a-z]\)/\U\1/')" "dont_ask"
+prompt APPLICATION_VERSION "The version of this program, without the prefix" "0.1.0"
+
+prompt AUTHOR_NAME "The name of the author (or authors)" "$(git config --get user.name)"
+prompt AUTHOR_EMAIL "The email of the author (or authors)" "$(git config --get user.email)"
+
+# cog change-log variables
+prompt REMOTE "The remote, this project will be pushed to" "codeberg.org"
+prompt REPOSITORY "The name of the repository in the remote" "$APPLICATION_NAME"
+prompt OWNER "The name of owner of the repository" "$AUTHOR_NAME"
+
+# nice meta data
+prompt DESCRIPTION "The description of this project" "[can be empty]"
+prompt CURRENT_DATE "The stylized version of the current date" "$(date +'%b %Y')"
+prompt YEAR "The year the work on this has begun (for copyright reasons)" "$(date +'%Y')"
+
+# LICENSE.spdx data (source: https://github.com/david-a-wheeler/spdx-tutorial)
+prompt APPLICATION_ORIGINATOR "The person or organization from whom the package originally came" "$AUTHOR_NAME"
+prompt APPLICATION_HOME_PAGE "The package's home page URL" "https://$REMOTE/$OWNER/$REPOSITORY"
+
+echo "$DESCRIPTION" > .git/description
+
+while read -r var; do
+ var_name="${var%=*}"
+ var_value="${var#*=\"}"
+ var_value="${var_value%\"}"
+
+ fd . --hidden --type file --exec sed --in-place "s|%\bINIT_$var_name\b|$var_value|"
+done < "$replacement_file"
+
+# vim: ft=sh
diff --git a/common/files/scripts/renew_copyright_header.sh b/common/files/scripts/renew_copyright_header.sh
new file mode 100755
index 0000000..4f424c3
--- /dev/null
+++ b/common/files/scripts/renew_copyright_header.sh
@@ -0,0 +1,92 @@
+#! /usr/bin/env sh
+
+# NOTE: This is the line length of the .licensure.yml header template **plus** the extra
+# line after the template comment.
+TEMPLATE_LINE_LENGTH=20
+LATEX_TEMPLATE_LINE_LENGTH=9
+
+PROJECT_ROOT="$(git rev-parse --show-toplevel)"
+
+remove() {
+ extension="$1"
+ file="$2"
+
+ # We need to differentiate, when removing the old copyright header, as some
+ # formatters do weird things to the file
+ case "$extension" in
+ # normal '#' comments (these are $TEMPLATE_LINE_LENGTH lines long)
+ "Makefile" | "toml" | "envrc" | "yml" | "gitignore" | "awk")
+ sed --in-place "1,${TEMPLATE_LINE_LENGTH}d" "$file"
+ ;;
+ # LaTeX files (or TeX files in general) have a different license, use the
+ # $LATEX_TEMPLATE_LINE_LENGTH variable.
+ "tex")
+ sed --in-place "1,${LATEX_TEMPLATE_LINE_LENGTH}d" "$file"
+ ;;
+ # normal '/* ... */' like comments (these are $TEMPLATE_LINE_LENGTH + 2 lines long)
+ "c" | "h" | "md" | "rs")
+ length="$((TEMPLATE_LINE_LENGTH + 2))"
+ sed --in-place "1,${length}d;" "$file"
+ ;;
+ # alejandra (the nix formatter) removes the blank line after the comment,
+ # thus only $TEMPLATE_LINE_LENGTH - 1 lines
+ "nix")
+ length="$((TEMPLATE_LINE_LENGTH - 1))"
+ sed --in-place "1,${length}d;" "$file"
+ ;;
+ # Shell needs a shebang on the first line, only after the first line can we
+ # remove the $TEMPLATE_LINE_LENGTH lines
+ "sh")
+ sed --in-place "2,${TEMPLATE_LINE_LENGTH}d;" "$file"
+ licensure --in-place "$file"
+
+ TEMPLATE_LINE_LENGTH_NEW="$(($(yq --raw-output '.licenses | map(.template) | join("")' "$PROJECT_ROOT/.licensure.yml" | wc -l) + $(yq '.comments | last | .commenter.trailing_lines' "$PROJECT_ROOT/.licensure.yml")))"
+
+ # delete the current shebang
+ to="$((TEMPLATE_LINE_LENGTH_NEW + 1))"
+ sed --in-place "${TEMPLATE_LINE_LENGTH_NEW},${to}d;" "$file"
+
+ # add a new one
+ sed --in-place "1i#! /usr/bin/env sh" "$file"
+ ;;
+ *)
+ echo "File '$file' with extension '$extension' is not know yet, please add it!"
+ ;;
+ esac
+}
+
+list() {
+ echo "$extension -> $file"
+}
+
+if [ -f "$1" ]; then
+ file="$(realpath "$1")"
+ filename="$(basename -- "$file")"
+ extension="${filename##*.}"
+ filename="${filename%.*}"
+
+ if [ -n "$DRY_RUN" ]; then
+ list "$extension" "$file"
+ else
+ remove "$extension" "$file"
+ fi
+else
+ fd --type file --hidden . | while read -r file; do
+ if grep --quiet 'SPDX-License-Identifier' "$file"; then
+ filename="$(basename -- "$file")"
+ extension="${filename##*.}"
+ filename="${filename%.*}"
+
+ if [ -n "$DRY_RUN" ]; then
+ list "$extension" "$file"
+ else
+ remove "$extension" "$file"
+ fi
+ fi
+ done
+
+ if [ -z "$DRY_RUN" ]; then
+ licensure --in-place --project
+ nix fmt
+ fi
+fi
diff --git a/common/files/shell_line_editor.sh b/common/files/shell_line_editor.sh
new file mode 100644
index 0000000..8d6833a
--- /dev/null
+++ b/common/files/shell_line_editor.sh
@@ -0,0 +1,247 @@
+#! /usr/bin/env sh
+# Taken in verbatim from: https://unix.stackexchange.com/a/113450, and somewhat changed
+
+LE_print_debug() {
+ LE_debug="$1"
+ LE_debug_msg="$2"
+ [ -n "$LE_debug" ] && printf "\nDBG: (%s)\n" "$LE_debug_msg" >outfile.debug
+}
+
+LE() {
+ # Shell Line Editor. Extremely slow and stupid code. However it
+ # should work on ansi/vt100/linux derived terminals on POSIX
+ # systems.
+ # Understands some emacs key bindings: CTRL-(A,B,D,E,F,H,K,L)
+ # plus the CTRL-W and CTRL-U normal killword and kill.
+ # no Meta-X key, but handling of <Left>, <Right>, <Home>, <End>
+ # <Suppr>.
+ #
+ # Args:
+ # [1]: prompt (\x sequences recognized, defaults to "")
+ # [2]: max input length (unlimited if < 0, (default))
+ # [3]: fill character when erasing (defaults to space)
+ # [4]: initial value.
+ # [5]: whether to output debugfiles (outfile.debug and outfile.raw.debug)
+ # Returns:
+ # 0: OK
+ # 1: od(d) error or CTRL-C hit
+
+ LE_prompt="$1"
+ LE_max=${2--1}
+ LE_fill=${3-" "}
+ LE_debug="$5"
+
+ LE_backward() {
+ LE_substract="$1"
+ while [ -n "$LE_substract" ]; do
+ printf '\b%s' "$2"
+ LE_substract=${LE_substract%?}
+ done
+ }
+
+ LE_fill() {
+ LE_substract="$1"
+ while [ -n "$LE_substract" ]; do
+ printf '%s' "$LE_fill"
+ LE_substract=${LE_substract%?}
+ done
+ }
+
+ # Used but not right now
+ # shellcheck disable=2016
+ LE_restore='stty "$LE_tty"
+ LC_COLLATE='${LC_COLLATE-"; unset LC_COLLATE"}
+
+ # LE_tty is used in the restore above
+ # shellcheck disable=2034
+ LE_ret=1 LE_tty=$(stty -g) LC_COLLATE=C
+
+ # text on the right of the cursor
+ LE_left=$4
+ # text on the left of the cursor
+ LE_right=''
+
+ # Tell the terminal to show us every char inputted
+ stty -icanon -echo -isig min 3 time 1 -istrip
+ printf '%b%s' "$LE_prompt" "$LE_left"
+
+ # clear the output
+ [ -n "$LE_debug" ] && printf "" >outfile.debug
+ [ -n "$LE_debug" ] && printf "" >outfile.raw.debug
+
+ # The value needs to be split for it to work (and it's either way just numbers)
+ # shellcheck disable=2046
+ while set -- $(dd bs=3 count=1 2>/dev/null | od -vAn -to1); do
+ while [ "$#" -gt 0 ]; do
+ [ -n "$LE_debug" ] && printf "%b" "\0$1" >>outfile.debug
+ [ -n "$LE_debug" ] && printf "%s " "$1" >>outfile.raw.debug
+ LE_current_key=$1
+ shift
+
+ # 033 is ^[ (`printf "\\$1\n" | cat -v`)
+ if [ "$LE_current_key" = 033 ]; then
+ case "$1$2$3" in
+ # [ C | O C -> ^F forward
+ 133103* | 117103*)
+ shift 2
+ LE_current_key=006
+ ;;
+ # [ D | O D -> ^B backward
+ 133104* | 117104*)
+ shift 2
+ LE_current_key=002
+ ;;
+ # [ H | O H -> ^A beginning of line
+ 133110* | 117110*)
+ shift 2
+ LE_current_key=001
+ ;;
+ # [ P | O P -> ^D del char
+ 133120* | 117120*)
+ shift 2
+ LE_current_key=004
+ ;;
+ # [ F | O F -> ^E end of line
+ 133106* | 117106*)
+ shift 2
+ LE_current_key=005
+ ;;
+ # [ 1 ~ -> ^A beginning of line
+ 133061176)
+ shift 3
+ LE_current_key=001
+ ;;
+ # [ 4 ~ -> ^E end of line
+ 133064176)
+ shift 3
+ LE_current_key=005
+ ;;
+ # [ 3 ~ -> ^D del char
+ 133063176)
+ shift 3
+ LE_current_key=004
+ ;;
+ # [ | O
+ 133* | 117*)
+ shift
+ # Is $1 in ge 0 AND le 9 OR eq ';'?
+ # These are control sequences for things like colors; Ignore them
+ while [ "0$1" -ge 060 ] && [ "0$1" -le 071 ] ||
+ [ "0$1" -eq 073 ]; do
+ shift
+ done
+ ;;
+ esac
+ fi
+
+ case "$LE_current_key" in
+ 001) # ^A beginning of line
+ LE_backward "$LE_left"
+ LE_right="$LE_left$LE_right"
+ LE_left=
+ ;;
+ 002) # ^B backward
+ if [ "$LE_left" = "" ]; then
+ # bell
+ printf '\a'
+ LE_print_debug "$LE_debug" "backward with empty left"
+ else
+ printf '\b'
+ LE_tmp="${LE_left%?}"
+ LE_right="${LE_left#"$LE_tmp"}$LE_right"
+ LE_left="$LE_tmp"
+ fi ;;
+ 003) # CTRL-C
+ break 2 ;;
+ 004) # ^D del char
+ if [ "$LE_right" = "" ]; then
+ # bell (tell the user that the line is empty)
+ printf '\a'
+ LE_print_debug "$LE_debug" "delete with empty right"
+ else
+ LE_right="${LE_right#?}"
+ printf '%s\b' "$LE_right$LE_fill"
+ LE_backward "$LE_right"
+ fi ;;
+ 012 | 015) # NL or CR
+ LE_ret=0
+ break 2
+ ;;
+ 005) # ^E end of line
+ printf '%s' "$LE_right"
+ LE_left="$LE_left$LE_right"
+ LE_right=
+ ;;
+ 006) # ^F forward
+ if [ "$LE_right" = "" ]; then
+ # bell (tell the user that the line is empty)
+ printf '\a'
+ LE_print_debug "$LE_debug" "forward with empty right"
+ else
+ LE_tmp="${LE_right#?}"
+ LE_left="$LE_left${LE_right%"$LE_tmp"}"
+ printf %s "${LE_right%"$LE_tmp"}"
+ LE_right="$LE_tmp"
+ fi ;;
+ 010 | 177) # backspace or del
+ if [ "$LE_left" = "" ]; then
+ # bell
+ printf '\a'
+ LE_print_debug "$LE_debug" "backspace with empty left"
+ else
+ printf '\b%s\b' "$LE_right$LE_fill"
+ LE_backward "$LE_right"
+ LE_left="${LE_left%?}"
+ fi ;;
+ 013) # ^K kill to end of line
+ LE_fill "$LE_right"
+ LE_backward "$LE_right"
+ LE_right=""
+ ;;
+ 014) # ^L redraw
+ printf '\r%b%s' "$LE_prompt" "$LE_left$LE_right"
+ LE_backward "$LE_right"
+ ;;
+ 025) # ^U kill line
+ LE_backward "$LE_left"
+ LE_fill "$LE_left$LE_right"
+ LE_backward "$LE_left$LE_right"
+ LE_left=""
+ LE_right=""
+ ;;
+ 027) # ^W kill word
+ if [ "$LE_left" = "" ]; then
+ # bell
+ printf '\a'
+ else
+ LE_tmp="${LE_left% *}"
+ LE_backward "${LE_left#"$LE_tmp"}"
+ LE_fill "${LE_left#"$LE_tmp"}"
+ LE_backward "${LE_left#"$LE_tmp"}"
+ LE_left="$LE_tmp"
+ fi ;;
+ # Print the received key, as it did not match a special key
+ [02][4-7]? | [13]??) # 040 -> 177, 240 -> 377
+ # was assuming iso8859-x at the time
+ if [ "$LE_max" -gt 0 ] && LE_tmp="$LE_left$LE_right" &&
+ [ "${#LE_tmp}" -eq "$LE_max" ]; then
+ # bell, when the user is trying to cross the line limit
+ printf '\a'
+ LE_print_debug "$LE_debug" "max output reached"
+ else
+ LE_left="$LE_left$(printf '%b' "\0$LE_current_key")"
+ printf '%b%s' "\0$LE_current_key" "$LE_right"
+ LE_backward "$LE_right"
+ fi ;;
+ *)
+ LE_print_debug "$LE_debug" "key not recognized: $(printf "%b" "\0$LE_current_key")"
+ printf '\a'
+ ;;
+ esac
+ done
+ done
+ eval "$LE_restore"
+ REPLY=$LE_left$LE_right
+ echo
+ return "$LE_ret"
+}
diff --git a/common/files/treefmt.nix b/common/files/treefmt.nix
new file mode 100644
index 0000000..1cbab40
--- /dev/null
+++ b/common/files/treefmt.nix
@@ -0,0 +1,73 @@
+{
+ treefmt-nix,
+ pkgs,
+}:
+treefmt-nix.lib.evalModule pkgs (
+ {pkgs, ...}: {
+ # Used to find the project root
+ projectRootFile = "flake.nix";
+
+ programs = {
+ alejandra.enable = true;
+ rustfmt.enable = true;
+ clang-format.enable = true;
+ mdformat.enable = true;
+ shfmt = {
+ enable = true;
+ indent_size = 4;
+ };
+ shellcheck.enable = true;
+ prettier = {
+ settings = {
+ arrowParens = "always";
+ bracketSameLine = false;
+ bracketSpacing = true;
+ editorconfig = true;
+ embeddedLanguageFormatting = "auto";
+ endOfLine = "lf";
+ # experimentalTernaries = false;
+ htmlWhitespaceSensitivity = "css";
+ insertPragma = false;
+ jsxSingleQuote = true;
+ printWidth = 80;
+ proseWrap = "always";
+ quoteProps = "consistent";
+ requirePragma = false;
+ semi = true;
+ singleAttributePerLine = true;
+ singleQuote = true;
+ trailingComma = "all";
+ useTabs = false;
+ vueIndentScriptAndStyle = false;
+
+ tabWidth = 4;
+ overrides = {
+ files = ["*.js"];
+ options.tabwidth = 2;
+ };
+ };
+ };
+ stylua.enable = true;
+ ruff = {
+ enable = true;
+ format = true;
+ };
+ taplo.enable = true;
+ };
+
+ settings = {
+ global.excludes = [
+ "CHANGELOG.md"
+ "NEWS.md"
+ ];
+ formatter = {
+ clang-format = {
+ options = ["--style" "GNU"];
+ };
+ shfmt = {
+ includes = ["*.bash"];
+ };
+ };
+ };
+ }
+)