commit fef0bb9266f99a8276a3d62d2976ee1f55b14350 Author: Carlos Date: Sat Jun 14 20:39:13 2025 -0400 Initial commit: ideaDrop.nvim plugin with sidebar and idea saving diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e18ca08 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# Lua bytecode (just in case) +*.luac + +# OS junk +.DS_Store +Thumbs.db + +# Backup/swap files +*.swp +*.swo +*.swn +*~ + +# Neovim plugin manager folders (if used for testing locally) +.pack/ +site/ + +# Logs or temp files +*.log +.idea/ +.vscode/ + +# Ignore user's idea storage directory (don't commit personal files) +.ideaDrop/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..41bbf88 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,99 @@ +# Contributing to ideaDrop.nvim + +Thank you for your interest in contributing to ideaDrop.nvim! This document provides guidelines and instructions for contributing to this project. + +## ๐ŸŽฏ Development Setup + +1. Fork the repository +2. Clone your fork: + ```bash + git clone https://github.com/YOUR_USERNAME/ideaDrop.nvim.git + cd ideaDrop.nvim + ``` +3. Create a new branch for your feature/fix: + ```bash + git checkout -b feature/your-feature-name + ``` + +## ๐Ÿ“ Code Style + +- Follow the [Lua Style Guide](https://github.com/lunarmodules/lua-style-guide) +- Use TypeScript-style type annotations in comments +- Keep functions small and focused +- Write meaningful commit messages following [Conventional Commits](https://www.conventionalcommits.org/) + +Example of type annotations: +```lua +---@param config table Configuration table +---@field idea_dir string Directory to store ideas +---@return nil +local function setup(config) + -- function implementation +end +``` + +## ๐Ÿงช Testing + +1. Test your changes in a clean Neovim environment +2. Ensure all commands work as expected +3. Test edge cases and error handling +4. Update documentation if necessary + +## ๐Ÿ“š Documentation + +- Update `doc/ideaDrop.txt` for any new commands or features +- Add examples for new functionality +- Keep the README.md up to date +- Document any breaking changes + +## ๐Ÿ”„ Pull Request Process + +1. Update the README.md and documentation with details of changes +2. Update the version number in any relevant files +3. The PR must pass all checks +4. Get a review from at least one maintainer +5. Once approved, your PR will be merged + +## ๐Ÿ› Bug Reports + +When reporting bugs, please include: + +1. Neovim version +2. Operating system +3. Steps to reproduce +4. Expected behavior +5. Actual behavior +6. Relevant error messages +7. Your configuration + +## โœจ Feature Requests + +When suggesting features: + +1. Describe the feature in detail +2. Explain why it would be useful +3. Provide examples of how it would work +4. Consider potential edge cases + +## ๐Ÿ“‹ Code of Conduct + +- Be respectful and inclusive +- Be patient and welcoming +- Be thoughtful +- Be collaborative +- When disagreeing, try to understand why + +## ๐ŸŽ‰ Your First Contribution + +1. Look for issues labeled `good first issue` +2. Comment on the issue to let us know you're working on it +3. Follow the development setup steps above +4. Submit your PR + +## ๐Ÿ“„ License + +By contributing to ideaDrop.nvim, you agree that your contributions will be licensed under the project's MIT License. + +--- + +Thank you for contributing to ideaDrop.nvim! ๐Ÿš€ \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..f094a06 --- /dev/null +++ b/README.md @@ -0,0 +1,69 @@ +# ideaDrop.nvim + +๐Ÿ’ก A simple Neovim plugin to drop and organize your ideas in floating Markdown sidebars. + +## ๐Ÿ“ฆ Installation + +Using **lazy.nvim**: + +```lua +{ + dir = "/Users/carlos/Documents/SSD_Documents/personals/ideaDrop", + name = "ideaDrop", + config = function() + require("ideaDrop").setup({ + idea_dir = "/Users/carlos/Nextcloud/ObsidianVault", -- where your ideas will be saved + }) + end, +} +``` + +## โš™๏ธ Configuration + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `idea_dir` | string | `vim.fn.stdpath("data") .. "/ideaDrop"` | Directory where your idea files will be stored | + +## ๐Ÿงช Commands + +| Command | Description | +|---------|-------------| +| `:Idea` | Opens today's idea file | +| `:Idea name` | Opens or creates an idea with the specified name | +| `:Idea listAll` | Opens a fuzzy picker to select from existing ideas | + +## ๐Ÿ“Œ Features + +- ๐Ÿ“ Markdown editor in a floating sidebar +- ๐Ÿ’พ Automatic save on close +- ๐Ÿ“… Date-based and custom named notes +- ๐Ÿ“ Folder support (e.g., `project/vision.md`) +- ๐Ÿ” Fuzzy finder for existing ideas +- ๐ŸŽจ Clean and distraction-free interface + +## ๐Ÿ—‚ Example Usage + +```vim +:Idea project/nextgen " Opens or creates project/nextgen.md +:Idea listAll " Opens fuzzy finder for all ideas +``` + +## ๐Ÿ“š Documentation + +For detailed documentation, run `:help ideaDrop` in Neovim. + +## ๐Ÿ›  Development + +This plugin is built with: +- Lua +- Neovim API +- Markdown support +- Fuzzy finding capabilities + +## ๐Ÿ“„ License + +MIT License - feel free to use this plugin in your own projects! + +## ๐Ÿค Contributing + +Contributions are welcome! Please feel free to submit a Pull Request. \ No newline at end of file diff --git a/doc/ideaDrop.txt b/doc/ideaDrop.txt new file mode 100644 index 0000000..6852cdb --- /dev/null +++ b/doc/ideaDrop.txt @@ -0,0 +1,76 @@ +*ideaDrop.txt* ideaDrop.nvim plugin for Neovim + +============================================================================== +INTRODUCTION *ideaDrop-introduction* + +ideaDrop.nvim is a simple Neovim plugin that allows you to drop and organize +your ideas in floating Markdown sidebars. It provides a clean and +distraction-free interface for quick note-taking and idea organization. + +============================================================================== +INSTALLATION *ideaDrop-installation* + +Using lazy.nvim: + + { + dir = "path/ideaDrop", + name = "ideaDrop", + config = function() + require("ideaDrop").setup({ + idea_dir = "path/ideaDrop", + }) + end, + } + +============================================================================== +CONFIGURATION *ideaDrop-configuration* + +ideaDrop.nvim can be configured by passing a table to the setup function: + + require("ideaDrop").setup({ + idea_dir = "/path/to/your/ideas", -- Directory to store idea files + }) + +OPTIONS *ideaDrop-options* + +idea_dir (string) ~ + Default: vim.fn.stdpath("data") .. "/ideaDrop" + Directory where your idea files will be stored. + +============================================================================== +COMMANDS *ideaDrop-commands* + +:Idea *:Idea* + Opens today's idea file in a floating sidebar. + +:Idea {name} *:Idea-name* + Opens or creates an idea file with the specified name. + Example: `:Idea project/vision` + +:Idea listAll *:Idea-listAll* + Opens a fuzzy picker to select from existing ideas. + +============================================================================== +FEATURES *ideaDrop-features* + +- Markdown editor in a floating sidebar +- Automatic save on close +- Date-based and custom named notes +- Folder support (e.g., project/vision.md) +- Fuzzy finder for existing ideas +- Clean and distraction-free interface + +============================================================================== +EXAMPLES *ideaDrop-examples* + +1. Open today's idea: + :Idea + +2. Create a new idea in a project folder: + :Idea project/nextgen + +3. List and select from existing ideas: + :Idea listAll + +============================================================================== +vim:tw=78:ts=8:ft=help:norl: \ No newline at end of file diff --git a/doc/tags b/doc/tags new file mode 100644 index 0000000..fc24f6c --- /dev/null +++ b/doc/tags @@ -0,0 +1,11 @@ +:Idea ideaDrop.txt /*:Idea* +:Idea-listAll ideaDrop.txt /*:Idea-listAll* +:Idea-name ideaDrop.txt /*:Idea-name* +ideaDrop-commands ideaDrop.txt /*ideaDrop-commands* +ideaDrop-configuration ideaDrop.txt /*ideaDrop-configuration* +ideaDrop-examples ideaDrop.txt /*ideaDrop-examples* +ideaDrop-features ideaDrop.txt /*ideaDrop-features* +ideaDrop-installation ideaDrop.txt /*ideaDrop-installation* +ideaDrop-introduction ideaDrop.txt /*ideaDrop-introduction* +ideaDrop-options ideaDrop.txt /*ideaDrop-options* +ideaDrop.txt ideaDrop.txt /*ideaDrop.txt* diff --git a/lua/ideaDrop/config.lua b/lua/ideaDrop/config.lua new file mode 100644 index 0000000..38c348c --- /dev/null +++ b/lua/ideaDrop/config.lua @@ -0,0 +1,24 @@ +-- ideaDrop/config.lua + +---@class Config +---@field options IdeaDropOptions +---@field setup fun(user_opts: IdeaDropOptions|nil): nil + +---@class IdeaDropOptions +---@field idea_dir string Directory where idea files will be stored + +local M = {} + +---Default configuration options +M.options = { + idea_dir = vim.fn.stdpath("data") .. "/ideaDrop" -- default path +} + +---Setup function to merge user options with defaults +---@param user_opts IdeaDropOptions|nil User configuration options +---@return nil +function M.setup(user_opts) + M.options = vim.tbl_deep_extend("force", M.options, user_opts or {}) +end + +return M diff --git a/lua/ideaDrop/init.lua b/lua/ideaDrop/init.lua new file mode 100644 index 0000000..5ca7a49 --- /dev/null +++ b/lua/ideaDrop/init.lua @@ -0,0 +1,53 @@ +-- ideaDrop.nvim/init.lua +local config = require("ideaDrop.config") +local sidebar = require("ideaDrop.sidebar") +local list = require("ideaDrop.list") +local M = {} + +---@class IdeaDrop +---@field setup fun(user_opts: IdeaDropConfig): nil + +---@class IdeaDropConfig +---@field idea_dir string Directory where idea files will be stored + +---Setup function for ideaDrop.nvim +---@param user_opts IdeaDropConfig|nil User configuration options +---@return nil +function M.setup(user_opts) + config.setup(user_opts) + + vim.api.nvim_create_user_command("Idea", function(opts) + local arg = opts.args + local idea_dir = config.options.idea_dir + + if arg == "listAll" then + list.list_all() + elseif arg ~= "" then + -- Ensure directory exists (even for nested folders) + local filename = arg:match("%.md$") and arg or (arg .. ".md") + local full_path = idea_dir .. "/" .. filename + + -- Create parent folders if needed + local folder = vim.fn.fnamemodify(full_path, ":h") + if vim.fn.isdirectory(folder) == 0 then + vim.fn.mkdir(folder, "p") + end + + sidebar.open(full_path, filename) + else + -- Default to today's idea file + local path = string.format("%s/%s.md", idea_dir, os.date("%Y-%m-%d")) + sidebar.open(path) + end + end, { + nargs = "?", + complete = function() + return { "listAll" } + end, + desc = "Open today's idea, a named idea, or list all", + }) + + vim.notify("ideaDrop loaded!", vim.log.levels.INFO) +end + +return M diff --git a/lua/ideaDrop/keymaps.lua b/lua/ideaDrop/keymaps.lua new file mode 100644 index 0000000..e6e35fa --- /dev/null +++ b/lua/ideaDrop/keymaps.lua @@ -0,0 +1,16 @@ +-- ideaDrop/keymaps.lua +---@class Keymaps +---@field setup fun(): nil +local M = {} + +---Sets up default keymaps for ideaDrop +---Currently only sets up a demo keymap +---@return nil +function M.setup() + -- Demo keymap for idea capture + vim.keymap.set("n", "id", function() + vim.notify("๐Ÿ’ก Idea captured!") + end, { desc = "Drop idea (demo)" }) +end + +return M diff --git a/lua/ideaDrop/list.lua b/lua/ideaDrop/list.lua new file mode 100644 index 0000000..7f86d1e --- /dev/null +++ b/lua/ideaDrop/list.lua @@ -0,0 +1,30 @@ +-- ideaDrop/list.lua +local config = require("ideaDrop.config") +local sidebar = require("ideaDrop.sidebar") + +---@class List +---@field list_all fun(): nil +local M = {} + +---Lists all idea files and allows user to select one to open +---@return nil +function M.list_all() + local path = config.options.idea_dir + -- Find all .md files recursively + local files = vim.fn.glob(path .. "**/*.md", false, true) + + if #files == 0 then + vim.notify("๐Ÿ“‚ No idea files found", vim.log.levels.INFO) + return + end + + -- Present file selection UI + vim.ui.select(files, { prompt = "๐Ÿ“‚ Select an idea file to open:" }, function(choice) + if choice then + sidebar.open(choice) -- Open the selected file in sidebar + end + end) +end + +return M + diff --git a/lua/ideaDrop/sidebar.lua b/lua/ideaDrop/sidebar.lua new file mode 100644 index 0000000..f976bec --- /dev/null +++ b/lua/ideaDrop/sidebar.lua @@ -0,0 +1,82 @@ +local config = require("ideaDrop.config") + +---@class Sidebar +---@field open fun(file: string|nil, filename: string|nil): nil +---@field save_idea fun(lines: string[], file: string|nil): nil +local M = {} + +---Opens a floating sidebar window with the specified file +---@param file string|nil Path to the file to open +---@param filename string|nil Name of the file (used for new files) +---@return nil +function M.open(file, filename) + -- Create a new buffer + local buf = vim.api.nvim_create_buf(false, true) + vim.api.nvim_buf_set_option(buf, "filetype", "markdown") + + -- Calculate window dimensions (30% of screen width, 80% of screen height) + local width = math.floor(vim.o.columns * 0.3) + local height = math.floor(vim.o.lines * 0.8) + + -- Create and configure the floating window + local win = vim.api.nvim_open_win(buf, true, { + relative = "editor", + width = width, + height = height, + row = 1, + col = 1, + border = "rounded", + style = "minimal", + }) + + -- Load file content or create new file template + if file and vim.fn.filereadable(file) == 1 then + local content = vim.fn.readfile(file) + vim.api.nvim_buf_set_lines(buf, 0, -1, false, content) + else + vim.api.nvim_buf_set_lines(buf, 0, -1, false, { + "# " .. (filename or "Idea for " .. os.date("%Y-%m-%d")), + "", + "- ", + }) + end + + -- Set up autosave on window close + vim.api.nvim_create_autocmd("WinClosed", { + pattern = tostring(win), + once = true, + callback = function() + local lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false) + M.save_idea(lines, file) + end, + }) +end + +---Saves the idea content to a file +---@param lines string[] Array of lines to save +---@param file string|nil Path where to save the file +---@return nil +function M.save_idea(lines, file) + local idea_path = config.options.idea_dir + + -- Create default path if none provided + if not file then + if vim.fn.isdirectory(idea_path) == 0 then + vim.fn.mkdir(idea_path, "p") + end + file = string.format("%s/%s.md", idea_path, os.date("%Y-%m-%d")) + end + + -- Write content to file + local f, err = io.open(file, "w") + if not f then + vim.notify("โŒ Failed to write idea: " .. tostring(err), vim.log.levels.ERROR) + return + end + + f:write(table.concat(lines, "\n") .. "\n") + f:close() + vim.notify("๐Ÿ’พ Idea saved to " .. file, vim.log.levels.INFO) +end + +return M diff --git a/lua/ideaDrop/utils.lua b/lua/ideaDrop/utils.lua new file mode 100644 index 0000000..e69de29