carbon-steel/detour.nvim

Use Detour for `:h`

Closed this issue ยท 12 comments

I've been trying to think of how I could use detour to always open up :h in a detour popup. Any ideas? I was thinking by event but I don't see any event that I think would correlate to help being opened.

I just found this comment so I'll keep you posted if this works instead!

I gave it a try. Here is what I came up with:

vim.api.nvim_create_user_command("H", function (args)
    local file = args.args
    vim.cmd.h(file)
    local help_win = vim.api.nvim_get_current_win()

    local ok = require('detour').Detour()
    if ok then
        vim.api.nvim_win_close(help_win, false)
    end
end, { nargs = 1 })

If you run this code and then run :H autocmd, you should get the help page for autocmd in a detour popup.

I don't think you can overwrite the behavior of the :h builtin command so you may just have to settle with creating this new command :H.

@carbon-steel Thanks! I'll give this a try I spent a good part of the weekend trying to figure something out, that Reddit post worked for what that particular person wanted but not for me. Haha.

@carbon-steel This is fantastic! and I have a couple ideas I'm gonna in combination with the other post as well! I'll keep you updated! But I'll close this as it does 100% answer my question!

@carbon-steel Update: Got it to work so far pretty flawlessly with the following autocmd. If this is something you think would be good to add to the examples and you don't see anything that could potentially cause issues, I'd be more than happy to submit a PR with an .md file for this!

-- Open help files only in a float
vim.api.nvim_create_autocmd("BufWinEnter", {
    pattern = "*",
    callback = function(event)
        local filetype = vim.bo[event.buf].filetype

        if filetype == "help" then
            -- Get the basename of the help file
            -- Then the file name w/o the extension
            -- Then call h on that file name
            local basename = vim.fs.basename(event.match)
            local ext_idx = basename:find('%.')
            local file = basename:sub(1, (ext_idx - 1))
            vim.cmd.h(file)

            -- Get the newly opened help window
            -- and attempt to open a Detour() float
            local help_win = vim.api.nvim_get_current_win()
            local ok = require("detour").Detour()

            -- If we successfully create a float of the help file
            -- Close the split
            if ok then
                vim.api.nvim_win_close(help_win, false)
            end
        end
    end,
})

I think it looks pretty good! Can I ask why you call vim.cmd.h for the user when checking if filetype == "help" means you want this code to run after the user opens a help file themselves?

Like, how about:

-- Open help files only in a float
vim.api.nvim_create_autocmd("BufWinEnter", {
    pattern = "*",
    callback = function(event)
        local filetype = vim.bo[event.buf].filetype

        if filetype == "help" then
            -- Get the newly opened help window
            -- and attempt to open a Detour() float
            local help_win = vim.api.nvim_get_current_win()
            local ok = require("detour").Detour()

            -- If we successfully create a float of the help file
            -- Close the split
            if ok then
                vim.api.nvim_win_close(help_win, false)
            end
        end
    end,
})

@carbon-steel Because I got distracted and only half completed the autocmd and forgot to add the markdown exception. If the help docs are .md and not .txt, Neovim doesn't appear to consider the filetype to be 'help'. So when I try to open .md docs like Detour - it still opens in a split.

So I meant to say if filetype == 'help' or 'markdown' then ... end

Unless you have an idea how to handle that, which doesn't require the extra, then I am all for it!

Edit: vim.cmd.h(...) was from previous attempts after I got that work I forgot to clean it up.
And I ended up moving that code into an after/ftplugin/help.lua file. So before hand I was using vim.cmd.h

This works up until you open a help doc thats an .md file and then you want to open a different .md file like a README or TODO file and then it also tries to open in a split. So maybe the vim.cmd.h does need to stay. I'll do some more testing.

-- Open help files only in a float
vim.api.nvim_create_autocmd("BufWinEnter", {
    pattern = "*",
    callback = function(event)
        local filetype = vim.bo[event.buf].filetype

        -- Only run if the filetype is a help file
        if filetype == "help" or  filetype == 'markdown' then
            -- Get the newly opened help window
            -- and attempt to open a Detour() float
            local help_win = vim.api.nvim_get_current_win()
            local ok = require("detour").Detour()

            -- If we successfully create a float of the help file
            -- Close the split
            if ok then
                vim.api.nvim_win_close(help_win, false)
            end
        end
    end,
})

Alright this is the best way I can come up with currently via an autocmd.

Just checking the file path contains '/doc/' and if it does we proceed with it as a help item.
I used event.match instead of event.file because I believe pathing in linux is /../ where as windows can do either (I could be wrong on that, I don't use linux very often).

-- Open help files only in a float
vim.api.nvim_create_autocmd("BufWinEnter", {
    pattern = "*",
    callback = function(event)
        local filetype = vim.bo[event.buf].filetype
        local file_path = event.match

        if file_path:match "/doc/" ~= nil then
            -- Only run if the filetype is a help file
            if filetype == "help" or filetype == "markdown" then
                -- Get the newly opened help window
                -- and attempt to open a Detour() float
                local help_win = vim.api.nvim_get_current_win()
                local ok = require("detour").Detour()

                -- If we successfully create a float of the help file
                -- Close the split
                if ok then
                    vim.api.nvim_win_close(help_win, false)
                end
            end
        end
    end,
})

Nice!

@carbon-steel If you think this is something others using Detour might be interested in setting up I can write an example tonight and submit a PR

Yeah! I'd appreciate a PR for an example :)