theprimeagen / harpoon Goto Github PK
View Code? Open in Web Editor NEWLicense: MIT License
License: MIT License
Autocmd time! Lets listen for win close events and ensure that we save upon floating window closed with ZZ/q
<S>zz
should write and close the current open window.
<S>zz
closes window but doesn't write modifications.
Pretty cool tool you've created - glad I ran across it.
I was surprised to come across the terminal functionality, and it is pretty sweet! However, when I create a terminal, I am stuck.
I am unable to run any (neo)vim commands to jump back to my open buffers, unable to bg
the terminal, etc. I can continue using the terminal, and eventually Ctrl-d
or exit
, but the language in the README mentions persistence.
Is there something I am missing? Appreciate it!
FWIW: Using neovim, in iTerm2. Let me know what configs you might need and I can send them your way.
This means I need to create some unit tests too :)
Plenary here I come
Harpoon.projector would combine the defined terminal commands + any project commands + telescope + async execution.
For package.json
this would be easy to accomplish. For other types (makefiles?) this could be harder
Preconfigured commands for project helps a lot when we have to test the project or build the project all the time. However, vimrc doesn't seem to be the best location for saving it. Not only it mixes project configuration with vimrc(we can have many temporary projects... long vimrc is unreasonable) also it makes it static. That means with evolution of project, if the workflow changes... user have to change its vimrc and restart vim to make the changes take effect... There is a lot of friction in it.
We already have dynamic marks with harpoon... So, why not use similar idea here. A user can configure the project commands dynamically with the help of provided API functions. Also, he can use some quick_command_menu kind of thing for visually changing the configured commands for project. When we have to send the command to terminal we send it by fetching the command from json (maybe named as harpoon_commands.json).
Now, users have the power of dynamically configuring the project commands that means tests and builds are so easy and so configurable now without messing our dotfiles.
Additional problem of having preconfigured commands in vimrc is the fact that most of people just maintain their dotfiles as git repo and many people do some temporary projects and temporary project configuration in vimrc is just a pain in ass...
Any chance of adding this feature.... If you want I can work on it and submit the PR. I hope it would highly increase the usability of the plugin
Please add doc/harpoon.txt
Have an issue when navigate.
When I first add 2 marks, one file and one terminal, navigation works just fine.
But when I close nvim, and then reopen it, there is an issue.
I can still navigate to the file normally, but I can only navigate to marked terminal for one time.
When I try to naviage from file to marked terminal again, it has an error.
Currently, harpoon
opens quick menu entries in a new buffer, even if the current buffer is empty. I think it would be better if harpoon
first attempted to open the entry in the current empty buffer if possible, similarly to what :edit
does.
Upon vim open and we are on netrw then navigate to ui mark 1.
Small iteration and likely wrong a good deal of the time, but will provide a nicer experience than the file explorer
Should be configurable.
Today terminal commands are strings, but they should be functions as well. A function must return a string.
-- requirements: sync function
function myJob()
return "some command"
end
-- requirements: async function
-- Probably should talk to tj to make sure that it falls within any of the async await work coming up.
-- open question: should false signify its an async function?
function myJob(cb)
... code ...
return false
end
An alternative approach would be to have objects
{
sync = true, -- default
run = function(workspace, subpath) -- workspace and subpath are specified else where.
... code ...
return "my command"
end
}
With git-worktrees being my primary vehicle of development it would be nice if my marks persisted across all the different trees. With this in mind I think the best possible solution is base directories
. Meaning that we can specify a base path and all marks / workspaces / terminal commands will work.
Example
harpoon.setup({
projects = {
["~/personal/vim-with-me/{}"] = {
... harpoon config here ...
}
}
});
This will apply to all sub directories of ~/personal/vim-with-me/...
. We will pass in the path to the terminal command if its a function.
PLEASE CREATE THIS.
Project is officially to big for no unit tests.
https://github.com/brandoncc/telescope-harpoon.nvim
this should be moved into this plugin to be more easily seen and known to be used. should be easy as copying the telescope folder into the lua folder here
Is this possible to add a feature to support column position of the cursor when saving or restoring marks, please ?
Here is a patch of what I use now :
diff --git a/lua/harpoon/mark.lua b/lua/harpoon/mark.lua
index a5097e6..a9bf86d 100644
--- a/lua/harpoon/mark.lua
+++ b/lua/harpoon/mark.lua
@@ -181,6 +181,8 @@ M.store_offset = function()
harpoon.get_mark_config().marks[idx].row =
vim.fn.line(".");
+ harpoon.get_mark_config().marks[idx].col =
+ vim.fn.col(".");
end)
if not ok then
diff --git a/lua/harpoon/ui.lua b/lua/harpoon/ui.lua
index c87e163..720c5fa 100644
--- a/lua/harpoon/ui.lua
+++ b/lua/harpoon/ui.lua
@@ -106,7 +106,7 @@ M.nav_file = function(id)
vim.api.nvim_set_current_buf(buf_id)
if set_row and mark.row then
- vim.cmd(string.format(":%d", mark.row))
+ vim.cmd(string.format(":call cursor(%d, %d)", mark.row, mark.col))
end
end
harpoon
inherits the number
, foldcolum
, and signcolumn
of init.lua
or vimrc
. Depending on user settings, this can lead to the harpoon
window not properly rendering marks. It'll be nice to have default settings for these options.
I use this workaround in the meantime.
au FileType harpoon setlocal number norelativenumber numberwidth=1 foldcolumn=0 signcolumn=no
I'm using harpoon alongside with git worktree.
When switching trees i always have to close the terminals I'm using to reopen them in the current directory.
It would be nice to have a function that let you kill all terminal, similar to the clear all marks feature.
I don't mind trying to do it myself, but i don't know if it would be a good feature or not, maybe my case is very specific
I think commit a96cafc is broken (or maybe I'm excepting an other use case).
The use case I'm expecting with this commit is :
When I , I jump to the file specified.
What I get is:
I have harpoon configured like Prime's dotfiles
The menu is always a new menu between directories
Sometimes I want to swap between a file in my tools dir and my utils dir within a greater project and it's a new harpoon menu for each directory.
Something simple I am missing?
I tried defining an empty project spec in config but this does not work either
require("harpoon").setup({
global_settings = {
save_on_toggle = true,
save_on_change = true,
},
projects = {
["absolute path to super cool project"] = {}
}
})
Of course, I can use this mapping
nnoremap <C-h> :lua require("harpoon.ui").nav_file(1)<CR>
nnoremap <C-t> :lua require("harpoon.ui").nav_file(2)<CR>
nnoremap <C-n> :lua require("harpoon.ui").nav_file(3)<CR>
nnoremap <C-s> :lua require("harpoon.ui").nav_file(4)<CR>
but this is not quite what I need.
Gotta make those marks save... This is annoying!
Just like marks has its status support to show the mark index
of the current buffer.
This would be nice to have for terminals too.
Where marks have M1, M2, M3, ...
The terminals could show T1, T2, T3, ... in the statusline.
As you can see, poor terminal is living in a void. Nobody likes living in a void. Specially terminals.
Good evening, Prime. I've seen that plenary.nvim is a great dependency of this and many other great plugins and I think more people would benefit from it if it were listed as a dependency on the README. I don't know if this is quite right but in packer it would look like this:
use { "ThePrimeagen/harpoon", requires = "nvim-lua/plenary.nvim" }
and I don't know if this is the optimal way to do it, but something in the lines of
Plug 'nvim-lua/plenary.nvim' " Wonderful requirement for this plugin and many more!
Plug 'ThePrimeagen/harpoon'
for vim-plug.
I'm in the works of submitting a PR to fix this, I'll reference this issue on it.
#4 has clearly shown me the importance of debug logging.
Create a debug logger to log every place of the application so we can reduce errors quickly.
This would also include wrapping more calls in pcall
to get exact values out.
@polarmutex if you have any examples you have seen / used, lmk
I've been using harpoon for a while now and it has sped up my workflow by a lot, however this one bit is missing (or so I believe) which is the ability to navigate back to the last file/terminal you've opened.
This opens so many possibilities, in my case it would give me the ability to do this
nmap term.nav_last()
and tmap ui.nav_last()
to the same key
now whenever I press that key it switches me between file and terminal
I've tried to take a stab at It and my stab did work but it's not the right way to stab it :(
I've tried doing it the right way but I've found the codebase a little confusing/inconsistent right now for example:
in ui.select_menu_item()
an idx
is defined and passed to ui.nav_file()
which now refers to it as id
and uses it to create an another idx
also some module functions are defined as function M.name(args)
while others as M.name = function(args)
and a general lack of documentation, I wanted to also implement ui.nav_next()
and ui.nav_prev()
but I've found it to be already implemented after digging through the source code, also what in the deuce is c.c
Point is, I like this plugin and want to see it flourish and I do understand it's still in beta but it doesn't have to be.
I would do a cleanup PR if it's a welcome change.
There needs to be a way in which we can resolve the full path of a file and ensure that they are not in our buffer list. My guess is that when I use bufnr / bufname i should be able to determine if that path (no matter if its absolute or not) is already in the list.
The setup global setting enter_on_sendcmd
does not run the command passed to the terminal when calling sendCommand
.
It work for me when replacing '\n' with '\r' in sendCommand
. For my computer this diff fixes the issue :
diff --git a/lua/harpoon/term.lua b/lua/harpoon/term.lua
index fef47ec..ee1f8a5 100644
--- a/lua/harpoon/term.lua
+++ b/lua/harpoon/term.lua
@@ -78,7 +78,7 @@ M.sendCommand = function(idx, cmd, ...)
end
if global_config.enter_on_sendcmd then
- cmd = cmd .. "\n"
+ cmd = cmd .. "\r"
end
if cmd then
Am I the only one to encounter this problem ?
And if not, can we apply the diff above or will it not work for every OS ?
currently i have this settings
" set autochdir
to make it easier for navigation throught fuzzy finders and the newtrw but i hope the there was a way to tell the harpoon to detect the root directory as the lsp servers do like .git or something like that it should expose and api so we could configure it
It makes sense to cache marks, but I don't think it makes sense to cache the new menu
config proposed by #46.
For example, if you add the following:
require('harpoon').setup {
menu = {
width = 50,
height = 8,
borderchars = {'!', '@', '$', '%', '^', '&', '*', '|'},
}
}
Then remove that config, it'll keep reading that from harpoon.json. I feel like if you remove cosmetic menu config, it should revert back to uncached defaults.
After installing harpoon
, I get the following error when running :bnext
, :bprev
, :CocCommand explorer
etc...
Error detected while processing BufLeave Autocommands for "*":
E5108: Error executing lua ...onfig/nvim/autoload/plugged/harpoon/lua/harpoon/mark.lua:34: attempt to get length of field 'marks' (a nil value)
I'm using Neovim nightly v0.5.0-dev+1097-g18f90336c
.
When I execute:
:lua require("harpoon.term").gotoTerminal(1)
I am shown the following error:
E5108: Error executing lua /Users/brandoncc/dev/harpoon/lua/harpoon/term.lua:48: Invalid buffer id: 2
Each subsequent time I execute the same command, it says a subsequent buffer id (3, 4, 5, 6, etc).
I like the idea of having keys in logs, the one downside is that every log message now shows as being logged in dev.lua:36
, as that's where the log is called with the key.
Maybe we should explore some alternatives to this so as not to lose the context where the log really takes place?
Perhaps plenary is fine by offering something like this, as it would be a really straightforward fix on its side. Or we could repurpose its log script. However, these are more extreme solutions.
Every time I try to install and use harpoon I got this error.
[harpoon] [WARN 20:45:55] .../nvim/site/pack/packer/start/harpoon/lua/harpoon/dev.lua:36: 1623091478 store_offset(): Could not store offset: ...nvim/site/pack/packer/start/harpoo
n/lua/harpoon/mark.lua:276: attempt to index upvalue 'harpoon' (a boolean value)
The error is cast by every motion or command I try. I don't know how to reproduce the error.
My Nvim version
NVIM v0.5.0-dev+1385-g93f15db5d
Build type: RelWithDebInfo
LuaJIT 2.1.0-beta3
I really don't know what's the problem I tryed to do a clean install of Nvim as well, but the problem is still there
I've been playing around with this plugin since I watched this masterpiece and I'm quite enjoying the workflow that harpoon
provides to me. During my usage experience, I've been noticed some things that may be improved. Let me list them below.
'harpoon.ui'.toggle_quick_menu()
It's really nice that the user can just edit the quick menu and then press <Esc>
followed by q
to exit or even an <Enter>
to just open the entry of the selected line. However, I don't see the need to have to write the index of the entry before its path. I think the approach used in 'harpoon.cmd-ui'.toggle_quick_menu()
is a lot better. The quick menu for commands previously mentioned relies on the user to move lines around in order to switch the index of the commands in the list. It also has number
set by default, which I think it's a better way to visualize the index of each entry. That said, I think that the quick menu for the ui
module would be improved if behaved like the quick menu from cmd-ui
.
'harpoon.cmd-ui'.toggle_quick_menu()
This quick menu is almost perfect to me, but it lacks some essential features... The first one is that by pressing <Enter>
in normal mode won't actually run the command in the selected line, which I think is a lot counterintuitive. The second one is that by pressing q
in normal mode the menu won't close.
Really thanks for this plugin!
The same file gets stored multiple times.
Instead we need to use the Path from plenary to make it relative to the cwd.
This should also allow for project moving as well.
I would like to setup with harpoon one shot commands.
They would do the following.
Great suggestion by Asbjorn to have a replace_at(idx: number): void
This should be a really simple function to write and a great first issue if anyone wants to take this.
👋🏼
This plugin looks like something that would fit wonderfully into my workflow but I'm failing to get it to install properly. The UI looks like this:
Renaming a line in the popup, like NEED´, breaks the mark and just opens a new file named
NEED`. When trying this out on a larger project it seemed to get stuck in some weird loop also - ending up feeding the content of the current buffer into the popup instead.
I'm loading the plugin with:
use({
'ThePrimeagen/harpoon',
event = 'BufEnter',
requires = {'nvim-lua/plenary.nvim', 'nvim-lua/popup.nvim'},
})
Making it non-lazy makes not difference.
issue description: quick menu ordering does not update when using toggle_quick_menu
. Using :wq
does update it.
nvim version: 0.5.0-dev+1157-g0ab88c2ea
harpoon version: up to date as of 2021/03/27
get_mark_config
before changing the order:
{
marks = { {
col = 0,
filename = "tests/file1.js",
row = 43
}, {
col = 0,
filename = "tests/file2.js",
row = 19
}, {
col = 0,
filename = "tests/data.json",
row = 81
}, {
col = 0,
filename = "tests/data.json_backup",
row = 23
} }
}
after changing the 2nd and 3th item around and close using toggle_quick_menu
nothing has changed.
it you have defined a project in your harpoon config like "/path/project" . The user config contains a duplicated entries of the following "/path/project" and "/path/project"
When opening the menu, the marked files are listed with the complete path relative from the cwd.
It would improve readability to only show the filename and as much as needed from the path to remain unique.
This is the same way some buffer line plugins handle this.
See: https://github.com/akinsho/bufferline.nvim#unique-buffer-names
Maybe a very basic quesion but few tries and google search did not help.
I want to kill last (/currently running) command and send a new command to terminal.
I have had the file saving process not work 2x shutdown -r now
. Perhaps we should consider on every update to the harpoon mark config. We could use Path's async save
Thoughts @asbjornhaland @brandoncc
I've been using harpoon since yesterday. Today I cd'ed into a project, started up neovim, opened a file and tried to bring up the harpoon UI to see if my main files are still harpooned (I'm expecting them to be), but I got this error:
E5108: Error executing lua /home/me/.vim/plugged/harpoon/lua/harpoon/ui.lua:36: attempt to call field 'create' (a nil value)
I am on commit 22b2650 which is up to date as of now.
Much kudos to you for Harpoon! I have been l looking for a project like this a while now. I made a hackish version in pure vimscript a while back, but gave up on my implementation as it took too much of my time maintaining.
In my use case, I'd like to have terminals not only for the classical shell, but also to deal with REPLs. Think gotoTerminal(1)
gives me normal Bash shell, gotoTemrinal(2)
gives me Ipython (if in Python development).
In your current implementation, you would have to first create a shell gotoTerminal(2)
, and then pass the next command with sendCommand("ipython\n")
. This works, but feels awkwards:
$ ipython
will uneadely take up visual space.sendCommand("ipython\n")
, when it is already running, is an annoyance.There are a few ways to solve this, but the approach I'd prefer is to add terminal create string as an extra optional arg. E.g. gotoTerminal(2, ':e term://ipython -c \\%run %')
will, if terminal 2 does not exist, create Ipython REPL, execute the file you are editing, and terminate when done. If a REPL is already running, the argument is ignored.
Looking at your code, I should be able to add this. If you like, I can even give a try drafting it up.
Hi
I have started to try out the extension. amazing idea.
some of the files listed on the menu and saved do not open but I can't remove them from he toggle menu or clear the cache. Is there a way to do that or delete the data?
thanks!
I'm loving this plugin, but can't seem to find out why this is not working.
Both commands bellow give me this error:
lua require("harpoon.term").sendCommand(1, 1)
lua require("harpoon.term").sendCommand(1, "ls -la")
I'm guessing there's something with my config?
require("harpoon").setup({
nav_first_in_list = true,
projects = {
["/home/lpanebr/Dropbox/work/extyles.git"] = {
term = {
cmds = {
"ls *.py\n",
}
}
},
["/home/lpanebr/.config/nvim"] = {
term = {
cmds = {
"tree -d -L 2\n",
}
}
}
}
})
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.