Skip to content

Content Types

sysid edited this page Apr 8, 2026 · 6 revisions

Content Types and Actions

bkmr handles different content types with intelligent, context-aware actions. When you run bkmr open, the system tag determines what happens.

Content Type Overview

Type System Tag Action Use Case
URLs (none) Open in browser Web bookmarks, documentation links
Code Snippets _snip_ Copy to clipboard Reusable code fragments
Shell Scripts _shell_ Interactive edit + execute Automation, commands
Markdown _md_ Render in browser with TOC Documentation, notes
Environment Variables _env_ Print for sourcing Environment setup
Text Documents _imported_ Copy to clipboard Plain text content
Agent Memory _mem_ Display content to stdout AI agent memory bookmarks

URLs and Web Resources

Default Action: Open in default browser

# Simple URL
bkmr add https://github.com/sysid/bkmr rust,cli

# Dynamic URL with template interpolation
bkmr add "https://api.example.com/daily/{{ current_date | strftime('%Y-%m-%d') }}" api,reports

Automatic metadata extraction (title, description). Supports any URL scheme.

Custom Openers

Override the default open behavior per bookmark:

# Add with custom opener
bkmr add https://docs.rust-lang.org rust,docs --open-with "firefox"

# Update existing bookmark
bkmr update 42 --open-with "chromium --profile-directory=Work"

# Clear custom opener
bkmr update 42 --open-with ""

The opener command is executed via shell with the URL as $1. Supports path expansion (~, $HOME). Only applies to URLs and local files (not _md_, _shell_, _snip_, _env_).

Code Snippets (_snip_)

Default Action: Copy to clipboard

# JavaScript snippet
bkmr add "const user = { name: 'John', role: 'admin' };" javascript --type snip

# SQL query
bkmr add "SELECT * FROM users WHERE created_at > NOW() - INTERVAL 7 DAY;" sql --type snip

Snippets are accessible directly in your editor via the built-in LSP server. See Editor Integration.

Shell Scripts (_shell_)

Default Action: Interactive editor then execute

# Add a shell script (editor opens for content)
bkmr add "" deploy,production,_shell_ --title "deploy-production"

# Or with inline content
bkmr add "#!/bin/bash\nssh server 'cd /app && git pull && systemctl restart app'" deploy --type shell

Execution Modes

Interactive (default): Presents editor before execution — review, modify, add parameters:

bkmr open 123   # Opens editor with script content

Direct execution: Skip the editor:

bkmr open --no-edit 123

With arguments: Pass arguments via -- separator:

bkmr open --no-edit 123 -- --env production --dry-run
# In your script: $1=--env, $2=production, $3=--dry-run

Interactive Editor Features

  • Pre-filled with script content
  • Vim or Emacs bindings (auto-detected from shell config)
  • Command history saved to ~/.config/bkmr/shell_history.txt
  • Press Enter to execute, Ctrl-C to cancel

Shell Function Stubs

Transform bookmarked scripts into callable shell functions:

# View all generated function stubs
bkmr search --shell-stubs

# Example output:
# backup-database() { bkmr open --no-edit 123 -- "$@"; }
# export -f backup-database
# deploy-app() { bkmr open --no-edit 124 -- "$@"; }
# export -f deploy-app

Dynamic loading (always fresh, recommended):

# Add to ~/.bashrc or ~/.zshrc
source <(bkmr search --shell-stubs)

Static caching (faster startup):

bkmr search --shell-stubs > ~/.config/bkmr/shell-functions.sh
source ~/.config/bkmr/shell-functions.sh

Selective loading by tag:

source <(bkmr search --tags _shell_,production --shell-stubs)

Shell History Integration

When bkmr executes a script, the command doesn't appear in shell history (child processes can't modify parent shell history). The --stdout flag solves this:

Command-line buffer (recommended) — places command on your prompt for review:

