Skip to content

File Import and Editing

sysid edited this page Oct 12, 2025 · 2 revisions

File Import and Smart Editing

bkmr can import files with structured metadata and provides intelligent editing that automatically detects whether to edit the source file or database content.

Overview

The file import system bridges the gap between file-based workflows and bkmr's database:

  • Import files with metadata - Use frontmatter in your scripts and documents
  • Track changes automatically - SHA-256 hashing detects when files change
  • Portable paths - Base path configuration works across different machines
  • Smart editing - Automatically edits source files when appropriate

This means you can keep your scripts and documents as files while enjoying bkmr's powerful search and organization.

Supported File Types

bkmr recognizes these file types and automatically assigns appropriate system tags:

File Extension Detected Type System Tag 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

Frontmatter Formats

Frontmatter provides metadata about your files. bkmr supports two formats:

YAML Frontmatter (Preferred for Markdown)

---
name: "Database Backup Script"
tags: ["database", "backup", "automation"]
type: "_shell_"
---
#!/bin/bash
# Actual script content below
pg_dump mydb | gzip > backup_$(date +%Y%m%d).sql.gz

Benefits:

  • Clean, standard format
  • Lists for tags
  • Works in any file type

Hash-Style Frontmatter (Better for Scripts)

#!/bin/bash
# name: Database Backup Script
# tags: database, backup, automation
# type: _shell_
# description: Daily backup with compression

# Script starts here
pg_dump mydb | gzip > backup_$(date +%Y%m%d).sql.gz

Benefits:

  • Native comments (scripts stay executable)
  • No special delimiters needed
  • Reads naturally in the file

Metadata Fields

Field Required Description Example
name ✅ Yes Title/name of the bookmark "Backup Script"
tags ❌ No Comma-separated or list database,backup or ["database", "backup"]
type ❌ No System tag override _shell_, _md_, _snip_
description ❌ No Additional context "Daily backup with rotation"

Note: System tags like _shell_ are usually auto-detected from file extension, but you can override if needed.

Base Path Configuration

Base paths make your file references portable across different machines and environments.

Why Use Base Paths?

Without base paths:

# Stored as absolute path - breaks on different machines
/Users/john/scripts/backup.sh  # ❌ Won't work on another computer

With base paths:

# Stored as variable - portable across machines
$SCRIPTS_HOME/backup.sh  # ✅ Works anywhere with config

Configuration

Add base paths to ~/.config/bkmr/config.toml:

[base_paths]
SCRIPTS_HOME = "$HOME/scripts"
DOCS_HOME = "$HOME/documents"
WORK_SCRIPTS = "/work/automation/scripts"
PROJECT_NOTES = "$HOME/projects/documentation"
DOTFILES = "$HOME/.config"

Environment variable support:

  • $HOME - User home directory
  • $USER - Current username
  • $PWD - Current working directory
  • Any custom environment variables

Validation

Base paths are validated before import:

# If SCRIPTS_HOME doesn't exist or isn't configured:
$ bkmr import-files backup.sh --base-path SCRIPTS_HOME
Error: Base path 'SCRIPTS_HOME' not found in configuration
Add it to ~/.config/bkmr/config.toml under [base_paths]

Importing Files

Basic Import

# Import single file
bkmr import-files ~/scripts/backup.sh

# Import multiple files
bkmr import-files ~/scripts/backup.sh ~/scripts/deploy.sh

# Import entire directory (recursive)
bkmr import-files ~/scripts/

# Import with .gitignore support
bkmr import-files ~/scripts/  # Automatically respects .gitignore

Import with Base Paths

# Import using base path (stores as $SCRIPTS_HOME/backup.sh)
bkmr import-files scripts/backup.sh --base-path SCRIPTS_HOME

# Import directory with base path
bkmr import-files scripts/ --base-path SCRIPTS_HOME

# Multiple directories with different base paths
bkmr import-files ~/scripts/ --base-path SCRIPTS_HOME
bkmr import-files ~/docs/ --base-path DOCS_HOME

Update Existing Bookmarks

The --update flag detects and updates changed files:

# Update when content changes
bkmr import-files scripts/ --base-path SCRIPTS_HOME --update

