diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 00000000..9db93ce5 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,27 @@ +name: Documentation + +on: [push] + +jobs: + docs: + name: Generate vim docs + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: actions/checkout@v3 + - uses: kdheepak/panvimdoc@main + with: + description: Getting you where you want with the fewest keystrokes + vimdoc: harpoon + pandoc: README.md + toc: "false" + - run: | + sudo add-apt-repository ppa:neovim-ppa/stable + sudo apt-get update + sudo apt-get install -y neovim + nvim +"helptags doc | exit" + - uses: stefanzweifel/git-auto-commit-action@v5 + with: + commit_author: Harpoon + commit_message: 'doc: generate vim docs' diff --git a/Makefile b/Makefile index 1cb386a8..5d76496e 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,15 @@ test: nvim --headless --noplugin -u scripts/tests/minimal.vim \ -c "PlenaryBustedDirectory lua/harpoon/test/ {minimal_init = 'scripts/tests/minimal.vim'}" +.PHONY: doc +doc: + echo "===> Generating docs" + panvimdoc.sh \ + --description "Getting you where you want with the fewest keystrokes" \ + --input-file README.md --project-name harpoon --toc false + nvim +"helptags doc | exit" + + clean: echo "===> Cleaning" rm /tmp/lua_* diff --git a/doc/harpoon.txt b/doc/harpoon.txt new file mode 100644 index 00000000..9583ae5c --- /dev/null +++ b/doc/harpoon.txt @@ -0,0 +1,342 @@ +*harpoon.txt* Getting you where you want with the fewest keystrokes + +⇁ TOC *harpoon-⇁-toc* + +- |harpoon-the-problems| +- |harpoon-the-solutions| +- |harpoon-installation| +- |harpoon-getting-started| +- |harpoon-api| + - |harpoon-config| + - |harpoon-settings| +- |harpoon-contribution| +- |harpoon-social| +- |harpoon-note-to-legacy-harpoon-1-users| + + +⇁ THE PROBLEMS *harpoon-⇁-the-problems* + +1. You’re working on a codebase. medium, large, tiny, whatever. You find +yourself frequenting a small set of files and you are tired of using a fuzzy finder, +`:bnext` & `:bprev` are getting too repetitive, alternate file doesn’t quite cut it, etc etc. +2. You want to execute some project specific commands, have any number of +persistent terminals that can be easily navigated to, send commands to other +tmux windows, or dream up your own custom action and execute with a single key + + +⇁ THE SOLUTIONS *harpoon-⇁-the-solutions* + +1. Specify either by altering a ui or by adding via hot key files +2. Unlimited lists and items within the lists + + +⇁ INSTALLATION *harpoon-⇁-installation* + +- neovim 0.8.0+ required +- install using your favorite plugin manager (i am using `packer` in this case) + +>lua + use "nvim-lua/plenary.nvim" -- don't forget to add this one if you don't have it yet! + use { + "ThePrimeagen/harpoon", + branch = "harpoon2", + requires = { {"nvim-lua/plenary.nvim"} } + } +< + +- install using lazy.nvim + +>lua + { + "ThePrimeagen/harpoon", + branch = "harpoon2", + dependencies = { "nvim-lua/plenary.nvim" } + } +< + + +⇁ GETTING STARTED *harpoon-⇁-getting-started* + + +QUICK NOTE ~ + +You will want to add your style of remaps and such to your neovim dotfiles with +the shortcuts you like. My shortcuts are for me. Me alone. Which also means +they are designed with dvorak in mind (My layout btw, I use dvorak btw). + + +HARPOON:SETUP() IS REQUIRED ~ + +it is a requirement to call `harpoon:setup()`. This is required due to autocmds +setup. + + +BASIC SETUP ~ + +Here is my basic setup + +>lua + local harpoon = require("harpoon") + + -- REQUIRED + harpoon:setup() + -- REQUIRED + + vim.keymap.set("n", "a", function() harpoon:list():append() end) + vim.keymap.set("n", "", function() harpoon.ui:toggle_quick_menu(harpoon:list()) end) + + vim.keymap.set("n", "", function() harpoon:list():select(1) end) + vim.keymap.set("n", "", function() harpoon:list():select(2) end) + vim.keymap.set("n", "", function() harpoon:list():select(3) end) + vim.keymap.set("n", "", function() harpoon:list():select(4) end) + + -- Toggle previous & next buffers stored within Harpoon list + vim.keymap.set("n", "", function() harpoon:list():prev() end) + vim.keymap.set("n", "", function() harpoon:list():next() end) +< + + +TELESCOPE ~ + +In order to use Telescope as +a UI, make sure to add `telescope` to your dependencies and paste this +following snippet into your configuration. + +>lua + local harpoon = require('harpoon') + harpoon:setup({}) + + -- basic telescope configuration + local conf = require("telescope.config").values + local function toggle_telescope(harpoon_files) + local file_paths = {} + for _, item in ipairs(harpoon_files.items) do + table.insert(file_paths, item.value) + end + + require("telescope.pickers").new({}, { + prompt_title = "Harpoon", + finder = require("telescope.finders").new_table({ + results = file_paths, + }), + previewer = conf.file_previewer({}), + sorter = conf.generic_sorter({}), + }):find() + end + + vim.keymap.set("n", "", function() toggle_telescope(harpoon:list()) end, + { desc = "Open harpoon window" }) +< + + +⇁ API *harpoon-⇁-api* + +You can define custom behavior of a harpoon list by providing your own calls. + +Here is a simple example where i create a list named `cmd` that takes the +current line in the editor and adds it to harpoon menu. When `list:select(...)` +is called, we take the contents of the line and execute it as a vim command + +I don’t think this is a great use of harpoon, but its meant to show how to +add your own custom lists. You could imagine that a terminal list would be just +as easy to create. + +>lua + local harpoon = require("harpoon") + + harpoon:setup({ + -- Setting up custom behavior for a list named "cmd" + "cmd" = { + + -- When you call list:append() this function is called and the return + -- value will be put in the list at the end. + -- + -- which means same behavior for prepend except where in the list the + -- return value is added + -- + -- @param possible_value string only passed in when you alter the ui manual + add = function(possible_value) + -- get the current line idx + local idx = vim.fn.line(".") + + -- read the current line + local cmd = vim.api.nvim_buf_get_lines(0, idx - 1, idx, false)[1] + if cmd == nil then + return nil + end + + return { + value = cmd, + context = { ... any data you want ... }, + } + end, + + --- This function gets invoked with the options being passed in from + --- list:select(index, <...options...>) + --- @param list_item {value: any, context: any} + --- @param list { ... } + --- @param option any + select = function(list_item, list, option) + -- WOAH, IS THIS HTMX LEVEL XSS ATTACK?? + vim.cmd(list_item.value) + end + + } + }) +< + + +CONFIG ~ + +There is quite a bit of behavior you can configure via `harpoon:setup()` + +- `settings`: is the global settings. as of now there isn’t a global setting in use, but once we have some custom behavior i’ll put them here +- `default`: the default configuration for any list. it is simply a file harpoon +- `[name] = HarpoonPartialConfigItem`: any named lists config. it will be merged with `default` and override any behavior + +**HarpoonPartialConfigItem Definition** + +> + ---@class HarpoonPartialConfigItem + ---@field select_with_nil? boolean defaults to false + ---@field encode? (fun(list_item: HarpoonListItem): string) | boolean + ---@field decode? (fun(obj: string): any) + ---@field display? (fun(list_item: HarpoonListItem): string) + ---@field select? (fun(list_item?: HarpoonListItem, list: HarpoonList, options: any?): nil) + ---@field equals? (fun(list_line_a: HarpoonListItem, list_line_b: HarpoonListItem): boolean) + ---@field create_list_item? fun(config: HarpoonPartialConfigItem, item: any?): HarpoonListItem + ---@field BufLeave? fun(evt: any, list: HarpoonList): nil + ---@field VimLeavePre? fun(evt: any, list: HarpoonList): nil + ---@field get_root_dir? fun(): string +< + +**Detailed Definitions** * `select_with_nil`: allows for a list to call select +even if the provided item is nil * `encode`: how to encode the list item to the +harpoon file. if encode is `false`, then the list will not be saved to disk +(think terminals) * `decode`: how to decode the list * `display`: how to +display the list item in the ui menu * `select`: the action taken when +selecting a list item. called from `list:select(idx, options)` * `equals`: how +to compare two list items for equality * `create_list_item`: called when +`list:append()` or `list:prepend()` is called. called with an item, which will +be a string, when adding through the ui menu * `BufLeave`: this function is +called for every list on BufLeave. if you need custom behavior, this is the +place * `VimLeavePre`: this function is called for every list on VimLeavePre. * +`get_root_dir`: used for creating relative paths. defaults to `vim.loop.cwd()` + + +SETTINGS ~ + +Settings can alter the experience of harpoon + +**Definition** + +>lua + ---@class HarpoonSettings + ---@field save_on_toggle boolean defaults to false + ---@field sync_on_ui_close boolean defaults to false + ---@field key (fun(): string) +< + +**Descriptions** * `save_on_toggle`: any time the ui menu is closed then we +will save the state back to the backing list, not to the fs * +`sync_on_ui_close`: any time the ui menu is closed then the state of the list +will be sync’d back to the fs * `key` how the out list key is looked up. This +can be useful when using worktrees and using git remote instead of file path + +**Defaults** + +>lua + settings = { + save_on_toggle = false, + sync_on_ui_close = false, + key = function() + return vim.loop.cwd() + end, + }, +< + + +EXTEND ~ + +The 'extend' functionality can be used to add keymaps for opening files in +splits & tabs. + +>lua + harpoon:extend({ + UI_CREATE = function(cx) + vim.keymap.set("n", "", function() + harpoon.ui:select_menu_item({ vsplit = true }) + end, { buffer = cx.bufnr }) + + vim.keymap.set("n", "", function() + harpoon.ui:select_menu_item({ split = true }) + end, { buffer = cx.bufnr }) + + vim.keymap.set("n", "", function() + harpoon.ui:select_menu_item({ tabedit = true }) + end, { buffer = cx.bufnr }) + end, + }) +< + + +HIGHLIGHT GROUPS ~ + +TODO: Fill in the idea that we will emit out window information + + +LOGGER ~ + +This can help debug issues on other’s computer. To get your debug log please +do the following. + +1. open up a new instance of vim +2. perform exact operation to cause bug +3. execute vim command `:lua require("harpoon").logger:show()` and copy the buffer +4. paste the buffer as part of the bug creation + + +EXTENDS *harpoon-extends* + +THIS PART OF THE DOCS NEEDS FILLING OUT + +>lua + local harpoon = require("harpoon"); + local extensions = require("harpoon.extensions"); + + harpoon:setup() + harpoon:extend(extensions.builtins.command_on_nav("foo bar")); + harpoon:extend(extensions.builtins.navigate_with_number()); +< + + +⇁ CONTRIBUTION *harpoon-⇁-contribution* + +This project is officially open source, not just public source. If you wish to +contribute start with an issue and I am totally willing for PRs, but I will be +very conservative on what I take. I don’t want Harpoon _solving_ specific +issues, I want it to create the proper hooks to solve any problem + +**Running Tests** To run the tests make sure plenary + is checked out in the parent +directory of _this_ repository, then run `make test`. + + +⇁ SOCIAL *harpoon-⇁-social* + +For questions about Harpoon, there’s a #harpoon channel on the Primeagen’s +Discord server. * Discord + * Twitch +* Twitter + + +⇁ NOTE TO LEGACY HARPOON 1 USERS*harpoon-⇁-note-to-legacy-harpoon-1-users* + +Original Harpoon will remain in a frozen state and i will merge PRs in with _no +code review_ for those that wish to remain on that. Harpoon 2 is significantly +better and allows for MUCH greater control. Please migrate to that (will become +`master` within the next few months). + +Generated by panvimdoc + +vim:tw=78:ts=8:noet:ft=help:norl: diff --git a/doc/tags b/doc/tags new file mode 100644 index 00000000..e5782967 --- /dev/null +++ b/doc/tags @@ -0,0 +1,10 @@ +harpoon-extends harpoon.txt /*harpoon-extends* +harpoon-⇁-api harpoon.txt /*harpoon-⇁-api* +harpoon-⇁-contribution harpoon.txt /*harpoon-⇁-contribution* +harpoon-⇁-getting-started harpoon.txt /*harpoon-⇁-getting-started* +harpoon-⇁-installation harpoon.txt /*harpoon-⇁-installation* +harpoon-⇁-social harpoon.txt /*harpoon-⇁-social* +harpoon-⇁-the-problems harpoon.txt /*harpoon-⇁-the-problems* +harpoon-⇁-the-solutions harpoon.txt /*harpoon-⇁-the-solutions* +harpoon-⇁-toc harpoon.txt /*harpoon-⇁-toc* +harpoon.txt harpoon.txt /*harpoon.txt*