about summary refs log tree commit diff stats
path: root/templates/c
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2024-06-11 08:00:45 +0200
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2024-06-11 08:00:45 +0200
commite4a334234b91f230571b5111a2b698230b27c660 (patch)
tree7545deca502c7ef7f676fc689f8caaeee6e19801 /templates/c
parentchore(templates/rust): Quickly Update [THIS WILL BE REBASED] (diff)
downloadflake-templates-e4a334234b91f230571b5111a2b698230b27c660.tar.gz
flake-templates-e4a334234b91f230571b5111a2b698230b27c660.zip
refactor(common): Use symlinks to state, which files should be replaced
Every symlink in the `./templates` directory is now replaced with
the file it points to, making it obvious that this file should not be
edited.
Diffstat (limited to '')
l---------[-rw-r--r--]templates/c/.licensure.yml187
l---------[-rw-r--r--]templates/c/docs/%INIT_APPLICATION_NAME.1.md55
l---------[-rwxr-xr-x]templates/c/init97
l---------[-rwxr-xr-x]templates/c/scripts/renew_copyright_header.sh93
l---------[-rw-r--r--]templates/c/shell_line_editor.sh248
l---------[-rw-r--r--]templates/c/treefmt.nix74
6 files changed, 6 insertions, 748 deletions
diff --git a/templates/c/.licensure.yml b/templates/c/.licensure.yml
index 639d750..68a2454 100644..120000
--- a/templates/c/.licensure.yml
+++ b/templates/c/.licensure.yml
@@ -1,186 +1 @@
----
-# 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_APPLICATION_NAME_STYLIZED %INIT_YEAR - [year] (C) by [name of author]
-      SPDX-License-Identifier: CC-BY-SA-4.0
-
-      %INIT_APPLICATION_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
+../../common/files/.licensure.yml
\ No newline at end of file
diff --git a/templates/c/docs/%INIT_APPLICATION_NAME.1.md b/templates/c/docs/%INIT_APPLICATION_NAME.1.md
index e044647..8baad22 100644..120000
--- a/templates/c/docs/%INIT_APPLICATION_NAME.1.md
+++ b/templates/c/docs/%INIT_APPLICATION_NAME.1.md
@@ -1,54 +1 @@
-% %INIT_APPLICATION_NAME_CAPITALIZED_MAN_PART %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_AUTHOR_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/>.
+../../../common/files/docs/%INIT_APPLICATION_NAME.1.md
\ No newline at end of file
diff --git a/templates/c/init b/templates/c/init
index b9b4f80..2daec78 100755..120000
--- a/templates/c/init
+++ b/templates/c/init
@@ -1,96 +1 @@
-#!/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_MAN_PART "The capitalized name of the application (for documentation also with a man section part)" "$(echo "$APPLICATION_NAME" | sed 's/\([a-z]*\)/\U\1(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|g"
-
-    # Replace the variable in file paths
-    fd "%INIT_$var_name" . --hidden | while read -r file_path; do
-        new_file_path="$(echo "$file_path" | sed "s|%INIT_$var_name|$var_value|g")";
-        mv "$file_path" "$new_file_path"
-    done
-done < "$replacement_file"
-
-# HACK: Re-add the executable permissions to files, which the nix template has somehow
-# removed <2024-04-02>
-chmod +x scripts/*
-chmod +x update.sh
-[ -f ./build.sh ] && chmod +x build.sh
-
-# vim: ft=sh
+../../common/files/init
\ No newline at end of file
diff --git a/templates/c/scripts/renew_copyright_header.sh b/templates/c/scripts/renew_copyright_header.sh
index 4f424c3..70917db 100755..120000
--- a/templates/c/scripts/renew_copyright_header.sh
+++ b/templates/c/scripts/renew_copyright_header.sh
@@ -1,92 +1 @@
-#! /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
+../../../common/files/scripts/renew_copyright_header.sh
\ No newline at end of file
diff --git a/templates/c/shell_line_editor.sh b/templates/c/shell_line_editor.sh
index 8d6833a..0d2f727 100644..120000
--- a/templates/c/shell_line_editor.sh
+++ b/templates/c/shell_line_editor.sh
@@ -1,247 +1 @@
-#! /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"
-}
+../../common/files/shell_line_editor.sh
\ No newline at end of file
diff --git a/templates/c/treefmt.nix b/templates/c/treefmt.nix
index 1cbab40..94a5d85 100644..120000
--- a/templates/c/treefmt.nix
+++ b/templates/c/treefmt.nix
@@ -1,73 +1 @@
-{
-  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"];
-        };
-      };
-    };
-  }
-)
+../../common/files/treefmt.nix
\ No newline at end of file