summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEthan Morgan <ethan@gweithio.com>2026-02-13 14:58:57 +0000
committerEthan Morgan <ethan@gweithio.com>2026-02-13 14:58:57 +0000
commitb2318bae725de4055c0466e3f1858f51b22e37fe (patch)
tree44645ccbe2312faffb694202919026c414b626cb
add scriptsHEADmaster
-rwxr-xr-xa21
-rwxr-xr-xcreate_c_project.py647
-rwxr-xr-xdev-tmux10
-rwxr-xr-xsisc45
-rwxr-xr-xtmux-cmd3
5 files changed, 726 insertions, 0 deletions
diff --git a/a b/a
new file mode 100755
index 0000000..7ee09eb
--- /dev/null
+++ b/a
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+export SHELL="/bin/zsh"
+export acmeshell="/bin/zsh"
+export BROWSER=safari
+export tabstop=2
+export TERM=dumb
+export PAGER=nobs
+
+if [ "$(pgrep plumber)" ]; then
+ echo plumber is running
+else
+ echo starting plumber
+ plumber
+fi
+
+export NODE_NO_READLINE=1
+
+export PATH="/usr/bin:/bin:/usr/sbin:/sbin:$PATH"
+
+acme -a -b -c 2 -f /mnt/font/JetBrainsMono-Medium/16a/font $1
diff --git a/create_c_project.py b/create_c_project.py
new file mode 100755
index 0000000..b3ba6dd
--- /dev/null
+++ b/create_c_project.py
@@ -0,0 +1,647 @@
+#!/usr/bin/env python3
+"""
+Create a C project structure based on the gcli build system pattern.
+Simplified version with minimal files.
+"""
+
+import argparse
+import os
+import sys
+from pathlib import Path
+import urllib.request
+
+
+def create_configure_script(project_name, version):
+ """Generate a configure script."""
+ return f'''#!/usr/bin/env sh
+#
+# Configure script for {project_name}
+#
+
+CONFIGURE_CMD_ARGS="${{*}}"
+
+PACKAGE_VERSION="{version}"
+PACKAGE_DATE="$(date +%Y-%m-%d)"
+PACKAGE_STRING="{project_name} $PACKAGE_VERSION"
+PACKAGE_BUGREPORT="your-email@example.com"
+PACKAGE_URL="https://example.com/{project_name}"
+
+find_program() {{
+ varname=$1
+ shift
+
+ printf "Checking for $varname ..." >&2
+ for x in $*; do
+ if command -v $x >/dev/null 2>&1 && [ -x $(command -v $x) ]; then
+ binary="$(command -v $x)"
+ printf " $binary\\n" >&2
+ echo "${{binary}}"
+ return 0
+ fi
+ done
+ printf " not found\\n" >&2
+ return 1
+}}
+
+die() {{
+ printf "%s\\n" "${{*}}"
+ exit 1
+}}
+
+# Default values
+PREFIX="/usr/local"
+OPTIMISE="release"
+CC=""
+AR="ar"
+RANLIB="ranlib"
+RM="rm"
+INSTALL="install"
+
+# Parse arguments
+while [ $# -gt 0 ]; do
+ case "$1" in
+ --prefix=*)
+ PREFIX="${{1#--prefix=}}"
+ ;;
+ --prefix)
+ shift
+ PREFIX="$1"
+ ;;
+ --debug)
+ OPTIMISE="debug"
+ ;;
+ --release)
+ OPTIMISE="release"
+ ;;
+ --help)
+ cat <<EOF
+Configure script for {project_name}
+
+Options:
+ --prefix=PREFIX Installation prefix (default: /usr/local)
+ --debug Build with debug symbols, no optimization
+ --release Build with optimizations (default)
+ --help Show this help message
+
+Environment variables:
+ CC C compiler
+ AR Archiver
+ RANLIB ranlib
+ CFLAGS Additional C flags
+ LDFLAGS Additional linker flags
+EOF
+ exit 0
+ ;;
+ *)
+ die "Unknown option: $1"
+ ;;
+ esac
+ shift
+done
+
+# Find required tools
+if [ -z "$CC" ]; then
+ CC=$(find_program CC cc clang gcc) || die "No C compiler found"
+fi
+
+# Use basename only for better tool compatibility (e.g., bear)
+CC=$(basename "$CC")
+
+# Detect compiler type
+if $CC --version 2>&1 | grep -i clang >/dev/null; then
+ CCOM="clang"
+elif $CC --version 2>&1 | grep -i gcc >/dev/null; then
+ CCOM="gcc"
+else
+ CCOM="unknown"
+fi
+
+printf "Compiler: %s (%s)\\n" "$CC" "$CCOM"
+
+# Generate config.h
+cat > config.h <<EOF_CONFIG
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+#define PACKAGE_STRING "$PACKAGE_STRING"
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+#define PACKAGE_URL "$PACKAGE_URL"
+
+#endif /* CONFIG_H */
+EOF_CONFIG
+
+# Determine source directory
+SRCDIR="$(dirname "$0")"
+SRCDIR="$(cd "$SRCDIR" && pwd)"
+
+# Generate Makefile from Makefile.in
+sed \\
+ -e "s|@PREFIX@|$PREFIX|g" \\
+ -e "s|@CC@|$CC|g" \\
+ -e "s|@CCOM@|$CCOM|g" \\
+ -e "s|@AR@|$AR|g" \\
+ -e "s|@RANLIB@|$RANLIB|g" \\
+ -e "s|@RM@|$RM|g" \\
+ -e "s|@INSTALL@|$INSTALL|g" \\
+ -e "s|@OPTIMISE@|$OPTIMISE|g" \\
+ -e "s|@VERSION@|$PACKAGE_VERSION|g" \\
+ -e "s|@SRCDIR@|$SRCDIR|g" \\
+ < "$SRCDIR/Makefile.in" > Makefile
+
+echo "Configuration complete. Run 'make' to build."
+'''
+
+
+def create_makefile_in(project_name):
+ """Generate a Makefile.in template."""
+ return f'''# Makefile for {project_name}
+VERSION = @VERSION@
+
+# Environment and values saved by the configure script
+CC = @CC@
+CCOM = @CCOM@
+AR = @AR@
+RANLIB = @RANLIB@
+RM = @RM@
+INSTALL = @INSTALL@
+OPTIMISE = @OPTIMISE@
+PREFIX = @PREFIX@
+SRCDIR = @SRCDIR@
+
+# Find all .c files in src/ recursively
+SRCS := $(shell find $(SRCDIR)/src -name '*.c' -type f)
+# Generate object file names (strip SRCDIR/src/ prefix and change .c to .o)
+OBJS := $(patsubst $(SRCDIR)/src/%.c,%.o,$(SRCS))
+
+# VPATH for finding source files
+VPATH = $(SRCDIR)/src:$(shell find $(SRCDIR)/src -type d 2>/dev/null | tr '\\n' ':')
+
+# Compiler flags
+COPTFLAGS_gcc_debug = -O0 -g3 -Wall -Wextra
+COPTFLAGS_gcc_release = -O2 -DNDEBUG
+COPTFLAGS_clang_debug = -O0 -g3 -Wall -Wextra
+COPTFLAGS_clang_release = -O2 -DNDEBUG
+COPTFLAGS = $(COPTFLAGS_$(CCOM)_$(OPTIMISE))
+
+CSTDFLAGS_gcc = -std=c11 -pedantic
+CSTDFLAGS_clang = -std=c11 -pedantic
+CSTDFLAGS = $(CSTDFLAGS_$(CCOM))
+
+CFLAGS = $(CSTDFLAGS) $(COPTFLAGS) -I$(SRCDIR)/include -I$(SRCDIR)/thirdparty/utest -I. -DHAVE_CONFIG_H=1
+LDFLAGS =
+
+# Targets
+BINARY = {project_name}
+
+.PHONY: all clean install check
+
+all: $(BINARY)
+
+# Create subdirectories for object files if needed
+$(BINARY): $(OBJS)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS)
+
+# Suffix rule for compiling (uses VPATH to find .c files)
+.SUFFIXES: .c .o
+
+.c.o:
+ @test -d $(dir $@) || mkdir -p $(dir $@)
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+clean:
+ $(RM) -f $(BINARY) $(OBJS)
+ $(RM) -f test_main test_main.o
+ find . -type f -name '*.o' -delete 2>/dev/null || true
+
+install: $(BINARY)
+ $(INSTALL) -d $(DESTDIR)$(PREFIX)/bin
+ $(INSTALL) -m 755 $(BINARY) $(DESTDIR)$(PREFIX)/bin/
+
+# Test target - links with all objects except main.o
+TEST_OBJS := $(filter-out main.o,$(OBJS))
+
+check: test_main
+ ./test_main
+
+test_main: test_main.o $(TEST_OBJS)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
+
+test_main.o: $(SRCDIR)/tests/test_main.c $(SRCDIR)/include/{project_name}/base.h
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+'''
+
+
+def create_main_c(project_name):
+ """Generate a main.c file."""
+ return f'''#include <stdio.h>
+#include <stdlib.h>
+#include "{project_name}/base.h"
+#include "config.h"
+
+int main(int argc, char **argv) {{
+ (void)argc;
+ (void)argv;
+
+ printf("%s version %s\\n", PACKAGE_STRING, PACKAGE_VERSION);
+
+ /* Call a function from base.h */
+ {project_name}_init();
+
+ printf("Hello from {project_name}!\\n");
+
+ {project_name}_cleanup();
+
+ return 0;
+}}
+'''
+
+
+def create_base_c(project_name):
+ """Generate a base.c implementation file."""
+ return f'''#include "{project_name}/base.h"
+
+void {project_name}_init(void) {{
+ /* Initialize resources here */
+}}
+
+void {project_name}_cleanup(void) {{
+ /* Cleanup resources here */
+}}
+'''
+
+
+def create_base_h(project_name):
+ """Generate a base.h header file."""
+ guard = f"{project_name.upper()}_BASE_H"
+ return f'''#ifndef {guard}
+#define {guard}
+
+/**
+ * Initialize {project_name}
+ */
+void {project_name}_init(void);
+
+/**
+ * Cleanup {project_name} resources
+ */
+void {project_name}_cleanup(void);
+
+#endif /* {guard} */
+'''
+
+
+def create_test_c(project_name):
+ """Generate a test file using utest.h."""
+ return f'''#include "utest.h"
+#include "{project_name}/base.h"
+
+UTEST({project_name}, init_cleanup) {{
+ {project_name}_init();
+ {project_name}_cleanup();
+ ASSERT_TRUE(1);
+}}
+
+UTEST({project_name}, basic_test) {{
+ ASSERT_EQ(1, 1);
+ ASSERT_NE(1, 0);
+ ASSERT_TRUE(1);
+ ASSERT_FALSE(0);
+}}
+
+UTEST_MAIN()
+'''
+
+
+def create_readme(project_name, version):
+ """Generate a README.md file."""
+ return f'''# {project_name.upper()}
+
+Version {version}
+
+## Description
+
+A C project created with the gcli-style build system.
+
+## Building
+
+### Dependencies
+
+Required:
+- C11 compiler (gcc or clang)
+- make
+
+### Build Instructions
+
+```bash
+./configure
+make
+```
+
+### Debug Build
+
+```bash
+./configure --debug
+make
+```
+
+### Out-of-tree builds (optional)
+
+You can also build in a separate directory:
+
+```bash
+mkdir build
+cd build
+../configure
+make
+```
+
+### Installation
+
+```bash
+sudo make install
+```
+
+Default prefix is `/usr/local`. To change:
+
+```bash
+./configure --prefix=/usr
+```
+
+## Testing
+
+```bash
+make check
+```
+
+## IDE Support
+
+### clangd / LSP
+
+To generate `compile_commands.json` for clangd, use one of these methods:
+
+**Option 1: Using compiledb (recommended)**
+```bash
+pip install compiledb
+compiledb make
+```
+
+**Option 2: Using bear**
+```bash
+bear -- make
+```
+
+If the file is empty, try a clean build:
+```bash
+make clean
+bear -- make
+```
+
+## Usage
+
+```bash
+./{project_name}
+```
+'''
+
+
+def create_gitignore():
+ """Generate a .gitignore file."""
+ return '''# Build artifacts
+*.o
+*.a
+*.so
+*.dylib
+*.dll
+*.exe
+
+# Build directories
+build/
+debug/
+release/
+dist/
+
+# Generated files
+config.h
+Makefile
+
+# Editor files
+.vscode/
+.idea/
+*.swp
+*.swo
+*~
+
+# OS files
+.DS_Store
+Thumbs.db
+'''
+
+
+def create_clangd_config():
+ """Generate a .clangd configuration file."""
+ return '''# clangd configuration
+CompileFlags:
+ Add:
+ - -Wall
+ - -Wextra
+
+Diagnostics:
+ UnusedIncludes: Strict
+ MissingIncludes: Strict
+'''
+
+
+def create_license(project_name):
+ """Generate a simple LICENSE file."""
+ import datetime
+ year = datetime.datetime.now().year
+ return f'''Copyright (c) {year}, {project_name} authors
+
+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.
+'''
+
+
+def create_gentarball_sh(project_name):
+ """Generate a gentarball.sh script for creating release tarballs."""
+ return f'''#!/bin/sh
+#
+# Generate release tarballs for {project_name}
+
+command -v git > /dev/null 2>&1 || (echo "error: you need git to run this script" && exit 1)
+
+findversion() {{
+ eval $(grep PACKAGE_VERSION $(dirname $0)/../configure | sed 1q)
+ echo $PACKAGE_VERSION
+}}
+
+VERSION=$(findversion)
+
+DIR=dist/{project_name}-${{VERSION}}
+mkdir -p $DIR
+
+if [ -d .got ]; then
+ repodir=$(got info | grep '^repository' | cut -d: -f2 | xargs)
+ head=$(got br)
+else
+ repodir=$(git rev-parse --show-toplevel)/.git
+ head=@
+fi
+
+echo "Making BZIP tarball"
+git --git-dir="${{repodir}}" archive --format=tar --prefix={project_name}-$VERSION/ $head \\
+ | bzip2 -v > $DIR/{project_name}-$VERSION.tar.bz2
+echo "Making XZ tarball"
+git --git-dir="${{repodir}}" archive --format=tar --prefix={project_name}-$VERSION/ $head \\
+ | xz -v > $DIR/{project_name}-$VERSION.tar.xz
+echo "Making GZIP tarball"
+git --git-dir="${{repodir}}" archive --format=tar --prefix={project_name}-$VERSION/ $head \\
+ | gzip -v > $DIR/{project_name}-$VERSION.tar.gz
+
+(
+ cd $DIR
+ echo "Calculating SHA256SUMS"
+ sha256sum *.tar* > SHA256SUMS
+)
+
+echo "Release Tarballs are at $DIR"
+'''
+
+
+def create_project(project_name, version, output_dir):
+ """Create the complete project structure."""
+ project_path = Path(output_dir) / project_name
+
+ if project_path.exists():
+ print(f"Error: Directory {project_path} already exists!", file=sys.stderr)
+ return False
+
+ print(f"Creating project: {project_name} v{version}")
+ print(f"Output directory: {project_path}")
+
+ # Create directory structure
+ dirs = [
+ project_path,
+ project_path / "src",
+ project_path / "include" / project_name,
+ project_path / "tests",
+ project_path / "thirdparty" / "utest",
+ project_path / "tools",
+ ]
+
+ for dir_path in dirs:
+ dir_path.mkdir(parents=True, exist_ok=True)
+ print(f" Created: {dir_path.relative_to(output_dir)}/")
+
+ # Create files
+ files = {
+ project_path / "configure": create_configure_script(project_name, version),
+ project_path / "Makefile.in": create_makefile_in(project_name),
+ project_path / "src" / "main.c": create_main_c(project_name),
+ project_path / "src" / "base.c": create_base_c(project_name),
+ project_path / "include" / project_name / "base.h": create_base_h(project_name),
+ project_path / "tests" / "test_main.c": create_test_c(project_name),
+ project_path / "tools" / "gentarball.sh": create_gentarball_sh(project_name),
+ project_path / "README.md": create_readme(project_name, version),
+ project_path / ".gitignore": create_gitignore(),
+ project_path / ".clangd": create_clangd_config(),
+ project_path / "LICENSE": create_license(project_name),
+ }
+
+ for file_path, content in files.items():
+ file_path.write_text(content)
+ print(f" Created: {file_path.relative_to(output_dir)}")
+
+ # Download utest.h
+ print(" Downloading utest.h...")
+ utest_url = "https://raw.githubusercontent.com/sheredom/utest.h/master/utest.h"
+ utest_path = project_path / "thirdparty" / "utest" / "utest.h"
+ try:
+ with urllib.request.urlopen(utest_url) as response:
+ utest_content = response.read().decode('utf-8')
+ utest_path.write_text(utest_content)
+ print(f" Created: {utest_path.relative_to(output_dir)}")
+ except Exception as e:
+ print(f" Warning: Could not download utest.h: {e}", file=sys.stderr)
+ print(f" You can manually download it from {utest_url}", file=sys.stderr)
+
+ # Make configure executable
+ (project_path / "configure").chmod(0o755)
+ (project_path / "tools" / "gentarball.sh").chmod(0o755)
+
+ print(f"\\n✓ Project created successfully!")
+ print(f"\\nNext steps:")
+ print(f" cd {project_path}")
+ print(f" ./configure")
+ print(f" make")
+ print(f" ./{project_name}")
+
+ return True
+
+
+def main():
+ parser = argparse.ArgumentParser(
+ description="Create a C project with gcli-style build system",
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ epilog="""
+Examples:
+ %(prog)s myproject
+ %(prog)s myproject --version 0.1.0
+ %(prog)s myproject --output ~/projects
+ """
+ )
+
+ parser.add_argument(
+ "name",
+ help="Project name (lowercase, no spaces)"
+ )
+
+ parser.add_argument(
+ "--version",
+ default="0.1.0",
+ help="Initial version number (default: 0.1.0)"
+ )
+
+ parser.add_argument(
+ "--output",
+ default=".",
+ help="Output directory (default: current directory)"
+ )
+
+ args = parser.parse_args()
+
+ # Validate project name
+ if not args.name.replace("_", "").replace("-", "").isalnum():
+ print("Error: Project name must contain only letters, numbers, hyphens, and underscores",
+ file=sys.stderr)
+ return 1
+
+ if not args.name.islower():
+ print("Warning: Project name should be lowercase", file=sys.stderr)
+
+ # Create the project
+ if create_project(args.name, args.version, args.output):
+ return 0
+ else:
+ return 1
+
+
+if __name__ == "__main__":
+ sys.exit(main()) \ No newline at end of file
diff --git a/dev-tmux b/dev-tmux
new file mode 100755
index 0000000..e0ac529
--- /dev/null
+++ b/dev-tmux
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+SESSION_NAME=${1:- 󰊠 }
+
+tmux new-session -d -s "$SESSION_NAME" -n vi
+tmux new-window -t "$SESSION_NAME" -n build
+tmux new-window -t "$SESSION_NAME" -n git
+tmux new-window -t "$SESSION_NAME" -n nix
+tmux select-window -t "$SESSION_NAME":vi
+tmux attach-session -t "$SESSION_NAME"
diff --git a/sisc b/sisc
new file mode 100755
index 0000000..137bd48
--- /dev/null
+++ b/sisc
@@ -0,0 +1,45 @@
+#!/bin/sh
+
+# Some weird script to find a word
+
+if [ $# -lt 1 ]; then
+ echo "Usage: $0 <search_word> [search_directory] [ignored_dir1] [ignored_dir2] ..." >&2
+ exit 1
+fi
+
+WORD="$1"
+shift
+
+DIR="${1:-.}"
+shift
+
+if [ ! -d "$DIR" ]; then
+ echo "Error: Directory '$DIR' does not exist." >&2
+ exit 1
+fi
+
+IGNORED_DIRS=""
+while [ $# -gt 0 ]; do
+ IGNORED_DIR="$1"
+ # Construct prune conditions
+ if [ -z "$IGNORED_DIRS" ]; then
+ IGNORED_DIRS="-path \"$DIR/$IGNORED_DIR\" -prune"
+ else
+ IGNORED_DIRS="$IGNORED_DIRS -o -path \"$DIR/$IGNORED_DIR\" -prune"
+ fi
+ shift
+done
+
+if [ -n "$IGNORED_DIRS" ]; then
+ FIND_COMMAND="find \"$DIR\" $IGNORED_DIRS -o -type f -print"
+else
+ FIND_COMMAND="find \"$DIR\" -type f"
+fi
+
+eval "$FIND_COMMAND" | while read -r file; do
+ if grep -q "$WORD" "$file" 2>/dev/null; then
+ grep -n "$WORD" "$file" 2>/dev/null | while IFS=: read -r linenum line; do
+ printf "%s:%d - %s\n" "$file" "$linenum" "$(echo "$line" | sed 's/^ *//')"
+ done
+ fi
+done
diff --git a/tmux-cmd b/tmux-cmd
new file mode 100755
index 0000000..cbaaac7
--- /dev/null
+++ b/tmux-cmd
@@ -0,0 +1,3 @@
+#/bin/sh
+
+tmux list-windows | grep -v "irc" | grep -v "email" | cut -d: -f1 | xargs -I{} tmux send-keys -t {} "$1" C-m