{"id":31333366,"url":"https://github.com/jasonrdsouza/scratchpad","last_synced_at":"2026-05-15T22:33:55.509Z","repository":{"id":305392370,"uuid":"1022770072","full_name":"jasonrdsouza/scratchpad","owner":"jasonrdsouza","description":"Browser based, web first, vim backed, AI assisted scratchpad for quick notes, brainstorming, and brain dumping.","archived":false,"fork":false,"pushed_at":"2025-08-13T01:59:26.000Z","size":102,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-26T01:54:07.047Z","etag":null,"topics":["vim"],"latest_commit_sha":null,"homepage":"https://scratch.dsouza.io/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jasonrdsouza.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-19T19:35:46.000Z","updated_at":"2025-08-13T01:52:20.000Z","dependencies_parsed_at":"2025-07-19T22:31:51.650Z","dependency_job_id":"3f83c352-fd00-4b2f-8d57-e88f7ab19351","html_url":"https://github.com/jasonrdsouza/scratchpad","commit_stats":null,"previous_names":["jasonrdsouza/scratchpad"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/jasonrdsouza/scratchpad","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jasonrdsouza%2Fscratchpad","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jasonrdsouza%2Fscratchpad/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jasonrdsouza%2Fscratchpad/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jasonrdsouza%2Fscratchpad/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jasonrdsouza","download_url":"https://codeload.github.com/jasonrdsouza/scratchpad/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jasonrdsouza%2Fscratchpad/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33082036,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-15T20:25:35.270Z","status":"ssl_error","status_checked_at":"2026-05-15T20:25:34.732Z","response_time":103,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["vim"],"created_at":"2025-09-26T01:53:44.616Z","updated_at":"2026-05-15T22:33:55.502Z","avatar_url":"https://github.com/jasonrdsouza.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Scratchpad\n\nA browser based, web first, vim backed, AI assisted scratchpad for quick notes, brainstorming, and brain dumping.\n\n## Project Overview\n\n### Core Features\n\n- **Vim editing** with all standard modes (normal, insert, visual)\n- **Syntax highlighting** for multiple programming languages\n- **Theme switching** - 13+ themes via `:colorscheme`, `:colo`, or `:theme` commands\n- **Persistent storage** of content, vim command history, undo/redo history, and theme preferences\n- **Autosave** functionality to prevent data loss (only saves changed data)\n- **Clean, minimal interface** with vim mode indicator\n- **JavaScript execution** - Execute code from vim registers with `:js` and `:eval`, results stored in `\"r` register\n- **Register management** - Store and execute code snippets using vim's register system\n\n## Development Preferences\n\n### Package Management\n\n- **Always use `pnpm`** instead of npm or yarn\n- Run `pnpm run format` after making code changes to maintain consistent formatting\n- Use `pnpm run format:check` to verify formatting\n\n### Code Quality\n\n- **Run prettier after code changes** - This project uses prettier for consistent formatting\n- Prefer **4-space indentation**, double quotes, semicolons\n- Keep code clean and readable\n\n### Architecture Decisions\n\n#### Language \u0026 Framework Choices\n\n- **Vanilla JavaScript** - No heavy frameworks, keep it lightweight\n- **CodeMirror 6** - Modern, performant editor with good vim support\n- **@replit/codemirror-vim** - Best vim implementation for CM6\n\n#### Dependency Strategy\n\n- **Prefer official CodeMirror 6 packages** over third-party or legacy alternatives\n- **Avoid legacy modes** - Only use native CM6 language support\n- **Leverage existing library functionality** instead of reinventing features\n- **Stay up-to-date** with CodeMirror ecosystem\n\n#### Current Language Support\n\nOfficial CM6 packages only (with shorthand aliases):\n\n- **JavaScript/TypeScript** (`js`, `ts`, `jsx`, `tsx`) - Full language support with variants\n- **Web languages** (`json`, `css`, `html`) - Frontend development\n- **Data formats** (`yaml`/`yml`, `xml`, `sql`) - Configuration and data\n- **Programming languages** (`go`, `python`/`py`) - Backend development\n- **Documentation** (`markdown`/`md`) - Notes and documentation\n\n#### Storage Strategy\n\n- **localStorage for everything** - content, vim history, editor state\n- **Optimized autosave** - Only saves data when it has actually changed (every 5 seconds)\n- **State serialization** - Use CM6's built-in `toJSON`/`fromJSON` for editor state persistence\n- **Modular state management** - All persistence logic isolated in `state-manager.js`\n\n#### UI/UX Principles\n\n- **Minimal interface** - Focus on the editor\n- **Vim-first experience** - All interactions should feel natural to vim users\n- **Nord theme** - Consistent dark theme throughout\n- **Visual feedback** - Mode indicator, proper syntax highlighting\n\n## Technical Implementation Notes\n\n### Key Files\n\n- `script.js` - Editor setup, configuration, language definitions, UI initialization\n- `state-manager.js` - All persistence and state management functionality\n- `commands.js` - Vim command implementations and execution coordination\n- `theme-manager.js` - Theme management with 13+ CodeMirror themes and persistence\n- `execution/` - **Modular execution engine for multi-language support**\n    - `engine.js` - Central execution coordinator with pluggable language support\n    - `executor.js` - Abstract base class for language executors\n    - `javascript.js` - JavaScript execution implementation\n    - `formatters.js` - Result formatting utilities for all data types\n    - `registers.js` - Register management and result storage\n- `style.css` - UI styling with Nord color scheme (including result popups)\n- `index.html` - Minimal HTML structure\n- `.prettierrc` - Code formatting configuration\n\n### Persistence Strategy\n\nThe app persists:\n\n1. **Document content** (`vim-scratchpad-content`)\n2. **File type** (`vim-scratchpad-filetype`)\n3. **Theme preference** (`vim-scratchpad-theme`)\n4. **Vim command history** (`vim-command-history`)\n5. **Vim search history** (`vim-search-history`)\n6. **Complete editor state** (`editor-state`) including undo/redo history\n\n### Vim Integration\n\n- Use `getCM(editorView)` to access vim functionality\n- Listen to `vim-mode-change` events for mode indicator\n- Define custom vim commands with `Vim.defineEx()`\n- Access vim history via `Vim.getVimGlobalState_()`\n- Access vim registers via `registerController.unnamedRegister.keyBuffer[0]`\n\n### CodeMirror 6 Patterns\n\n- Use `Compartment` for dynamic language and theme switching\n- Serialize state with `stateFields = { history: historyField }`\n- Handle state restoration gracefully with try/catch fallbacks\n\n### Theme Switching\n\nThe scratchpad includes comprehensive theme support with 13+ professionally designed themes:\n\n#### Available Themes\n\n- **Light themes**: `solarized-light`, `github-light`, `material-light`, `gruvbox-light`, `tokyo-night-day`, `basic-light`\n- **Dark themes**: `nord` (default), `solarized-dark`, `github-dark`, `material-dark`, `gruvbox-dark`, `tokyo-night`, `tokyo-night-storm`, `basic-dark`\n\n#### Theme Commands\n\n- **Standard vim**: `:colorscheme \u003ctheme\u003e` (e.g., `:colorscheme solarized-light`)\n- **Short form**: `:colo \u003ctheme\u003e` (e.g., `:colo github-dark`)\n- **Alternative**: `:theme \u003ctheme\u003e` (e.g., `:theme gruvbox-light`)\n- **List themes**: Any command without arguments shows current theme and available options\n\n#### Theme Persistence\n\n- Theme preferences are automatically saved to localStorage\n- Themes are restored on page load\n- Uses CodeMirror compartments for instant switching without losing editor state\n\n### JavaScript Code Execution\n\nThe scratchpad includes a powerful code execution system:\n\n#### Basic Usage\n\n- **Inline code**: Run `:js 1+2+3` directly for simple expressions\n- **Current line**: Run `:js` or `:eval` on any line with JavaScript\n- **Visual selection**: Select code, yank with `y`, then run `:js`\n- **Named registers**: Yank to register (`\"ay`), execute with `:js a`\n\n#### Advanced Features\n\n- **Result storage**: All execution results automatically stored in `\"r` register\n- **Result pasting**: Use `\"rp` to paste the last result into your buffer\n- **Register inspection**: Use `:registers` to view all register contents\n- **Error handling**: Syntax errors and runtime errors are displayed safely\n- **Result display**: Results appear in a styled popup with Nord theme colors\n- **Multiple result types**: Handles objects (JSON), functions, primitives, undefined/null\n\n#### Workflow Examples\n\n```javascript\n// Inline execution - results stored in \"r register\n:js Math.PI * 2\n\n// Multi-line - select, yank, :js\nconst x = 5;\nconst y = 10;\nx + y\n\n// Named registers - select, \"ay, then :js a\nconst users = [{name: \"Alice\"}, {name: \"Bob\"}];\nusers.map(u =\u003e u.name.toUpperCase());\n\n// View and paste previous results\n:registers r  // view last result\n\"rp          // paste result into buffer\n```\n\n## Development Workflow\n\n1. **Making changes**: Edit source files normally\n2. **Formatting**: Run `pnpm run format` after changes\n3. **Testing**: Use `pnpm run dev` to start development server\n4. **Language changes**: Use `:set ft=\u003clanguage\u003e` in the editor\n\n## Feature Implementation Philosophy\n\n### When adding new features:\n\n1. **Check if CodeMirror 6 has it built-in** first\n2. **Leverage existing vim patterns** from @replit/codemirror-vim\n3. **Maintain backward compatibility** with existing localStorage data\n4. **Keep the interface minimal** - avoid UI bloat\n5. **Test persistence** - Ensure features work across page refreshes\n6. **Optimize for vim users** - Use vim's register system rather than custom selection handling\n7. **Use the execution engine** - For new language support, implement the Executor interface\n8. **Follow modular architecture** - Separate concerns into focused files\n\n### Avoid:\n\n- Heavy external dependencies\n- Custom reinvention of editor functionality\n- Breaking changes to existing storage format\n- UI complexity that distracts from editing\n- Complex visual selection capture - use vim's register system instead\n- Adding execution logic directly to commands.js - use the execution engine\n\n## Key Technical Learnings\n\n### Vim Integration Patterns\n\n- **Mode transitions clear selections** - When entering command mode (`:`) from visual, selections are lost\n- **Register system is more reliable** - Use `\"ay` to yank, then access `keyBuffer[0]` rather than trying to capture selections\n- **Vim global state access** - `Vim.getVimGlobalState_().registerController` provides register access\n- **Mode change events work well** - `vim-mode-change` events are reliable for UI updates\n\n### CodeMirror 6 State Management\n\n- **State serialization is powerful** - `toJSON()`/`fromJSON()` handles complex undo/redo history\n- **Compartments enable dynamic changes** - Language switching without recreating the editor\n- **Graceful fallbacks matter** - Always handle state restoration failures\n- **Change detection saves performance** - Only write to localStorage when data actually changes\n\n### Architecture Insights\n\n- **Separate state management early** - Isolating persistence logic prevents coupling\n- **Prefer existing library patterns** - Don't reinvent vim behaviors, use the library's systems\n- **Optimize for the 90% case** - Single-line execution is most common, multi-line via registers\n- **Vim users expect vim patterns** - Yanking to registers feels natural vs. custom selection handling\n- **Modular command system** - Isolating vim commands makes the codebase more maintainable\n- **CSS over inline styles** - Keep styling in CSS files for better organization and maintenance\n- **Execution engine pattern** - Abstract interfaces enable easy language addition without coupling\n\n### Execution Engine Design\n\n- **Abstract Executor interface** - All languages implement the same contract\n- **Pluggable architecture** - Register new languages with a single line\n- **Consistent formatting** - Unified result formatting across all languages\n- **Proper error handling** - Language-specific errors handled uniformly\n- **Register integration** - Results automatically stored using vim's register API\n- **Future-proof** - Adding Python, SQL, or other languages requires minimal changes\n\n## Current Architecture\n\nThe project follows a modular architecture with clear separation of concerns:\n\n### **Module Responsibilities:**\n\n- **`script.js`** - Core editor setup\n    - Editor initialization and configuration\n    - Language definitions and mapping\n    - Mode indicator and UI event handling\n    - Theme and language compartment management\n\n- **`state-manager.js`** - Complete persistence layer\n    - All localStorage operations with change detection\n    - Editor state serialization/deserialization\n    - Vim history management\n    - Autosave coordination and initialization helpers\n\n- **`commands.js`** - Vim command coordination\n    - All vim command implementations (`:w`, `:q`, `:set`, `:colorscheme`, `:theme`)\n    - Execution command handlers (`:js`, `:eval`)\n    - Register inspection (`:registers`)\n    - Result display system\n\n- **`theme-manager.js`** - Theme management system\n    - 13+ professional CodeMirror themes with categorization\n    - Theme persistence and localStorage integration\n    - Dynamic theme switching via compartments\n    - Theme validation and information utilities\n\n- **`execution/`** - **Modular execution engine**\n    - **`engine.js`** - Central coordinator for multi-language execution\n    - **`executor.js`** - Abstract interface for language implementations\n    - **`javascript.js`** - JavaScript execution with eval() and async support\n    - **`formatters.js`** - Consistent result formatting across languages\n    - **`registers.js`** - Result storage using proper vim register API\n\n## Documentation Policy\n\n**IMPORTANT**: This README must be updated after any:\n\n- **Architectural changes** - New files, moved functions, refactored modules\n- **New features** - Commands, language support, UI changes\n- **Development workflow changes** - Build process, formatting, dependencies\n- **Key learnings** - Technical insights, debugging discoveries, implementation patterns\n\n**CRITICAL**: When adding new vim commands or functionality:\n\n1. **Update the `:help` command** - Add new commands to the help text in `commands.js`\n2. **Update this README** - Document the new feature in the appropriate section\n3. **Test the help system** - Ensure `:help` displays the new functionality correctly\n\nKeep the documentation current to maintain development velocity and onboarding effectiveness.\n\n## Success Metrics\n\nThe scratchpad is successful when:\n\n- **It feels like vim** - All standard vim patterns work intuitively\n- **Nothing is lost** - All content, history, and state persists reliably\n- **It's fast** - No noticeable lag during editing or mode switches\n- **It's reliable** - Works consistently across browser sessions\n\nThis is a tool for developers who want a familiar vim environment for quick notes and code snippets without the overhead of a full IDE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjasonrdsouza%2Fscratchpad","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjasonrdsouza%2Fscratchpad","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjasonrdsouza%2Fscratchpad/lists"}