# Bash: bind to Ctrl+B
_bkmr_widget() {
    local raw output
    raw=$(bkmr search --stdout --fzf --fzf-style enhanced \
        --Ntags-prefix _imported_,prompt --ntags-prefix _snip_,_shell_ 2>/dev/null) || return
    output=$(printf '%s' "$raw" | perl -pe 's/\e\[[0-9;?]*[ -\/]*[@-~]//g')
    [[ -n $output ]] || return
    READLINE_LINE=$output
    READLINE_POINT=${#READLINE_LINE}
}
bind -x '"\C-b": _bkmr_widget'

# Zsh: bind to Ctrl+B
_bkmr_widget() {
    local output
    output=$(bkmr search --fzf --stdout 2>/dev/null)
    if [[ -n "$output" ]]; then LBUFFER="$output"; zle redisplay; fi
}
zle -N _bkmr_widget
bindkey '^b' _bkmr_widget

Shell Script Configuration

# Disable interactive mode globally
export BKMR_SHELL_INTERACTIVE=false

# Or in ~/.config/bkmr/config.toml
[shell_opts]
interactive = false

Markdown Documents (_md_)

Default Action: Render HTML with interactive Table of Contents and open in browser

# Inline markdown
bkmr add "# Project Notes\n\n## Tasks\n- [ ] Complete docs" notes --type md

# Reference to markdown file
bkmr add "~/documents/project-specs.md" specifications --type md

Features:

  • Interactive TOC sidebar with hierarchical navigation (H1-H3)
  • Syntax highlighting, MathJax for LaTeX formulas
  • Dark mode support (inherits system theme)
  • No template processing (avoids conflicts with markdown {%} syntax)

Direct File Viewing

View markdown files without storing as bookmarks:

bkmr open --file README.md
bkmr open --file ~/docs/project-notes.md

Environment Variables (_env_)

Default Action: Print to stdout for shell sourcing

# Add environment variables
bkmr add "export DB_URL=postgres://localhost/dev\nexport API_KEY=dev_key" dev-env --type env

# Source them
eval "$(bkmr open 123)"
source <(bkmr open 123)

Supports template interpolation for dynamic values (timestamps, git branch, etc.).

Text Documents (_imported_)

Default Action: Copy to clipboard

Primarily assigned automatically during file import. Can also be set manually:

bkmr add "Important reference content here" reference --type text

Agent Memory (_mem_)

Default Action: Display content to stdout (no browser, no clipboard)

# Store an agent memory
bkmr add "The auth service uses JWT with 24h expiry" fact,auth \
  --title "Auth token config" -t mem --no-web

# Query memories
bkmr hsearch "authentication" -t _mem_ --json --np

# Open prints to stdout (machine-readable, no side effects)
bkmr open <id>

For comprehensive patterns including memory taxonomy, deduplication, and session workflows, see Agent Integration.

File Import and Smart Editing

Keep files on disk (for git, your editor, direct execution) while making them searchable and manageable in bkmr.

How It Works

bkmr edit <id>:
  file_path NOT NULL? → Open source file in $EDITOR, sync changes back
  file_path NULL?     → Open database content in template editor

Frontmatter Requirement

Files must have frontmatter with at least a name: field:

YAML frontmatter:

---
name: "Database Backup Script"
tags: ["database", "backup"]
type: "_shell_"
---
#!/bin/bash
pg_dump mydb > backup.sql

Hash-style frontmatter (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

File Type Auto-Detection

Extension System Tag Default Action
.sh, .py _shell_ Interactive execution
.md _md_ Render in browser
Others _imported_ Copy to clipboard

Override with the type: frontmatter field.

Import Commands

# Single file or directory (recursive, respects .gitignore)
bkmr import-files ~/scripts/backup.sh
bkmr import-files ~/scripts/

# With base paths for portability across machines
bkmr import-files ~/scripts/ --base-path SCRIPTS_HOME

# Update changed files (detects content/metadata/path changes via SHA-256)
bkmr import-files ~/scripts/ --base-path SCRIPTS_HOME --update

# Preview changes
bkmr import-files ~/scripts/ --base-path SCRIPTS_HOME --dry-run --update

# Remove bookmarks for deleted source files
bkmr import-files ~/scripts/ --delete-missing

Configure base paths in ~/.config/bkmr/config.toml:

[base_paths]
SCRIPTS_HOME = "$HOME/scripts"
DOCS_HOME = "$HOME/documents"

File-imported bookmarks are visually distinct in FZF (file path + timestamp shown in magenta).

File References

Any content type can reference local files:

bkmr add "~/docs/api-guide.md" documentation --type md
bkmr add "~/scripts/deploy.sh" automation --type shell

File content is loaded automatically. Path resolution supports ~ and environment variables. Embeddings update when files change.

Template Interpolation

Most content types support Jinja2-style templates (except markdown):

{{ current_date | strftime('%Y-%m-%d') }}    # Date formatting
{{ env('HOME') }}                             # Environment variable
{{ "whoami" | shell }}                       # Shell command output

For complete template documentation, see Template Interpolation.

Related Pages

Clone this wiki locally