Bug fixes for mac

This commit is contained in:
Tris Forster 2025-12-03 23:00:41 +11:00
parent f6397185c4
commit 50e9323b4b
4 changed files with 42 additions and 26 deletions

View File

@ -22,7 +22,7 @@ def main():
try: try:
f(**options) f(**options)
except RuntimeError as e: except RuntimeError as e:
parser.exit(e) parser.exit(1, str(e))
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -5,7 +5,15 @@ from pyn import notes
import sys import sys
import os import os
group = parser.add_subparsers(help="available commands") group = parser.add_subparsers(help="available note commands")
def cmd_config(config):
print(config)
show_config = group.add_parser("config", help="show config")
show_config.set_defaults(func=cmd_config)
### Add a note ### Add a note
@ -16,7 +24,7 @@ def cmd_add_note(config, title, notebook):
body = "" if sys.stdin.isatty() else sys.stdin.read() body = "" if sys.stdin.isatty() else sys.stdin.read()
notes.append_template(config, filename, "note", title=title, body=body) notes.append_template(filename, "note", title=title, body=body)
if not body: if not body:
notes.edit_file(config, filename) notes.edit_file(config, filename)

View File

@ -7,7 +7,7 @@ from pyn.config import Config
from datetime import datetime from datetime import datetime
from shutil import copyfileobj from shutil import copyfileobj
from collections import namedtuple from collections import namedtuple
from typing import Any from typing import Any, Generator
Entry = namedtuple("Entry", ("notebook", "filename")) Entry = namedtuple("Entry", ("notebook", "filename"))
SearchResult = namedtuple("SearchResult", ("filename", "line_number", "snippet")) SearchResult = namedtuple("SearchResult", ("filename", "line_number", "snippet"))
@ -15,12 +15,13 @@ SearchResult = namedtuple("SearchResult", ("filename", "line_number", "snippet")
NOTE_HEADING = """--- NOTE_HEADING = """---
date: {date} date: {date}
notebook: {notebook} notebook: {notebook}
---""" ---
"""
TEMPLATES = { TEMPLATES = {
"heading": NOTE_HEADING, "heading": NOTE_HEADING,
"note": "\n\n# {title}\n\n{body}\n---", "note": "\n# {title}\n\n{body}\n---\n",
"todo": "\n* [ ] {item}", "todo": "* [ ] {item}\n",
} }
@ -44,7 +45,6 @@ def get_note_filename(
notebook_path.mkdir(parents=True, exist_ok=True) notebook_path.mkdir(parents=True, exist_ok=True)
note_path.touch() note_path.touch()
append_template( append_template(
config,
note_path, note_path,
"heading", "heading",
date=now.isoformat(timespec="seconds"), date=now.isoformat(timespec="seconds"),
@ -54,9 +54,7 @@ def get_note_filename(
return note_path return note_path
def append_template( def append_template(filename: pathlib.Path, template: str, **context: Any) -> None:
config: Config, filename: pathlib.Path, template: str, **context: dict[str, Any]
) -> None:
rendered = TEMPLATES[template].format(**context) rendered = TEMPLATES[template].format(**context)
with open(filename, "a") as f: with open(filename, "a") as f:
f.write(rendered) f.write(rendered)
@ -64,19 +62,26 @@ def append_template(
def edit_file(config: Config, filename: pathlib.Path) -> None: def edit_file(config: Config, filename: pathlib.Path) -> None:
cmd = config.editor.copy() cmd = config.editor.copy()
cmd.append(filename) cmd.append(str(filename))
subprocess.check_call(cmd) subprocess.check_call(cmd)
def get_file_list(config: Config, notebook: str = None) -> list[pathlib.Path]: def get_file_list(
config: Config, notebook: str | None = None, show_hidden: bool = False
) -> Generator[pathlib.Path]:
root = config.directory / notebook if notebook else config.directory root = config.directory / notebook if notebook else config.directory
for d, _, files in root.walk(): for d, dirs, files in root.walk():
if not show_hidden:
dirs[:] = [d for d in dirs if d[0] != "."]
for filename in files: for filename in files:
yield d / filename yield d / filename
def search_filenames(config: Config, title: str, notebook: str = None) -> pathlib.Path: def search_filenames(
config: Config, title: str, notebook: str | None = None
) -> pathlib.Path:
root = config.directory / notebook if notebook else config.directory root = config.directory / notebook if notebook else config.directory
cmd = ["fzf", "-1", "-i"] cmd = ["fzf", "-1", "-i"]
@ -97,7 +102,7 @@ def file_entry(config: Config, filepath: pathlib.Path) -> Entry:
return Entry(str(relative.parent), relative.name) return Entry(str(relative.parent), relative.name)
def cat_files(*filenames: list[pathlib.Path]) -> None: def cat_files(*filenames: pathlib.Path) -> None:
for filename in filenames: for filename in filenames:
with open(filename, "r") as f: with open(filename, "r") as f:
copyfileobj(f, sys.stdout) copyfileobj(f, sys.stdout)
@ -106,10 +111,10 @@ def cat_files(*filenames: list[pathlib.Path]) -> None:
def search_contents( def search_contents(
config: Config, config: Config,
query: str, query: str,
notebook: str = None, notebook: str | None = None,
file_matcher: str = None, file_matcher: str = "*.md",
full_line: bool = False, full_line: bool = False,
) -> list[SearchResult]: ) -> Generator[SearchResult]:
root = config.directory / notebook if notebook else config.directory root = config.directory / notebook if notebook else config.directory
cmd = ["grep", "-rFn", query, str(root)] cmd = ["grep", "-rFn", query, str(root)]

View File

@ -1,8 +1,8 @@
from pyn.common import parser, logger
from pyn.config import Config from pyn.config import Config
from pyn import notes from pyn import notes
from pyn.commands import group as parent_group from pyn.commands import group as parent_group
from shutil import get_terminal_size from shutil import get_terminal_size
import sys
p = parent_group.add_parser("todo", help="manipulate todo items") p = parent_group.add_parser("todo", help="manipulate todo items")
@ -12,9 +12,9 @@ group = p.add_subparsers()
def cmd_add_todo(config: Config, item: list[str], notebook: str, create: bool) -> None: def cmd_add_todo(config: Config, item: list[str], notebook: str, create: bool) -> None:
item = " ".join(item) item_str = " ".join(item)
filename = notes.get_note_filename(config, "todo", notebook) filename = notes.get_note_filename(config, "todo", notebook)
notes.append_template(config, filename, "todo", item=item) notes.append_template(filename, "todo", item=item_str)
add_todo = group.add_parser("add", aliases=["a"]) add_todo = group.add_parser("add", aliases=["a"])
@ -29,7 +29,6 @@ add_todo.set_defaults(func=cmd_add_todo)
def cmd_list_pending(config: Config, notebook: str): def cmd_list_pending(config: Config, notebook: str):
nb = None nb = None
cols, _ = get_terminal_size() cols, _ = get_terminal_size()
fmt = "{snippet:" + str(cols - 20) + "s} {name}"
for result in notes.search_contents( for result in notes.search_contents(
config, "* [ ]", notebook, file_matcher="*-todo.md" config, "* [ ]", notebook, file_matcher="*-todo.md"
): ):
@ -37,7 +36,11 @@ def cmd_list_pending(config: Config, notebook: str):
if entry.notebook != nb: if entry.notebook != nb:
nb = entry.notebook nb = entry.notebook
print(f"\nNotebook: {entry.notebook}") print(f"\nNotebook: {entry.notebook}")
print(fmt.format(snippet=result.snippet, name=result.filename.name)) name = result.filename.name
sys.stdout.write(result.snippet)
sys.stdout.write(" " * (cols - len(result.snippet) - len(name)))
sys.stdout.write(name)
sys.stdout.write("\n")
pending_todo = group.add_parser("pending", aliases="p", help="list pending tasks") pending_todo = group.add_parser("pending", aliases="p", help="list pending tasks")
@ -56,7 +59,7 @@ def cmd_mark_complete(
if reverse: if reverse:
checked, unchecked = unchecked, checked checked, unchecked = unchecked, checked
item = " ".join(item) item_str = " ".join(item)
results = list( results = list(
notes.search_contents( notes.search_contents(
config, f"* [{unchecked}] {item}", notebook, full_line=True config, f"* [{unchecked}] {item}", notebook, full_line=True
@ -69,7 +72,7 @@ def cmd_mark_complete(
if not multiple and len(results) > 1: if not multiple and len(results) > 1:
raise RuntimeError("Multiple items matched - use --multiple to allow update") raise RuntimeError("Multiple items matched - use --multiple to allow update")
update = f"* [{checked}] {item}" update = f"* [{checked}] {item_str}"
for result in results: for result in results:
entry = notes.file_entry(config, result.filename) entry = notes.file_entry(config, result.filename)
with open(result.filename, "r") as f: with open(result.filename, "r") as f: