Merge pull request #129 from RaafatTurki/master

chore: project_cleanup
This commit is contained in:
ThePrimeagen 2021-12-02 09:00:27 -07:00 committed by GitHub
commit 6b6adf1ff4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 225 additions and 279 deletions

322
README.md
View File

@ -1,231 +1,175 @@
# WARNING <div align="center">
This is not fully baked, though used by several people. If you experience any
issues, see some improvement you think would be amazing, or just have some # Harpoon
feedback for harpoon (or me), make a ticket! ##### Getting you where you want with the fewest keystrokes.
[![Lua](https://img.shields.io/badge/Lua-blue.svg?style=for-the-badge&logo=lua)](http://www.lua.org)
[![Neovim](https://img.shields.io/badge/Neovim%200.5+-green.svg?style=for-the-badge&logo=neovim)](https://neovim.io)
</div>
![Harpoon](harpoon.png) ![Harpoon](harpoon.png)
-- Image provided by Liberty_DevCap -- image provided by **Liberty_DevCap**
# harpoon
The goal of Harpoon is to get you where you want with the fewest keystrokes.
## The Problem ## ⇁ WIP
You work on code. The code base is medium, large, tiny, whatever. You find This is not fully baked, though used by several people. If you experience any
yourself frequenting a small set of files (maybe it depends on task) and you issues, see some improvement you think would be amazing, or just have some
are tired of using a fuzzy finder, :bnext/prev, alternate file doesn't quite feedback for harpoon (or me), make an issue!
cut it, etc etc.
## The Other Problem
You want to execute some project specific commands or have any number of ## ⇁ 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.
1. You want to execute some project specific commands or have any number of
persistent terminals that can be easily navigated to. persistent terminals that can be easily navigated to.
## The Solution
The ability to specify, or on the fly, mark and create persisting key strokes ## ⇁ The Solutions:
1. The ability to specify, or on the fly, mark and create persisting key strokes
to go to the files you want. to go to the files you want.
1. Unlimited terminals and navigation.
## The Other Solution
Unlimited terminals and navigation.
## Installation
### Requires Neovim version 0.5.0+
Simply install via your favorite plugin manager.
## ⇁ Installation
* neovim 0.5.0+ required
* install using your favorite plugin manager (`vim-plug` in this example)
```vim ```vim
Plug 'nvim-lua/plenary.nvim' " don't forget to add this one if you don't have it yet! Plug 'nvim-lua/plenary.nvim' " don't forget to add this one if you don't have it yet!
Plug 'ThePrimeagen/harpoon' Plug 'ThePrimeagen/harpoon'
``` ```
## Harpooning ## ⇁ Harpooning
There are two modes of harpoon. File navigation and terminal navigation. here we'll explain how to wield the power of the harpoon:
Setup of harpoon configuration is at the bottom since its for more advanced use
cases.
### File Navigation
#### Mark a file
Marking a file is similar to vim global marks, but differ in a few key ways.
* They auto update their position
* They are unique _per project_.
* They can be hand edited vs replaced (swapping is easier)
To mark a file simply call the following lua function
### Marks
you mark files you want to revisit later on
```lua ```lua
:lua require("harpoon.mark").add_file() :lua require("harpoon.mark").add_file()
``` ```
This will mark the file and add it to the end of the mark list. ### File Navigation
view all project marks with:
#### Navigate to file
To navigate to any of the marked files simply call the navigation function with
which index. There are also functions you can call to navigate to the next or
previous marks in the marks list.
```lua
:lua require("harpoon.ui").nav_file(3) -- This will navigate to file 3
:lua require("harpoon.ui").nav_next() -- This will navigate to the next mark
:lua require("harpoon.ui").nav_prev() -- This will navigate to the previous mark
```
#### Manipulating current marks
There is a quick menu that will allow for you to edit your marks. You can hand
edit the name, its position within the list, or remove it from the list. To
bring up the quick list execute the following lua command.
```lua ```lua
:lua require("harpoon.ui").toggle_quick_menu() :lua require("harpoon.ui").toggle_quick_menu()
``` ```
you can go up and down the list, enter, delete or reorder. `q` and `<ESC>` exit and save the menu
You can simply edit this list as if it were a document in vim. `:wq` to save you also can switch to any mark without bringing up the menu, use the below with the desired mark index
the new edits or `:q` to ignore the edits. There is to save upon call to ```lua
toggle if you prefer that way. :lua require("harpoon.ui").nav_file(3) -- navigates to file 3
```
You can also exit the list with `q` or `<ESC>`, which will call `toggle_quick_menu()` again. you can also cycle the list in both directions
```lua
:lua require("harpoon.ui").nav_next() -- navigates to next mark
:lua require("harpoon.ui").nav_prev() -- navigates to previous mark
```
### Terminal Navigation ### Terminal Navigation
#### Motivation for terminals in neovim this works like file navigation except that if there is no terminal at the specified index
I want to use the terminal since I can gF and <c-w>gF to any errors arising a new terminal is created.
from execution that are within the terminal that are not appropriate for
something like dispatch. (not just running tests but perhaps a server that runs
for X amount of time before crashing).
I want the terminal to be persistent and I can return to one of many terminals
with some finger wizardry and reparse any of the execution information that was
not necessarily error related.
I would like to have commands that can be tied to terminals and sent them
without much thinking. Some sort of middle ground between vim-test and just
typing them into a terminal (configuring netflix's television project isn't
quite building and there are tons of ways to configure).
#### Navigating to a terminal
To navigate to a terminal simply provide an index and it will go. If there is
no terminal in that index or the terminal has been closed by some means,
harpoon will create a new terminal at that location.
```lua ```lua
lua require("harpoon.term").gotoTerminal(1) lua require("harpoon.term").gotoTerminal(1) -- navigates to term 1
``` ```
You can provide as high of a number as you would like. There is no terminal ### Commands to Terminals
count limitation though I personally find anything beyond two oft confusing. commands can be sent to any terminal
#### Commands to terminal
Sometimes you wish to send commands to terminals that have been preconfigured
for a project. To make this work properly you must predefine a command or hard
code it as part of the send process.
```lua ```lua
" This will send to terminal 1 either the predefined command 1 in the terminal lua require("harpoon.term").sendCommand(1, "ls -La") -- sends ls -La to tmux window 1
" config or "ls -la" ```
lua require("harpoon.term").sendCommand(1, 1) further more commands can be stored for later quick
lua require("harpoon.term").sendCommand(1, "ls -la") ```lua
lua require('harpoon.cmd-ui').toggle_quick_menu() -- shows the commands menu
lua require("harpoon.term").sendCommand(1, 1) -- sends command 1 to term 1
``` ```
#### Dynamic commands to terminal ### Tmux Support
This feature adds ability to change commands while working inside a project. tmux is supported out of the box and can be used as a drop-in replacement to normal terminals
Just call the following function to edit commands inside the list by simply switching `'term' with 'tmux'` like so
```lua
lua require('harpoon.cmd-ui').toggle_quick_menu()
```
#### Tmux Integration
Harpoon also supports all terminal operations (see above) with tmux terminals.
The configuration for using tmux is exactly the same as the config for using nvim
terminals. To use tmux terminals instead of nvim terminals, simply replace
`harpoon.term` with `harpoon.tmux` in your require statement.
For example:
```lua ```lua
-- goes to the first tmux window lua require("harpoon.tmux").gotoTerminal(1) -- goes to the first tmux window
lua require("harpoon.tmux").gotoTerminal(1) lua require("harpoon.tmux").sendCommand(1, "ls -La") -- sends ls -La to tmux window 1
lua require("harpoon.tmux").sendCommand(1, 1) -- sends command 1 to tmux window 1
-- sends a command to the first tmux window
lua require("harpoon.tmux").sendCommand(1, "ls -la")
``` ```
### Setup ### Telescope Support
Setup should be called once. 1st register harpoon as a telescope extension
#### TODO: Make this callable more than once and just layer in the commands
Yes... A todo in a readme. Deal with it.
#### The Configuration File
You can configure harpoon via lua in your rc. Here is a simple example that
will add a specific command to a project.
##### Global Settings
```lua
Here is the set of global settings and their default values.
require("harpoon").setup({
global_settings = {
save_on_toggle = false,
save_on_change = true,
enter_on_sendcmd = false,
tmux_autoclose_windows = false,
excluded_filetypes = { "harpoon" }
},
... your other configs ...
})
```
* `save_on_toggle` will set the marks upon calling `toggle` on the ui, instead
of require `:w`.
* `save_on_change` will save the harpoon file upon every change. If you don't
enable this option (on by default) harpoon will not save any changes to your
file. It is very unreliable to save your harpoon on exit (at least that is
what I have found).
* `enter_on_sendcmd` will set harpoon to run the command immediately as it's
passed to the terminal when calling `sendCommand`.
* `tmux_autoclose_windows` will close any tmux windows harpoon that harpoon creates
when you close Neovim.
* `excluded_filetypes` filetypes that you want to prevent from adding to the harpoon list menu.
#### Preconfigured Terminal Commands
These are project specific commands that you wish to execute on the regular.
```lua
require("harpoon").setup({
projects = {
-- Yes $HOME works
["$HOME/personal/vim-with-me/server"] = {
term = {
cmds = {
"./env && npx ts-node src/index.ts"
}
}
},
```
## Debugging
Harpoon writes logs to a `harpoon.log` file that resides in Neovim's cache
path. (`:echo stdpath("cache")` to find where that is for you.)
By default, logging is enabled for warnings and above. This can be changed by
setting `vim.g.harpoon_log_level` variable to one of the following log levels:
`trace`, `debug`, `info`, `warn`, `error`, or `fatal`. Note that this would
have to be done **before** harpoon's `setup` call. Alternatively, it can be
more convenient to launch Neovim with an environment variable, e.g. `>
HARPOON_LOG=trace nvim`. In case both, `vim.g` and an environment variable are
used, the log level set by the environment variable overrules. Supplying an
invalid log level defaults back to warnings.
## Telescope
### Setup
Add thet followingt to your config:
```lua ```lua
require("telescope").load_extension('harpoon') require("telescope").load_extension('harpoon')
``` ```
currently only marks are supported in telescope
### Launch ```
Call the following to launch the telescope window
```lua
:Telescope harpoon marks :Telescope harpoon marks
``` ```
## ⇁ Configuration
if configuring harpoon is desired it must be done through harpoons setup function
```lua
require("harpoon").setup({ ... })
```
### Global Settings
here are all the available global settings with their default values
```lua
global_settings = {
-- sets the marks upon calling `toggle` on the ui, instead of require `:w`.
save_on_toggle = false,
-- saves the harpoon file upon every change. disabling is unrecommended.
save_on_change = true,
-- sets harpoon to run the command immediately as it's passed to the terminal when calling `sendCommand`.
enter_on_sendcmd = false,
-- closes any tmux windows harpoon that harpoon creates when you close Neovim.
tmux_autoclose_windows = false,
-- filetypes that you want to prevent from adding to the harpoon list menu.
excluded_filetypes = { "harpoon" }
}
```
### Preconfigured Terminal Commands
to preconfigure terminal commands for later use
```lua
projects = {
-- Yes $HOME works
["$HOME/personal/vim-with-me/server"] = {
term = {
cmds = {
"./env && npx ts-node src/index.ts"
}
}
}
}
```
## ⇁ Logging
- logs are written to `harpoon.log` within the nvim cache path (`:echo stdpath("cache")`)
- available log levels are `trace`, `debug`, `info`, `warn`, `error`, or `fatal`. `warn` is default
- log level can be set with `vim.g.harpoon_log_level` (must be **before** `setup()`)
- launching nvim with `HARPOON_LOG=debug nvim` takes precedence over `vim.g.harpoon_log_level`.
- invalid values default back to `warn`.
## ⇁ Others
#### How do Harpoon marks differ from vim global marks
they seve a similar purpose however harpoon marks differs in a few key ways:
1. They auto update their position within the file
1. They are saved _per project_.
1. They can be hand edited vs replaced (swapping is easier)
#### The Motivation behind Harpoon terminals
1. I want to use the terminal since I can gF and <c-w>gF to any errors arising
from execution that are within the terminal that are not appropriate for
something like dispatch. (not just running tests but perhaps a server that runs
for X amount of time before crashing).
1. I want the terminal to be persistent and I can return to one of many terminals
with some finger wizardry and reparse any of the execution information that was
not necessarily error related.
1. I would like to have commands that can be tied to terminals and sent them
without much thinking. Some sort of middle ground between vim-test and just
typing them into a terminal (configuring netflix's television project isn't
quite building and there are tons of ways to configure).

View File

@ -9,4 +9,4 @@
* ackshual tests. * ackshual tests.
* interactive menu * interactive menu
* cycle * cycle
* make setup() callable more than once and just layer in the commands

View File

@ -68,7 +68,7 @@ local function get_menu_items()
return indices return indices
end end
M.toggle_quick_menu = function() function M.toggle_quick_menu()
log.trace("cmd-ui#toggle_quick_menu()") log.trace("cmd-ui#toggle_quick_menu()")
if if
Harpoon_cmd_win_id ~= nil Harpoon_cmd_win_id ~= nil
@ -138,7 +138,7 @@ M.toggle_quick_menu = function()
) )
end end
M.select_menu_item = function() function M.select_menu_item()
log.trace("cmd-ui#select_menu_item()") log.trace("cmd-ui#select_menu_item()")
local cmd = vim.fn.line(".") local cmd = vim.fn.line(".")
close_menu(true) close_menu(true)
@ -152,7 +152,7 @@ M.select_menu_item = function()
end end
end end
M.on_menu_save = function() function M.on_menu_save()
log.trace("cmd-ui#on_menu_save()") log.trace("cmd-ui#on_menu_save()")
term.set_cmd_list(get_menu_items()) term.set_cmd_list(get_menu_items())
end end

View File

@ -5,7 +5,7 @@
-- :nmap <leader>rr :lua require("harpoon.dev").reload()<CR> -- :nmap <leader>rr :lua require("harpoon.dev").reload()<CR>
local M = {} local M = {}
M.reload = function() function M.reload()
require("plenary.reload").reload_module("harpoon") require("plenary.reload").reload_module("harpoon")
end end
@ -41,7 +41,7 @@ for _, v in pairs(log_levels) do
override(v) override(v)
end end
M.get_log_key = function() function M.get_log_key()
return log_key return log_key
end end

View File

@ -119,7 +119,7 @@ local function expand_dir(config)
return config return config
end end
M.save = function() function M.save()
-- first refresh from disk everything but our project -- first refresh from disk everything but our project
M.refresh_projects_b4update() M.refresh_projects_b4update()
@ -133,7 +133,7 @@ local function read_config(local_config)
end end
-- 1. saved. Where do we save? -- 1. saved. Where do we save?
M.setup = function(config) function M.setup(config)
log.trace("setup(): Setting up...") log.trace("setup(): Setting up...")
if not config then if not config then
@ -174,13 +174,13 @@ M.setup = function(config)
log.trace("setup(): log_key", Dev.get_log_key()) log.trace("setup(): log_key", Dev.get_log_key())
end end
M.get_global_settings = function() function M.get_global_settings()
log.trace("get_global_settings()") log.trace("get_global_settings()")
return HarpoonConfig.global_settings return HarpoonConfig.global_settings
end end
-- refresh all projects from disk, except our current one -- refresh all projects from disk, except our current one
M.refresh_projects_b4update = function() function M.refresh_projects_b4update()
log.trace( log.trace(
"refresh_projects_b4update(): refreshing other projects", "refresh_projects_b4update(): refreshing other projects",
cache_config cache_config
@ -228,23 +228,23 @@ M.refresh_projects_b4update = function()
log.trace("refresh_projects_b4update(): log_key", Dev.get_log_key()) log.trace("refresh_projects_b4update(): log_key", Dev.get_log_key())
end end
M.get_term_config = function() function M.get_term_config()
log.trace("get_term_config()") log.trace("get_term_config()")
return ensure_correct_config(HarpoonConfig).projects[vim.loop.cwd()].term return ensure_correct_config(HarpoonConfig).projects[vim.loop.cwd()].term
end end
M.get_mark_config = function() function M.get_mark_config()
log.trace("get_mark_config()") log.trace("get_mark_config()")
return ensure_correct_config(HarpoonConfig).projects[vim.loop.cwd()].mark return ensure_correct_config(HarpoonConfig).projects[vim.loop.cwd()].mark
end end
M.get_menu_config = function() function M.get_menu_config()
log.trace("get_menu_config()") log.trace("get_menu_config()")
return HarpoonConfig.menu or {} return HarpoonConfig.menu or {}
end end
-- should only be called for debug purposes -- should only be called for debug purposes
M.print_config = function() function M.print_config()
print(vim.inspect(HarpoonConfig)) print(vim.inspect(HarpoonConfig))
end end

View File

@ -136,7 +136,7 @@ local function filter_filetype()
end end
end end
M.get_index_of = function(item) function M.get_index_of(item)
log.trace("get_index_of():", item) log.trace("get_index_of():", item)
if item == nil then if item == nil then
log.error( log.error(
@ -172,7 +172,7 @@ M.get_index_of = function(item)
return nil return nil
end end
M.status = function(bufnr) function M.status(bufnr)
log.trace("status()") log.trace("status()")
local buf_name local buf_name
if bufnr then if bufnr then
@ -190,7 +190,7 @@ M.status = function(bufnr)
return "" return ""
end end
M.valid_index = function(idx) function M.valid_index(idx)
log.trace("valid_index():", idx) log.trace("valid_index():", idx)
if idx == nil then if idx == nil then
return false return false
@ -200,7 +200,7 @@ M.valid_index = function(idx)
return file_name ~= nil and file_name ~= "" return file_name ~= nil and file_name ~= ""
end end
M.add_file = function(file_name_or_buf_id) function M.add_file(file_name_or_buf_id)
filter_filetype() filter_filetype()
local buf_name = get_buf_name(file_name_or_buf_id) local buf_name = get_buf_name(file_name_or_buf_id)
log.trace("add_file():", buf_name) log.trace("add_file():", buf_name)
@ -219,7 +219,7 @@ M.add_file = function(file_name_or_buf_id)
end end
-- _emit_on_changed == false should only be used internally -- _emit_on_changed == false should only be used internally
M.remove_empty_tail = function(_emit_on_changed) function M.remove_empty_tail(_emit_on_changed)
log.trace("remove_empty_tail()") log.trace("remove_empty_tail()")
_emit_on_changed = _emit_on_changed == nil or _emit_on_changed _emit_on_changed = _emit_on_changed == nil or _emit_on_changed
local config = harpoon.get_mark_config() local config = harpoon.get_mark_config()
@ -242,7 +242,7 @@ M.remove_empty_tail = function(_emit_on_changed)
end end
end end
M.store_offset = function() function M.store_offset()
log.trace("store_offset()") log.trace("store_offset()")
local ok, res = pcall(function() local ok, res = pcall(function()
local buf_name = get_buf_name() local buf_name = get_buf_name()
@ -270,7 +270,7 @@ M.store_offset = function()
emit_changed() emit_changed()
end end
M.rm_file = function(file_name_or_buf_id) function M.rm_file(file_name_or_buf_id)
local buf_name = get_buf_name(file_name_or_buf_id) local buf_name = get_buf_name(file_name_or_buf_id)
local idx = M.get_index_of(buf_name) local idx = M.get_index_of(buf_name)
log.trace("rm_file(): Removing mark at id", idx) log.trace("rm_file(): Removing mark at id", idx)
@ -285,14 +285,14 @@ M.rm_file = function(file_name_or_buf_id)
emit_changed() emit_changed()
end end
M.clear_all = function() function M.clear_all()
harpoon.get_mark_config().marks = {} harpoon.get_mark_config().marks = {}
log.trace("clear_all(): Clearing all marks.") log.trace("clear_all(): Clearing all marks.")
emit_changed() emit_changed()
end end
--- ENTERPRISE PROGRAMMING --- ENTERPRISE PROGRAMMING
M.get_marked_file = function(idxOrName) function M.get_marked_file(idxOrName)
log.trace("get_marked_file():", idxOrName) log.trace("get_marked_file():", idxOrName)
if type(idxOrName) == "string" then if type(idxOrName) == "string" then
idxOrName = M.get_index_of(idxOrName) idxOrName = M.get_index_of(idxOrName)
@ -300,18 +300,18 @@ M.get_marked_file = function(idxOrName)
return harpoon.get_mark_config().marks[idxOrName] return harpoon.get_mark_config().marks[idxOrName]
end end
M.get_marked_file_name = function(idx) function M.get_marked_file_name(idx)
local mark = harpoon.get_mark_config().marks[idx] local mark = harpoon.get_mark_config().marks[idx]
log.trace("get_marked_file_name():", mark and mark.filename) log.trace("get_marked_file_name():", mark and mark.filename)
return mark and mark.filename return mark and mark.filename
end end
M.get_length = function() function M.get_length()
log.trace("get_length()") log.trace("get_length()")
return table.maxn(harpoon.get_mark_config().marks) return table.maxn(harpoon.get_mark_config().marks)
end end
M.set_current_at = function(idx) function M.set_current_at(idx)
filter_filetype() filter_filetype()
local buf_name = get_buf_name() local buf_name = get_buf_name()
log.trace("set_current_at(): Setting id", idx, buf_name) log.trace("set_current_at(): Setting id", idx, buf_name)
@ -334,7 +334,7 @@ M.set_current_at = function(idx)
emit_changed() emit_changed()
end end
M.to_quickfix_list = function() function M.to_quickfix_list()
log.trace("to_quickfix_list(): Sending marks to quickfix list.") log.trace("to_quickfix_list(): Sending marks to quickfix list.")
local config = harpoon.get_mark_config() local config = harpoon.get_mark_config()
local file_list = filter_empty_string(config.marks) local file_list = filter_empty_string(config.marks)
@ -352,7 +352,7 @@ M.to_quickfix_list = function()
vim.fn.setqflist(qf_list) vim.fn.setqflist(qf_list)
end end
M.set_mark_list = function(new_list) function M.set_mark_list(new_list)
log.trace("set_mark_list(): New list:", new_list) log.trace("set_mark_list(): New list:", new_list)
local config = harpoon.get_mark_config() local config = harpoon.get_mark_config()
@ -372,7 +372,7 @@ M.set_mark_list = function(new_list)
emit_changed() emit_changed()
end end
M.toggle_file = function(file_name_or_buf_id) function M.toggle_file(file_name_or_buf_id)
local buf_name = get_buf_name(file_name_or_buf_id) local buf_name = get_buf_name(file_name_or_buf_id)
log.trace("toggle_file():", buf_name) log.trace("toggle_file():", buf_name)
@ -389,12 +389,12 @@ M.toggle_file = function(file_name_or_buf_id)
end end
end end
M.get_current_index = function() function M.get_current_index()
log.trace("get_current_index()") log.trace("get_current_index()")
return M.get_index_of(vim.api.nvim_buf_get_name(0)) return M.get_index_of(vim.api.nvim_buf_get_name(0))
end end
M.on = function(event, cb) function M.on(event, cb)
log.trace("on():", event) log.trace("on():", event)
if not callbacks[event] then if not callbacks[event] then
log.debug("on(): no callbacks yet for", event) log.debug("on(): no callbacks yet for", event)

View File

@ -63,14 +63,14 @@ local function get_first_empty_slot()
return M.get_length() + 1 return M.get_length() + 1
end end
M.gotoTerminal = function(idx) function M.gotoTerminal(idx)
log.trace("term: gotoTerminal(): Terminal:", idx) log.trace("term: gotoTerminal(): Terminal:", idx)
local term_handle = find_terminal(idx) local term_handle = find_terminal(idx)
vim.api.nvim_set_current_buf(term_handle.buf_id) vim.api.nvim_set_current_buf(term_handle.buf_id)
end end
M.sendCommand = function(idx, cmd, ...) function M.sendCommand(idx, cmd, ...)
log.trace("term: sendCommand(): Terminal:", idx) log.trace("term: sendCommand(): Terminal:", idx)
local term_handle = find_terminal(idx) local term_handle = find_terminal(idx)
@ -88,7 +88,7 @@ M.sendCommand = function(idx, cmd, ...)
end end
end end
M.clear_all = function() function M.clear_all()
log.trace("term: clear_all(): Clearing all terminals.") log.trace("term: clear_all(): Clearing all terminals.")
for _, term in ipairs(terminals) do for _, term in ipairs(terminals) do
vim.api.nvim_buf_delete(term.buf_id, { force = true }) vim.api.nvim_buf_delete(term.buf_id, { force = true })
@ -96,33 +96,33 @@ M.clear_all = function()
terminals = {} terminals = {}
end end
M.get_length = function() function M.get_length()
log.trace("_get_length()") log.trace("_get_length()")
return table.maxn(harpoon.get_term_config().cmds) return table.maxn(harpoon.get_term_config().cmds)
end end
M.valid_index = function(idx) function M.valid_index(idx)
if idx == nil or idx > M.get_length() or idx <= 0 then if idx == nil or idx > M.get_length() or idx <= 0 then
return false return false
end end
return true return true
end end
M.emit_changed = function() function M.emit_changed()
log.trace("_emit_changed()") log.trace("_emit_changed()")
if harpoon.get_global_settings().save_on_change then if harpoon.get_global_settings().save_on_change then
harpoon.save() harpoon.save()
end end
end end
M.add_cmd = function(cmd) function M.add_cmd(cmd)
log.trace("add_cmd()") log.trace("add_cmd()")
local found_idx = get_first_empty_slot() local found_idx = get_first_empty_slot()
harpoon.get_term_config().cmds[found_idx] = cmd harpoon.get_term_config().cmds[found_idx] = cmd
M.emit_changed() M.emit_changed()
end end
M.rm_cmd = function(idx) function M.rm_cmd(idx)
log.trace("rm_cmd()") log.trace("rm_cmd()")
if not M.valid_index(idx) then if not M.valid_index(idx) then
log.debug("rm_cmd(): no cmd exists for index", idx) log.debug("rm_cmd(): no cmd exists for index", idx)
@ -132,7 +132,7 @@ M.rm_cmd = function(idx)
M.emit_changed() M.emit_changed()
end end
M.set_cmd_list = function(new_list) function M.set_cmd_list(new_list)
log.trace("set_cmd_list(): New list:", new_list) log.trace("set_cmd_list(): New list:", new_list)
for k in pairs(harpoon.get_term_config().cmds) do for k in pairs(harpoon.get_term_config().cmds) do
harpoon.get_term_config().cmds[k] = nil harpoon.get_term_config().cmds[k] = nil

View File

@ -106,7 +106,7 @@ local function get_first_empty_slot()
return M.get_length() + 1 return M.get_length() + 1
end end
M.gotoTerminal = function(idx) function M.gotoTerminal(idx)
log.trace("tmux: gotoTerminal(): Window:", idx) log.trace("tmux: gotoTerminal(): Window:", idx)
local window_handle = find_terminal(idx) local window_handle = find_terminal(idx)
@ -118,7 +118,7 @@ M.gotoTerminal = function(idx)
}, vim.loop.cwd()) }, vim.loop.cwd())
end end
M.sendCommand = function(idx, cmd, ...) function M.sendCommand(idx, cmd, ...)
log.trace("tmux: sendCommand(): Window:", idx) log.trace("tmux: sendCommand(): Window:", idx)
local window_handle = find_terminal(idx) local window_handle = find_terminal(idx)
@ -144,7 +144,7 @@ M.sendCommand = function(idx, cmd, ...)
end end
end end
M.clear_all = function() function M.clear_all()
log.trace("tmux: clear_all(): Clearing all tmux windows.") log.trace("tmux: clear_all(): Clearing all tmux windows.")
for _, window in pairs(tmux_windows) do for _, window in pairs(tmux_windows) do
@ -160,33 +160,33 @@ M.clear_all = function()
tmux_windows = {} tmux_windows = {}
end end
M.get_length = function() function M.get_length()
log.trace("_get_length()") log.trace("_get_length()")
return table.maxn(harpoon.get_term_config().cmds) return table.maxn(harpoon.get_term_config().cmds)
end end
M.valid_index = function(idx) function M.valid_index(idx)
if idx == nil or idx > M.get_length() or idx <= 0 then if idx == nil or idx > M.get_length() or idx <= 0 then
return false return false
end end
return true return true
end end
M.emit_changed = function() function M.emit_changed()
log.trace("_emit_changed()") log.trace("_emit_changed()")
if harpoon.get_global_settings().save_on_change then if harpoon.get_global_settings().save_on_change then
harpoon.save() harpoon.save()
end end
end end
M.add_cmd = function(cmd) function M.add_cmd(cmd)
log.trace("add_cmd()") log.trace("add_cmd()")
local found_idx = get_first_empty_slot() local found_idx = get_first_empty_slot()
harpoon.get_term_config().cmds[found_idx] = cmd harpoon.get_term_config().cmds[found_idx] = cmd
M.emit_changed() M.emit_changed()
end end
M.rm_cmd = function(idx) function M.rm_cmd(idx)
log.trace("rm_cmd()") log.trace("rm_cmd()")
if not M.valid_index(idx) then if not M.valid_index(idx) then
log.debug("rm_cmd(): no cmd exists for index", idx) log.debug("rm_cmd(): no cmd exists for index", idx)
@ -196,7 +196,7 @@ M.rm_cmd = function(idx)
M.emit_changed() M.emit_changed()
end end
M.set_cmd_list = function(new_list) function M.set_cmd_list(new_list)
log.trace("set_cmd_list(): New list:", new_list) log.trace("set_cmd_list(): New list:", new_list)
for k in pairs(harpoon.get_term_config().cmds) do for k in pairs(harpoon.get_term_config().cmds) do
harpoon.get_term_config().cmds[k] = nil harpoon.get_term_config().cmds[k] = nil

View File

@ -70,7 +70,7 @@ local function get_menu_items()
return indices return indices
end end
M.toggle_quick_menu = function() function M.toggle_quick_menu()
log.trace("toggle_quick_menu()") log.trace("toggle_quick_menu()")
if Harpoon_win_id ~= nil and vim.api.nvim_win_is_valid(Harpoon_win_id) then if Harpoon_win_id ~= nil and vim.api.nvim_win_is_valid(Harpoon_win_id) then
close_menu() close_menu()
@ -144,18 +144,18 @@ M.toggle_quick_menu = function()
) )
end end
M.select_menu_item = function() function M.select_menu_item()
local idx = vim.fn.line(".") local idx = vim.fn.line(".")
close_menu(true) close_menu(true)
M.nav_file(idx) M.nav_file(idx)
end end
M.on_menu_save = function() function M.on_menu_save()
log.trace("on_menu_save()") log.trace("on_menu_save()")
Marked.set_mark_list(get_menu_items()) Marked.set_mark_list(get_menu_items())
end end
M.nav_file = function(id) function M.nav_file(id)
log.trace("nav_file(): Navigating to", id) log.trace("nav_file(): Navigating to", id)
local idx = Marked.get_index_of(id) local idx = Marked.get_index_of(id)
if not Marked.valid_index(idx) then if not Marked.valid_index(idx) then
@ -233,7 +233,7 @@ function M.close_notification(bufnr)
vim.api.nvim_buf_delete(bufnr) vim.api.nvim_buf_delete(bufnr)
end end
M.nav_next = function() function M.nav_next()
log.trace("nav_next()") log.trace("nav_next()")
local current_index = Marked.get_current_index() local current_index = Marked.get_current_index()
local number_of_items = Marked.get_length() local number_of_items = Marked.get_length()
@ -250,7 +250,7 @@ M.nav_next = function()
M.nav_file(current_index) M.nav_file(current_index)
end end
M.nav_prev = function() function M.nav_prev()
log.trace("nav_prev()") log.trace("nav_prev()")
local current_index = Marked.get_current_index() local current_index = Marked.get_current_index()
local number_of_items = Marked.get_length() local number_of_items = Marked.get_length()

View File

@ -2,42 +2,44 @@ local Path = require("plenary.path")
local data_path = vim.fn.stdpath("data") local data_path = vim.fn.stdpath("data")
local Job = require("plenary.job") local Job = require("plenary.job")
local M = { local M = {}
data_path = data_path,
normalize_path = function(item)
return Path:new(item):make_relative(vim.loop.cwd())
end,
get_os_command_output = function(cmd, cwd)
if type(cmd) ~= "table" then
print("Harpoon: [get_os_command_output]: cmd has to be a table")
return {}
end
local command = table.remove(cmd, 1)
local stderr = {}
local stdout, ret = Job
:new({
command = command,
args = cmd,
cwd = cwd,
on_stderr = function(_, data)
table.insert(stderr, data)
end,
})
:sync()
return stdout, ret, stderr
end,
split_string = function(str, delimiter)
local result = {}
for match in (str .. delimiter):gmatch("(.-)" .. delimiter) do M.data_path = data_path
table.insert(result, match)
end
return result function M.normalize_path(item)
end, return Path:new(item):make_relative(vim.loop.cwd())
is_white_space = function(str) end
return str:gsub("%s", "") == ""
end, function M.get_os_command_output(cmd, cwd)
} if type(cmd) ~= "table" then
print("Harpoon: [get_os_command_output]: cmd has to be a table")
return {}
end
local command = table.remove(cmd, 1)
local stderr = {}
local stdout, ret = Job
:new({
command = command,
args = cmd,
cwd = cwd,
on_stderr = function(_, data)
table.insert(stderr, data)
end,
})
:sync()
return stdout, ret, stderr
end
function M.split_string(str, delimiter)
local result = {}
for match in (str .. delimiter):gmatch("(.-)" .. delimiter) do
table.insert(result, match)
end
return result
end
function M.is_white_space(str)
return str:gsub("%s", "") == ""
end
return M return M