fix repl-block, check-tangle, commands: READMEs, exit codes, path resolution
repl-block: - Listing mode exits 0, not 1 (listing is not an error) - Dead lines parameter removed from find_by_function - Block listing goes to stderr (not stdout) so piped use works - Added README.org check-tangle: - Fixed tangle tool resolution: prefer local projects/tangle-tool/tangle - Fixed path resolution for relative and absolute tangle paths - Removed 2>/dev/null suppression so tangle errors are visible - Added README.org Commands: - Rewrote all three .opencode/commands/*.md with proper prompts
This commit is contained in:
22
projects/check-tangle/README.org
Normal file
22
projects/check-tangle/README.org
Normal file
@@ -0,0 +1,22 @@
|
||||
#+TITLE: check-tangle
|
||||
|
||||
Tangle an .org file and compile the resulting .lisp with SBCL in one step.
|
||||
|
||||
== Usage
|
||||
|
||||
#+begin_src shell
|
||||
check-tangle org/file.org
|
||||
#+end_src
|
||||
|
||||
Exit 0 if compilation succeeds, 1 if tangling or compilation fails.
|
||||
|
||||
== What it checks
|
||||
|
||||
1. Reads the ~:tangle~ header from the org file to find the target .lisp path
|
||||
2. Runs ~tangle~ to generate the .lisp from the .org source
|
||||
3. Runs ~sbcl compile-file~ on the result
|
||||
4. Reports the first compile error if any
|
||||
|
||||
== Requires
|
||||
|
||||
Emacs (for tangling), SBCL (for compilation).
|
||||
@@ -28,13 +28,26 @@ fi
|
||||
|
||||
# Resolve relative tangle path
|
||||
ORG_DIR=$(dirname "$ORG_FILE")
|
||||
LISP_FILE=$(cd "$ORG_DIR" && realpath -m "$TANGLE" 2>/dev/null || echo "$ORG_DIR/$TANGLE")
|
||||
if [ "$TANGLE" = "${TANGLE#/}" ]; then
|
||||
# Relative path
|
||||
LISP_FILE=$(cd "$ORG_DIR" && realpath -m "$TANGLE" 2>/dev/null || echo "$ORG_DIR/$TANGLE")
|
||||
else
|
||||
# Absolute path
|
||||
LISP_FILE="$TANGLE"
|
||||
fi
|
||||
|
||||
echo "Tangling: $ORG_FILE → $LISP_FILE" >&2
|
||||
|
||||
# Tangle using opencode's tangle tool
|
||||
TANGLE_CMD=$(command -v tangle 2>/dev/null || echo "/home/user/.opencode/bin/tangle")
|
||||
if ! "$TANGLE_CMD" "$ORG_FILE" 2>/dev/null; then
|
||||
# Prefer the memex's own tangle tool, then fall back to PATH
|
||||
if [ -x "projects/tangle-tool/tangle" ]; then
|
||||
TANGLE_CMD="projects/tangle-tool/tangle"
|
||||
elif command -v tangle &>/dev/null; then
|
||||
TANGLE_CMD="tangle"
|
||||
else
|
||||
TANGLE_CMD="/home/user/.opencode/bin/tangle"
|
||||
fi
|
||||
|
||||
if ! "$TANGLE_CMD" "$ORG_FILE"; then
|
||||
echo "FAIL: Tangling $ORG_FILE failed" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
28
projects/repl-block/README.org
Normal file
28
projects/repl-block/README.org
Normal file
@@ -0,0 +1,28 @@
|
||||
#+TITLE: repl-block
|
||||
|
||||
Extract a ~#+begin_src lisp~ block from an .org file and output it to stdout,
|
||||
ready to pipe to ~repl~ or inspect.
|
||||
|
||||
== Usage
|
||||
|
||||
#+begin_src shell
|
||||
repl-block org/file.org --function foo | repl
|
||||
repl-block org/file.org --block 3
|
||||
repl-block org/file.org --function foo --package :my-package
|
||||
repl-block org/file.org # list all blocks
|
||||
#+end_src
|
||||
|
||||
== Identifying blocks
|
||||
|
||||
By function name (--function): scans all blocks for (defun <name> ...) and
|
||||
outputs the containing block. By index (--block): 1-based position in file.
|
||||
|
||||
The --package flag prepends an ~(in-package ...)~ form so the REPL evaluates
|
||||
in the right namespace.
|
||||
|
||||
Combine with ~repl~ to send a block directly to the daemon:
|
||||
repl-block org/channel-tui-view.org --function view-status --package :passepartout.channel-tui | repl
|
||||
|
||||
== Requires
|
||||
|
||||
Python 3. No dependencies.
|
||||
@@ -41,7 +41,7 @@ def extract_blocks(lines):
|
||||
return blocks
|
||||
|
||||
|
||||
def find_by_function(blocks, name, lines):
|
||||
def find_by_function(blocks, name):
|
||||
for line_no, body in blocks:
|
||||
for bline in body:
|
||||
if re.match(rf"\(def(un|macro|method|var|parameter|class|struct|package)\s+{re.escape(name)}\b", bline):
|
||||
@@ -76,7 +76,7 @@ def main():
|
||||
blocks = extract_blocks(lines)
|
||||
|
||||
if args.function:
|
||||
line_no, body = find_by_function(blocks, args.function, lines)
|
||||
line_no, body = find_by_function(blocks, args.function)
|
||||
if body is None:
|
||||
print(f"No block found containing function '{args.function}'", file=sys.stderr)
|
||||
return 1
|
||||
@@ -86,12 +86,12 @@ def main():
|
||||
print(f"Block {args.block} not found (file has {len(blocks)} blocks)", file=sys.stderr)
|
||||
return 1
|
||||
else:
|
||||
# Print listing
|
||||
# Print listing to stderr so piping still works
|
||||
for idx, (line_no, body) in enumerate(blocks, 1):
|
||||
first = (body or [""])[0][:60]
|
||||
print(f" {idx}: line {line_no}: {first}")
|
||||
print(f" {idx}: line {line_no}: {first}", file=sys.stderr)
|
||||
print(f"\n{len(blocks)} total blocks", file=sys.stderr)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
if args.package:
|
||||
pkg = args.package
|
||||
|
||||
Reference in New Issue
Block a user