# What gets detected:
# ✅ Content changes (via SHA-256 hash)
# ✅ Metadata changes (name, tags, type in frontmatter)
# ✅ Path changes (file moved to different directory)

Example output:

Content changed: backup-database.sh
Metadata changed: deploy-app.sh (tags updated)
Path changed: monitoring.sh (moved from scripts/old/ to scripts/)
Updated 3 bookmarks

Delete Missing Files

Remove bookmarks whose source files no longer exist:

# Delete bookmarks for deleted/moved files
bkmr import-files scripts/ --delete-missing

# Safe with dry-run first
bkmr import-files scripts/ --delete-missing --dry-run

Dry Run (Preview Changes)

Always test with --dry-run before making changes:

# Preview what would happen
bkmr import-files scripts/ --base-path SCRIPTS_HOME --dry-run --update

# Example output:
# Would add: new-script.sh
# Would update: backup.sh (content changed)
# Would skip: deploy.sh (unchanged)

Smart Editing System

The smart editing system automatically detects the best way to edit each bookmark.

How It Works

When you run bkmr edit <id>:

1. Check bookmark metadata
   ├─ Has file_path? → File-imported bookmark
   │  ├─ Source file exists? → Open in $EDITOR
   │  └─ Source file missing? → Fall back to database editor
   └─ No file_path? → Regular bookmark → Database editor

Editing File-Imported Bookmarks

# Smart editing (automatically opens source file)
bkmr edit 123

# What happens:
# 1. Opens /path/to/source/file.sh in $EDITOR
# 2. You edit the file and save
# 3. On next access, bkmr re-reads the file
# 4. Metadata from frontmatter syncs to database

Benefits:

  • Edit files in their natural environment
  • Keep files version-controlled (git, etc.)
  • Metadata stays in sync automatically
  • Use your favorite editor's full features

Editing Regular Bookmarks

# For bookmarks not imported from files
bkmr edit 456

# Opens interactive database editor:
=== ID ===
456
=== URL ===
SELECT * FROM users WHERE active = true
=== TITLE ===
Active Users Query
=== TAGS ===
sql,_snip_
=== COMMENTS ===
Production database query

Force Database Editing

Sometimes you want to edit database content even for file-imported bookmarks:

# Force database editor (ignores source file)
bkmr edit 123 --force-db

# Use cases:
# - Source file is on unmounted drive
# - Want to make temporary change without affecting source
# - Testing different content

Advanced Features

Change Detection

bkmr tracks three types of changes:

1. Content Changes (SHA-256 hash):

# File content modified
echo "new line" >> backup.sh
bkmr import-files scripts/ --update
# Output: Content changed: backup.sh

2. Metadata Changes (frontmatter):

# Changed tags in frontmatter from "backup" to "backup,production"
# name: Database Backup
# tags: backup,production  # <-- changed
bkmr import-files scripts/ --update
# Output: Metadata changed: backup.sh

3. Path Changes (file moved):

# File moved to different directory
mv scripts/backup.sh scripts/database/backup.sh
bkmr import-files scripts/ --update
# Output: Path changed: backup.sh

Path Resolution

bkmr resolves paths intelligently:

# Base path variable expansion
$SCRIPTS_HOME/backup.sh → /home/user/scripts/backup.sh

# Environment variable expansion
$HOME/docs/notes.md → /home/user/docs/notes.md

# Tilde expansion
~/scripts/deploy.sh → /home/user/scripts/deploy.sh

# Relative paths (from import directory)
scripts/backup.sh → /current/working/dir/scripts/backup.sh

Incremental Updates

Only changed files are processed:

# First import
bkmr import-files scripts/  # Imports 10 files

# Change one file
echo "update" >> scripts/backup.sh

# Re-import (only processes changed file)
bkmr import-files scripts/ --update
# Processing: 1/10 files (9 unchanged, 1 updated)

Integration with bkmr Features

Search and Discovery

File-imported bookmarks are fully searchable:

# Full-text search includes file content
bkmr search "database backup"

# Tag filtering works with frontmatter tags
bkmr search -t backup,production

