Implement force-directed graph view for visualizing note connections:
- Add graph data model parsing [[wiki-style links]]
- Implement Fruchterman-Reingold layout algorithm
- Create character-based canvas renderer with highlights
- Add interactive filtering by tag/folder
- Support navigation (h/j/k/l), zoom (+/-), and node selection
- New commands: :IdeaGraph, :IdeaGraphFilter
New files:
- lua/ideaDrop/ui/graph/{init,types,data,layout,renderer}.lua
Updated documentation in README.md, CHANGELOG.md, and llms.txt
171 lines
6.6 KiB
Plaintext
171 lines
6.6 KiB
Plaintext
# ideaDrop.nvim - LLM Context
|
|
|
|
> A Neovim plugin for capturing, organizing, and managing ideas with markdown support.
|
|
|
|
## Project Overview
|
|
|
|
ideaDrop.nvim is a Lua-based Neovim plugin that provides a distraction-free environment for note-taking and idea management. It features multiple view modes, a tagging system, and search capabilities.
|
|
|
|
## Tech Stack
|
|
|
|
- **Language**: Lua
|
|
- **Platform**: Neovim (requires Neovim 0.8+)
|
|
- **Dependencies**: nvim-tree/nvim-tree.lua, nvim-tree/nvim-web-devicons
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
ideaDrop.nvim/
|
|
├── lua/ideaDrop/
|
|
│ ├── init.lua # Main entry point
|
|
│ ├── core/
|
|
│ │ ├── init.lua # Core module with setup and commands
|
|
│ │ └── config.lua # Configuration management
|
|
│ ├── ui/
|
|
│ │ ├── sidebar.lua # Floating/buffer/right-side window management
|
|
│ │ ├── tree.lua # nvim-tree integration
|
|
│ │ └── graph/ # Graph visualization module
|
|
│ │ ├── init.lua # Main graph module (window, keymaps, state)
|
|
│ │ ├── types.lua # Type definitions (GraphNode, GraphEdge, etc.)
|
|
│ │ ├── data.lua # Graph data model (link parsing, filtering)
|
|
│ │ ├── layout.lua # Force-directed layout (Fruchterman-Reingold)
|
|
│ │ └── renderer.lua # Character-based canvas renderer
|
|
│ ├── features/
|
|
│ │ ├── list.lua # File listing functionality
|
|
│ │ ├── tags.lua # Tag extraction and management
|
|
│ │ └── search.lua # Fuzzy search implementation
|
|
│ └── utils/
|
|
│ ├── utils.lua # Utility functions
|
|
│ ├── keymaps.lua # Keymap setup
|
|
│ └── constants.lua # Constants and defaults
|
|
├── doc/
|
|
│ └── ideaDrop.txt # Vim help documentation
|
|
├── README.md
|
|
├── CONTRIBUTING.md
|
|
├── CHANGELOG.md
|
|
└── LICENSE
|
|
```
|
|
|
|
## Key Features
|
|
|
|
1. **Multiple View Modes**
|
|
- Floating window (`:Idea`)
|
|
- Current buffer (`:IdeaBuffer`)
|
|
- Right-side persistent buffer (`:IdeaRight`)
|
|
- Tree browser (`:IdeaTree`)
|
|
- Graph visualization (`:IdeaGraph`)
|
|
|
|
2. **Tagging System**
|
|
- Uses `#tag` format in markdown files
|
|
- Tag extraction, caching, and filtering
|
|
- Commands: `:IdeaTags`, `:IdeaAddTag`, `:IdeaRemoveTag`, `:IdeaSearchTag`
|
|
|
|
3. **Search Functionality**
|
|
- Fuzzy search through titles and content
|
|
- Commands: `:IdeaSearch`, `:IdeaSearchContent`, `:IdeaSearchTitle`
|
|
|
|
4. **Auto-save**
|
|
- Automatic saving on window close
|
|
- Uses `BufWriteCmd` autocmd for custom save handling
|
|
|
|
5. **Graph Visualization** (Obsidian-style)
|
|
- Force-directed layout using Fruchterman-Reingold algorithm
|
|
- Parses `[[Note Name]]` wiki-style links to build graph
|
|
- Visual encoding: node size = degree, colors = connectivity level
|
|
- Interactive filtering by tag/folder
|
|
- Commands: `:IdeaGraph`, `:IdeaGraphFilter`
|
|
|
|
## Configuration
|
|
|
|
```lua
|
|
require("ideaDrop").setup({
|
|
idea_dir = "/path/to/your/ideas", -- Directory for storing idea files
|
|
graph = {
|
|
animate = false, -- Enable animated layout
|
|
show_orphans = true, -- Show nodes without connections
|
|
show_labels = true, -- Show node labels by default
|
|
node_colors = nil, -- Custom colors by folder/tag
|
|
},
|
|
})
|
|
```
|
|
|
|
## Code Conventions
|
|
|
|
- Type annotations using LuaCATS/EmmyLua format (`---@param`, `---@return`, `---@class`)
|
|
- Module pattern with local `M = {}` tables
|
|
- Neovim API usage:
|
|
- `vim.bo[buf]` for buffer options
|
|
- `vim.wo[win]` for window options
|
|
- `vim.api.nvim_*` for other API calls
|
|
- Error handling with `pcall` for optional dependencies
|
|
- Notifications via `vim.notify()` with appropriate log levels
|
|
|
|
## Important Implementation Details
|
|
|
|
- **Glob patterns**: Must include `/` separator: `path .. "/**/*.md"`
|
|
- **nvim-tree**: Use API directly (`require("nvim-tree.api")`) without calling `setup()` to preserve user config
|
|
- **Buffer management**: Right-side buffer uses `buftype = "acwrite"` for custom save handling
|
|
- **File paths**: Use `vim.fn.fnameescape()` for safe path handling
|
|
|
|
## Commands Reference
|
|
|
|
| Command | Description |
|
|
|---------|-------------|
|
|
| `:Idea [name]` | Open in floating window |
|
|
| `:IdeaBuffer [name]` | Open in current buffer |
|
|
| `:IdeaRight [name]` | Open in right-side buffer |
|
|
| `:IdeaTree` | Open file tree browser |
|
|
| `:IdeaTags` | Browse tags |
|
|
| `:IdeaAddTag {tag}` | Add tag to current file |
|
|
| `:IdeaRemoveTag {tag}` | Remove tag from current file |
|
|
| `:IdeaSearchTag {tag}` | Search files by tag |
|
|
| `:IdeaSearch {query}` | Fuzzy search all |
|
|
| `:IdeaSearchContent {query}` | Search content only |
|
|
| `:IdeaSearchTitle {query}` | Search titles only |
|
|
| `:IdeaGraph [animate]` | Open graph visualization |
|
|
| `:IdeaGraphFilter {type} {value}` | Filter graph by tag/folder |
|
|
|
|
## Graph Implementation Details
|
|
|
|
### Force-Directed Layout Algorithm
|
|
|
|
The graph uses the Fruchterman-Reingold algorithm with these components:
|
|
|
|
1. **Repulsion**: All nodes repel each other (`REPULSION_STRENGTH / distance²`)
|
|
2. **Attraction**: Connected nodes attract via spring force (`ATTRACTION_STRENGTH * (distance - ideal_length)`)
|
|
3. **Gravity**: Pulls toward center, inversely proportional to degree
|
|
4. **Cooling**: Temperature decreases each iteration (`temp * COOLING_RATE`)
|
|
5. **Convergence**: Stops when max displacement < `MIN_VELOCITY` or max iterations reached
|
|
|
|
### Graph Data Model
|
|
|
|
- **Nodes**: Created from each `.md` file, stores: id, name, file_path, folder, tags, degree, position (x,y), velocity
|
|
- **Edges**: Created from `[[link]]` patterns, undirected (stored once per pair)
|
|
- **Link Resolution**: Matches links to existing files using normalized names (case-insensitive, spaces→dashes)
|
|
|
|
### Visual Encoding
|
|
|
|
- Node size: `●` for high-degree, `•` for low-degree
|
|
- Node colors: Blue (default), Purple (hubs, degree > 5), Gray (orphans), Red (selected)
|
|
- Edges: `·` character with dim highlight
|
|
|
|
### Key Constants (in `constants.lua`)
|
|
|
|
```lua
|
|
GRAPH_SETTINGS = {
|
|
LAYOUT = { REPULSION_STRENGTH = 5000, ATTRACTION_STRENGTH = 0.01, ... },
|
|
VISUAL = { NODE_CHAR = "●", EDGE_CHAR_SIMPLE = "·", ... },
|
|
WINDOW = { WIDTH_RATIO = 0.8, HEIGHT_RATIO = 0.8, ... },
|
|
}
|
|
```
|
|
|
|
## Development Notes
|
|
|
|
- Help tags file at `doc/tags` is auto-generated
|
|
- Uses `vim.ui.select()` for picker interfaces
|
|
- Tag cache invalidation via `tag_cache_dirty` flag
|
|
- Markdown files default template includes title and bullet point
|
|
- Graph uses character-based canvas with highlight groups for colors
|
|
- Graph layout runs synchronously by default, optionally animated with `vim.defer_fn`
|
|
- Graph filtering re-runs partial layout (fewer iterations) for smooth transitions
|