Skip to content

Commit

Permalink
feat: action for opening entry in an external program
Browse files Browse the repository at this point in the history
  • Loading branch information
stevearc committed Sep 22, 2023
1 parent a9ceb90 commit df17302
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ require("oil").setup({
["`"] = "actions.cd",
["~"] = "actions.tcd",
["gs"] = "actions.change_sort",
["gx"] = "actions.open_external",
["g."] = "actions.toggle_hidden",
},
-- Set to false to disable all of the above keymaps
Expand Down
4 changes: 4 additions & 0 deletions doc/oil.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ OPTIONS *oil-option
["`"] = "actions.cd",
["~"] = "actions.tcd",
["gs"] = "actions.change_sort",
["gx"] = "actions.open_external",
["g."] = "actions.toggle_hidden",
},
-- Set to false to disable all of the above keymaps
Expand Down Expand Up @@ -360,6 +361,9 @@ open_cmdline_dir *actions.open_cmdline_di
open_cwd *actions.open_cwd*
Open oil in Neovim's current working directory

open_external *actions.open_external*
Open the entry under the cursor in an external program

open_terminal *actions.open_terminal*
Open a terminal in the current directory

Expand Down
43 changes: 43 additions & 0 deletions lua/oil/actions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,49 @@ M.open_terminal = {
end,
}

---Copied from vim.ui.open in Neovim 0.10+
---@param path string
---@return nil|string[] cmd
---@return nil|string error
local function get_open_cmd(path)
if vim.fn.has("mac") == 1 then
return { "open", path }
elseif vim.fn.has("win32") == 1 then
if vim.fn.executable("rundll32") == 1 then
return { "rundll32", "url.dll,FileProtocolHandler", path }
else
return nil, "rundll32 not found"
end
elseif vim.fn.executable("wslview") == 1 then
return { "wslview", path }
elseif vim.fn.executable("xdg-open") == 1 then
return { "xdg-open", path }
else
return nil, "no handler found"
end
end

M.open_external = {
desc = "Open the entry under the cursor in an external program",
callback = function()
local entry = oil.get_cursor_entry()
local dir = oil.get_current_dir()
if not entry or not dir then
return
end
local path = dir .. entry.name
-- TODO use vim.ui.open once this is resolved
-- https://github.com/neovim/neovim/issues/24567
local cmd, err = get_open_cmd(path)
if not cmd then
vim.notify(string.format("Could not open %s: %s", path, err), vim.log.levels.ERROR)
return
end
local jid = vim.fn.jobstart(cmd, { detach = true })
assert(jid > 0, "Failed to start job")
end,
}

M.refresh = {
desc = "Refresh current directory list",
callback = function()
Expand Down
1 change: 1 addition & 0 deletions lua/oil/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ local default_config = {
["`"] = "actions.cd",
["~"] = "actions.tcd",
["gs"] = "actions.change_sort",
["gx"] = "actions.open_external",
["g."] = "actions.toggle_hidden",
},
-- Set to false to disable all of the above keymaps
Expand Down
2 changes: 1 addition & 1 deletion lua/oil/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ local M = {}
---@field is_modifiable fun(bufnr: integer): boolean Return true if this directory is modifiable (allows for directories with read-only permissions).
---@field get_column fun(name: string): nil|oil.ColumnDefinition If the adapter has any adapter-specific columns, return them when fetched by name.
---@field normalize_url fun(url: string, callback: fun(url: string)) Before oil opens a url it will be normalized. This allows for link following, path normalizing, and converting an oil file url to the actual path of a file.
---@field get_entry_path? fun(url: string, entry: oil.Entry, callback: fun(path: nil|string)) Similar to normalize_url, but used when selecting an entry
---@field get_entry_path? fun(url: string, entry: oil.Entry, callback: fun(path: string)) Similar to normalize_url, but used when selecting an entry
---@field render_action? fun(action: oil.Action): string Render a mutation action for display in the preview window. Only needed if adapter is modifiable.
---@field perform_action? fun(action: oil.Action, cb: fun(err: nil|string)) Perform a mutation action. Only needed if adapter is modifiable.
---@field read_file? fun(bufnr: integer) Used for adapters that deal with remote/virtual files. Read the contents of the file into a buffer.
Expand Down

0 comments on commit df17302

Please sign in to comment.