a simple plugin to manage workspace directories in neovim
workspaces.nvim provides a few simple commands for managing workspace directories in neovim. A workspace is a name and a path, and opening a workspace will set the current directory to the correct path.
- Register a workspace with
:WorkspacesAdd
- Open a registered workspace with
:WorkspacesOpen [name]
- Hooks may be registered to provide additional functionality
- A telescope extension
:Telescope workspaces
is provided for fuzzy finding over workspaces
Nothing runs automatically. The idea is that workspace creation is an infrequent task, so there shouldn't be any need for automatic workspace registration, or heuristics to determine if a directory is a workspace. A command and telescope extension are provided to make it simple to open a workspace, but what that means beyond changing directories is left up to you by customizing the hooks. See Examples for inspiration on hooks!
Note that this plugin is small in scope and complexity. It has been stable for a long time. Just because I am not making changes doesn't mean it's been abandoned! It was designed to be small and stable, and it will stay that way.
Because naming could be confusing, here are some definitions:
-
Workspaces: as described above, are project directories. The purpose of this plugin being to switch easily between these project directories.
-
Dirs: These are directories that contain workspaces. It allows to easily sync multiple workspaces contained in a directory. For example, you might have a directory called
projects
on your machine, that contains all your projects. Just register this directory as adir
with:WorkspacesAddDir
and all the workspaces contained in it will be automatically added to the list of workspaces when running:WorkspacesSyncDirs
.
Install with your favorite neovim package manager. Be sure to run the setup function if you wish to change the default configuration or register the user commands.
require("workspaces").setup()
The setup function accepts a table to modify the default configuration:
{
-- path to a file to store workspaces data in
-- on a unix system this would be ~/.local/share/nvim/workspaces
path = vim.fn.stdpath("data") .. "/workspaces",
-- to change directory for nvim (:cd), or only for window (:lcd)
-- deprecated, use cd_type instead
-- global_cd = true,
-- controls how the directory is changed. valid options are "global", "local", and "tab"
-- "global" changes directory for the neovim process. same as the :cd command
-- "local" changes directory for the current window. same as the :lcd command
-- "tab" changes directory for the current tab. same as the :tcd command
--
-- if set, overrides the value of global_cd
cd_type = "global",
-- sort the list of workspaces by name after loading from the workspaces path.
sort = true,
-- sort by recent use rather than by name. requires sort to be true
mru_sort = true,
-- option to automatically activate workspace when opening neovim in a workspace directory
auto_open = false,
-- option to automatically activate workspace when changing directory not via this plugin
-- set to "autochdir" to enable auto_dir when using :e and vim.opt.autochdir
-- valid options are false, true, and "autochdir"
auto_dir = false,
-- enable info-level notifications after adding or removing a workspace
notify_info = true,
-- lists of hooks to run after specific actions
-- hooks can be a lua function or a vim command (string)
-- lua hooks take a name, a path, and an optional state table
-- if only one hook is needed, the list may be omitted
hooks = {
add = {},
remove = {},
rename = {},
open_pre = {},
open = {},
},
}
For example, the following settings will add a hook to run :Telescope find_files
after opening a workspace, and keep the default workspaces path:
require("workspaces").setup({
hooks = {
open = { "Telescope find_files" },
}
})
The setup function registers the following user commands:
-
:WorkspacesAdd [name] [path]
The workspace with the specified name and path will be registered.
-
:WorkspacesAddDir [path]
The directory with the specified or current path will be registered and each one of its sub folders stored as workspaces.
-
:WorkspacesRemove [name]
The workspace with the specified name will be removed.
-
:WorkspacesRemoveDir [name]
The directory with the specified name will be removed as well as all of its associated workspaces.
-
:WorkspacesRename [name] [new_name]
The workspace with the specified name will be renamed to
new_name
. -
:WorkspacesList
Prints all workspaces.
-
:WorkspacesListDirs
Prints all directories.
-
:WorkspacesOpen [name]
Opens the named workspace. opening a workspace means to change the current directory to that workspace's path.
-
:WorkspacesSyncDirs
Synchronize workspaces from registered directories.
See :h workspaces-usage
for more information on the commands.
The workspaces commands may also be accessed from Lua
local workspaces = require("workspaces")
workspaces.add(path: string, name: string)
workspaces.add_dir(path: string)
workspaces.remove(name: string)
workspaces.remove_dir(name: string)
workspaces.rename(name: string, new_name: string)
workspaces.list()
workspaces.list_dirs()
workspaces.open(name: string)
workspaces.get(): table
workspaces.name(): string|nil
workspaces.path(): string|nil
workspaces.sync_dirs()
workspaces.get_custom(name: string): string|nil
workspaces.set_custom(name: string, data: string)
See :h workspaces-api
for more information on the API functions.
workspaces.nvim is bundled with a telescope picker extension. To enable, add the following to your config
telescope.load_extension("workspaces")
The picker will list all workspaces. <cr>
will open the selected workspace,
running any registered hooks. <c-t>
will open the selected workspace in a new tab.
To keep nvim in insert mode (for example, when chaining multiple telescope pickers), add the following to your telescope setup function. You can also specify the highlight group used for the path in the picker.
require("telescope").setup({
extensions = {
workspaces = {
-- keep insert mode after selection in the picker, default is false
keep_insert = true,
-- Highlight group used for the path in the picker, default is "String"
path_hl = "String"
}
}
})
Remember that more than one hook is allowed, so these may be combined in creative ways! Hooks may also be registered after adding and removing workspaces, not only after opening a workspace.
See Configuration Recipes and Troubleshooting on the wiki for more inspiration and help configuring the plugin. Feel free to contribute your setup!
Change directory to the workspace and run fzf.
require("workspaces").setup({
hooks = {
open = "FZF",
}
})
Open nvim-tree.
require("workspaces").setup({
hooks = {
open = "NvimTreeOpen",
}
})
Load any saved sessions using natecraddock/sessions.nvim.
require("workspaces").setup({
hooks = {
open_pre = {
-- If recording, save current session state and stop recording
"SessionsStop",
-- delete all buffers (does not save changes)
"silent %bdelete!",
},
open = function()
require("sessions").load(nil, { silent = true })
end,
}
})
Open nvim-tree and a telescope file picker.
require("workspaces").setup({
hooks = {
open = { "NvimTreeOpen", "Telescope find_files" },
}
})
If you create a hook you think is useful, let me know and I might just add it to this list!
workspaces.nvim is a simple plugin with the ability to be extended through hooks. Nothing is registered or opened automatically. If you want a plugin to be less manual, try an alternative:
- ahmedkhalf/project.nvim Automatically tracks workspace directories based on pattern matching heuristics.