# System tags auto-assigned
bkmr search -t _shell_  # Finds all imported shell scripts

Fuzzy Finder

Smart editing works in fuzzy finder:

bkmr search --fzf

# Keyboard shortcuts:
# CTRL-E → Smart editing (opens source file for imported bookmarks)
# CTRL-D → Delete (also removes from import tracking)

Content-Aware Actions

File-imported bookmarks use appropriate actions:

# Shell scripts execute with interactive editing
bkmr open <shell-script-id>

# Markdown files render in browser
bkmr open <markdown-id>

# Works with arguments too
bkmr open <shell-script-id> --no-edit -- arg1 arg2

Complete Workflow Example

1. Setup Configuration

# Generate config
bkmr --generate-config > ~/.config/bkmr/config.toml

# Edit to add base paths
[base_paths]
SCRIPTS_HOME = "$HOME/scripts"

2. Create Scripts with Frontmatter

# Create script with metadata
cat > ~/scripts/backup-db.sh << 'EOF'
#!/bin/bash
# name: Database Backup
# tags: database,backup,production
# type: _shell_
# description: Daily PostgreSQL backup with rotation

BACKUP_DIR="/backups"
DATE=$(date +%Y%m%d)

pg_dump mydb | gzip > "$BACKUP_DIR/backup_$DATE.sql.gz"

# Keep only last 7 days
find "$BACKUP_DIR" -name "backup_*.sql.gz" -mtime +7 -delete
EOF

chmod +x ~/scripts/backup-db.sh

3. Import Scripts

# Initial import
bkmr import-files ~/scripts/ --base-path SCRIPTS_HOME

# Output:
# Imported: backup-db.sh (shell script)
# Added 1 bookmark

4. Search and Edit

# Find the script
bkmr search --fzf -t backup

# Select script and press CTRL-E
# Opens ~/scripts/backup-db.sh in your $EDITOR

# Make changes and save
# Changes automatically reflected in bkmr

5. Update After Changes

# After editing files directly
bkmr import-files ~/scripts/ --base-path SCRIPTS_HOME --update

# Only changed files are processed

Troubleshooting

Source File Not Found

$ bkmr edit 123
Source file does not exist: $SCRIPTS_HOME/old-script.sh
Falling back to database content editing...

Solutions:

  • Check if file was moved or deleted
  • Update base path in config.toml
  • Re-import with correct paths
  • Use --force-db to edit database content

Base Path Not Configured

$ bkmr import-files scripts/file.sh --base-path SCRIPTS_HOME
Error: Base path 'SCRIPTS_HOME' not found in configuration

Solution: Add to ~/.config/bkmr/config.toml:

[base_paths]
SCRIPTS_HOME = "/path/to/scripts"

Editor Not Found

$ bkmr edit 123
Error: EDITOR environment variable not set

Solution:

export EDITOR=vim  # or nano, code, emacs, etc.
# Add to ~/.bashrc or ~/.zshrc for persistence

Frontmatter Parse Errors

$ bkmr import-files script.sh
Warning: Invalid frontmatter in script.sh - using filename as title

Solution: Check frontmatter syntax:

  • YAML: proper --- delimiters
  • Hash-style: proper # key: value format
  • Required field: name

Best Practices

1. Use descriptive names in frontmatter:

# Good
# name: Backup Production Database

# Avoid
# name: backup.sh

2. Tag consistently:

# Good - hierarchical tags
# tags: production,database,backup,postgresql

# Avoid - vague tags
# tags: script,important,work

3. Keep frontmatter minimal:

# Only include necessary metadata
# name: Deploy to Staging
# tags: deploy,staging

4. Regular updates:

# Daily or weekly
bkmr import-files ~/scripts/ --base-path SCRIPTS_HOME --update

# Or create alias
alias bkmr-sync='bkmr import-files ~/scripts/ --base-path SCRIPTS_HOME --update'

5. Backup before bulk operations:

# Before large imports or updates
cp ~/.config/bkmr/bkmr.db ~/.config/bkmr/bkmr_backup.db

# Then proceed
bkmr import-files large-directory/ --update --delete-missing

Related Pages

Clone this wiki locally