-
Notifications
You must be signed in to change notification settings - Fork 16
Configuration Recipes
This page is a place to share various configurations for workspaces.nvim. If you make something useful please share it here!
Editing Instructions:
Please follow the following format:
Dependencies: list required plugins if applicable
briefly explain the behavior
require("workspaces.nvim").setup({
-- setup code here
})
Further details, notes, instructions, etc. here.
If you feel the need to deviate from this format that is fine, but try to keep things organized!
Dependencies: nvim-telescope/telescope.nvim
Opens a Telescope file fuzzy finder after switching directories.
require("workspaces").setup({
hooks = {
open = "Telescope find_files",
}
})
Dependencies: kyazdani42/nvim-tree.lua
Ensures NvimTree is open after switching directories
require("workspaces").setup({
hooks = {
open = "NvimTreeOpen",
}
})
Dependencies: natecraddock/sessions.nvim
Uses sessions.nvim to load a saved buffer, window, and tab layout from the current directory after opening a workspace. If no session exists, nothing happens.
require("workspaces").setup({
hooks = {
open_pre = {
"SessionsStop",
"silent %bdelete!",
},
open = {
function()
require("sessions").load(nil, { silent = true })
end
}
},
})
Note that the sessions.load()
function assumes a default sessions path has been configured
Dependencies: jedrzejboczar/possession.nvim
The following snippet saves the session of the current cwd before switching if it exists, and loads the session of the newly opened cwd if it exists.
--- Convert the given workspace.nvim path to a possession.nvim path
local function to_possesion_path(path)
path = path:gsub("^" .. os.getenv("HOME"), "~")
path = path:gsub("/$", "")
return path
end
require("workspaces").setup({
hooks = {
open_pre = function(name, path, state)
local workspaces = require("workspaces")
local possession_paths = require("possession.paths")
local possession_config = require("possession.config")
local possession_session = require("possession.session")
local curr_path = workspaces.path()
if not curr_path then return end
local autosave_info = possession_session.autosave_info()
if not possession_config.autosave.on_load or not autosave_info then return end
local next_session = possession_paths.session(to_possesion_path(path))
if next_session:exists() then
local session_data = vim.json.decode(next_session:read())
if session_data.name == autosave_info.name then return end
end
possession_session.autosave()
vim.wait(100, function() end) -- Stupid hack to wait for Neo-tree to close and open before/after saving
end,
--- Automatically load the session of the given workspace if it exists.
--- Otherwise, just close down the current session.
open = function(name, path, state)
path = to_possesion_path(path)
if require("possession.paths").session(path):exists() then
require("possession.session").load(path, { skip_autosave = true })
else
require("possession.session").close()
end
end,
},
})
This relatively complex recipe creates an autocommand to allow you to work on multiple workspaces within a single neovim session.
When a buffer / window is focused, and it is not in the current workspace, the active workspace will be switched to the correct one, if found.
-- returns true if `dir` is a child of `parent`
local is_dir_in_parent = function(dir, parent)
if parent == nil then return false end
local ws_str_find, _ = string.find(dir, parent, 1, true)
if ws_str_find == 1 then
return true
else
return false
end
end
-- convenience function which wraps is_dir_in_parent with active file
-- and workspace.
local current_file_in_ws = function()
local workspaces = require('workspaces')
local ws_path = require('workspaces.util').path
local current_ws = workspaces.path()
local current_file_dir = ws_path.parent(vim.fn.expand('%:p', true))
return is_dir_in_parent(current_file_dir, current_ws)
end
-- set workspace when changing buffers
local my_ws_grp = vim.api.nvim_create_augroup("my_ws_grp", { clear = true })
vim.api.nvim_create_autocmd({ "BufEnter", "VimEnter" }, {
callback = function()
-- do nothing if not file type
local buf_type = vim.api.nvim_get_option_value("buftype", { buf = 0 })
if (buf_type ~= "" and buf_type ~= "acwrite") then
return
end
-- do nothing if already within active workspace
if current_file_in_ws() then
return
end
local workspaces = require('workspaces')
local ws_path = require('workspaces.util').path
local current_file_dir = ws_path.parent(vim.fn.expand('%:p', true))
-- filtered_ws contains workspace entries that contain current file
local filtered_ws = vim.tbl_filter(function(entry)
return is_dir_in_parent(current_file_dir, entry.path)
end, workspaces.get())
-- select the longest match
local selected_workspace = nil
for _, value in pairs(filtered_ws) do
if not selected_workspace then
selected_workspace = value
end
if string.len(value.path) > string.len(selected_workspace.path) then
selected_workspace = value
end
end
if selected_workspace then workspaces.open(selected_workspace.name) end
end,
group = my_ws_grp
})
-- use below example if using any `open` hooks, such as telescope, otherwise
-- the hook will run every time when switching to a buffer from a different
-- workspace.
require("workspaces").setup({
hooks = {
open = {
-- do not run hooks if file already in active workspace
function()
if current_file_in_ws() then
return false
end
end,
function()
require('telescope.builtin').find_files()
end,
}
}
})
You might want to move Telescope logic out of the open
hook and into a user command like the one shown below, so that:
- changing the working directory using Telescope opens a Telescope file finder
- automatically changing the working directory by entering a file from a different workspace does not open a Telescope file finder
vim.api.nvim_create_user_command(
'SwitchWorkspace',
function(opts)
local buf = vim.api.nvim_get_current_buf()
cmd_id = vim.api.nvim_create_autocmd(
'DirChanged',
{
callback = function(args)
if buf == vim.api.nvim_get_current_buf() then
require('telescope.builtin').find_files({ cwd = args.file })
vim.api.nvim_del_autocmd(cmd_id)
end
vim.api.nvim_set_current_dir(args.file)
end
}
)
require('telescope').extensions.workspaces.workspaces()
end,
{ nargs = 0 }
)