-
Notifications
You must be signed in to change notification settings - Fork 10
File Import and Editing
You have scripts, documents, and snippets scattered across your filesystem. You want to:
- Keep them as files — for version control (git), your favorite editor, direct execution
- But also have bkmr's powerful search, tagging, fuzzy finder, and organization
File Import gives you both. Your files stay exactly where they are. bkmr indexes their content and metadata, making them searchable and manageable alongside your other bookmarks. When you edit, bkmr automatically opens the source file — not a database copy.
This is the critical distinction:
bkmr import-files ~/scripts/backup.sh --base-path SCRIPTS_HOME| Aspect | Behavior |
|---|---|
| Content storage | File content copied into database |
file_path field |
Set to source file location |
| Smart editing |
bkmr edit opens the source file in $EDITOR
|
| Sync | Edits to source file can be synced back to database |
| Requirements | Frontmatter with at least name: field |
| Visual indicator | FZF shows file path + timestamp in magenta |
bkmr add "file:///Users/me/scripts/backup.sh" scripts --title "Backup Script"| Aspect | Behavior |
|---|---|
| Content storage | Only the URL/path is stored |
file_path field |
NULL — not tracked as file-imported |
| Smart editing |
bkmr edit opens database template editor |
| Sync | None — file and bookmark are independent |
| Requirements | None — just a URL |
| Visual indicator | No file path shown in FZF |
| Use Case | Recommendation |
|---|---|
| Scripts you actively develop and want searchable | File Import |
| Documentation/notes you edit frequently | File Import |
| Quick reference to a file location | Regular bookmark with file:// URL |
| External URLs, code snippets, commands | Regular bookmark |
The smart edit mechanism is simple. When you run bkmr edit <id>:
Check: Is bookmark.file_path NOT NULL?
├─ YES (file-imported) → Open source file in $EDITOR, sync changes back
└─ NO (regular) → Open database content in template editor
Database schema fields for file tracking:
file_path TEXT NULL -- Source file path (NULL = regular bookmark)
file_mtime INT NULL -- File modification timestamp
file_hash TEXT NULL -- SHA-256 hash for change detectionA bookmark is considered "file-imported" if and only if file_path IS NOT NULL.
File-imported bookmarks are visually distinct in the fuzzy finder:
3164: api-reference [_md_,api,documentation] /path/to/api-reference.md (2025-06-27 19:30:30)
3234: Explain Rust Modules [_md_,doc,rs]
- Bookmark 3164: Shows file path and modification time in magenta — this is file-imported
-
Bookmark 3234: No file info — this is a regular bookmark (even though it has
_md_tag)
For a file to be imported, it must have frontmatter with at least a name: field:
YAML frontmatter (works in any file):
---
name: "Database Backup Script"
tags: ["database", "backup"]
type: "_shell_"
---
#!/bin/bash
pg_dump mydb > backup.sqlHash-style frontmatter (better for scripts — stays executable):
#!/bin/bash
# name: Database Backup Script
# tags: database, backup
# type: _shell_
pg_dump mydb > backup.sql| Field | Required | Description |
|---|---|---|
name |
Yes | Title for the bookmark |
tags |
No | Comma-separated or YAML list |
type |
No | System tag override (_shell_, _md_, _snip_) |
description |
No | Additional context |
Without frontmatter: The file will be skipped during import with a warning.
bkmr auto-detects file types and assigns appropriate system tags:
| Extension | Detected Type | System Tag | Default Action |
|---|---|---|---|
.sh |
Shell script | _shell_ |
Interactive execution |
.py |
Python script | _shell_ |
Interactive execution |
.md |
Markdown | _md_ |
Render in browser |
| Others | Text | _imported_ |
Copy to clipboard |
You can override the auto-detected type using the type: frontmatter field.
# Single file
bkmr import-files ~/scripts/backup.sh
# Multiple files
bkmr import-files ~/scripts/backup.sh ~/scripts/deploy.sh
# Entire directory (recursive, respects .gitignore)
bkmr import-files ~/scripts/Base paths make your imports portable across machines:
# Import with base path variable
bkmr import-files ~/scripts/backup.sh --base-path SCRIPTS_HOME
# Stored as: $SCRIPTS_HOME/backup.sh (not absolute path)Configure base paths in ~/.config/bkmr/config.toml:
[base_paths]
SCRIPTS_HOME = "$HOME/scripts"
DOCS_HOME = "$HOME/documents"# Detect and update changed files
bkmr import-files ~/scripts/ --base-path SCRIPTS_HOME --update
# Detects:
# - Content changes (SHA-256 hash comparison)
# - Metadata changes (frontmatter name, tags, type)
# - Path changes (file moved to different directory)# See what would happen without making changes
bkmr import-files ~/scripts/ --base-path SCRIPTS_HOME --dry-run --update# Delete bookmarks whose source files no longer exist
bkmr import-files ~/scripts/ --delete-missingbkmr edit 3164
# Output:
# Editing source file: /Users/me/scripts/backup.sh
# [Opens in $EDITOR]
# File edited successfully, syncing changes to database...
# Successfully synced changes to databaseWhat happens:
- Resolves
file_path(expands base path variables like$SCRIPTS_HOME) - Opens the source file in
$EDITOR - Waits for you to save and close
- Re-parses frontmatter and content
- Updates database with any changes
bkmr edit 3234
# Opens template editor with database content:
# === ID ===
# 3234
# === URL ===
# [content here]
# === TITLE ===
# Explain Rust Modules
# ...Even for file-imported bookmarks, you can force database editing:
bkmr edit 3164 --force-db
# Opens database template editor instead of source fileUse cases:
- Source file is on unmounted drive
- Want temporary changes without affecting source
- Source file was deleted but you want to keep/edit the bookmark
File-imported bookmarks are fully searchable:
# Full-text search includes file content
bkmr search "database backup"
# Tag filtering includes frontmatter tags
bkmr search -t backup,production
# Find all imported shell scripts
bkmr search -t _shell_bkmr search --fzf
# CTRL-E → Smart edit (opens source file for imported bookmarks)
# CTRL-D → Delete# Shell scripts: interactive execution
bkmr open <shell-script-id>
# With arguments
bkmr open <shell-script-id> --no-edit -- arg1 arg2
# Markdown: render in browser
bkmr open <markdown-id>bkmr --generate-config > ~/.config/bkmr/config.toml
# Edit to add:
# [base_paths]
# SCRIPTS_HOME = "$HOME/scripts"cat > ~/scripts/backup-db.sh << 'EOF'
#!/bin/bash
# name: Database Backup
# tags: database,backup,production
# type: _shell_
pg_dump mydb | gzip > backup_$(date +%Y%m%d).sql.gz
EOF
chmod +x ~/scripts/backup-db.shbkmr import-files ~/scripts/ --base-path SCRIPTS_HOME
# Output: Imported: backup-db.sh# Find it
bkmr search backup --fzf
# Edit (opens ~/scripts/backup-db.sh)
bkmr edit <id>
# Execute
bkmr open <id># After editing files directly
bkmr import-files ~/scripts/ --base-path SCRIPTS_HOME --update$ bkmr edit 123
Source file does not exist: $SCRIPTS_HOME/old-script.sh
Falling back to database content editing...Solutions: Check if file moved/deleted, update base path config, use --force-db
$ bkmr import-files script.sh
Warning: Invalid frontmatter in script.sh - skippingSolution: Add frontmatter with at least name: field
$ bkmr import-files scripts/ --base-path SCRIPTS_HOME
Error: Base path 'SCRIPTS_HOME' not found in configurationSolution: Add to ~/.config/bkmr/config.toml under [base_paths]
- Use base paths for portability across machines
-
Minimal frontmatter — just
name:and relevanttags: -
Regular sync — run
bkmr import-files --updateperiodically or create an alias - Descriptive names — "Backup Production Database" not "backup.sh"
-
Consistent tagging — use hierarchical tags like
production,database,backup
- Content Types — System tags and actions
- Configuration — Base path setup
- Shell Scripts — Working with imported scripts
- Search and Discovery — Finding imported files
bkmr Documentation