feat: workspaces (#74)

* create workspaces file

* add workspace numbers to project lines

* add action to change a project's workspace

* add keymapping to change workspace

* separate workspace mappings

* add workspace key mappings to README

* fix luacheck as recommended in

* fix test cases and make them more robust

- add a few assertions
- use `tostring` for the title to make it usable for plenary paths and
  regular paths defined as strings (from test cases)

* workspaces are shown on default

Co-authored-by: chrislaidler <cjjlaidler@gmail.com>
This commit is contained in:
matu3ba
2021-11-20 08:43:15 +01:00
committed by GitHub
parent 50ae840e22
commit ad33c9eb67
9 changed files with 80 additions and 31 deletions

View File

@@ -4,4 +4,7 @@ cache = true
-- Global objects defined by the C code
read_globals = {
"vim",
"describe",
"it",
"assert",
}

View File

@@ -1,6 +1,6 @@
# telescope-project.nvim
An extension for [telescope.nvim](https://github.com/nvim-telescope/telescope.nvim)
An extension for [telescope.nvim](https://github.com/nvim-telescope/telescope.nvim)
that allows you to switch between projects.
## Demo
@@ -30,7 +30,7 @@ require'telescope'.extensions.project.project{}
## Default mappings (normal mode):
| Key | Description |
|-----|---------------------------------------------------------------|
| --- | ------------------------------------------------------------- |
| `d` | delete currently selected project |
| `r` | rename currently selected project |
| `c` | create a project\* |
@@ -42,18 +42,24 @@ require'telescope'.extensions.project.project{}
## Default mappings (insert mode):
| Key | Description |
|-----|---------------------------------------------------------------|
| Key | Description |
| ------- | ------------------------------------------------------------- |
| `<c-d>` | delete currently selected project |
| `<c-v>` | rename currently selected project |
| `<c-a>` | create a project\* |
| `<c-s>` | search inside files within your project |
| `<c-b>` | browse inside files within your project |
| `<c-w>` | change to the selected project's directory without opening it |
| `<c-l>` | change to the selected project's directory without opening it |
| `<c-r>` | find a recently opened file within your project |
| `<c-f>` | find a file within your project (same as \<CR\>) |
\* *defaults to your git root if used inside a git project, otherwise, it will use your current working directory*
\* _defaults to your git root if used inside a git project, otherwise, it will use your current working directory_
## Workspace mappings (insert mode):
| Key | Description |
| ------- | ---------------- |
| `<c-w>` | change workspace |
Example key map config:
@@ -65,14 +71,14 @@ vim.api.nvim_set_keymap(
{noremap = true, silent = true}
)
```
## Available options:
| Keys | Description | Options |
|----------------|---------------------------------------------|-------------------------------|
| `display_type` | Show the title and the path of the project | 'full' or 'minimal' (default) |
| Keys | Description | Options |
| -------------- | ------------------------------------------ | ----------------------------- |
| `display_type` | Show the title and the path of the project | 'full' or 'minimal' (default) |
Options can be added when requiring telescope-project, as shown below:
Options can be added when requiring telescope-project, as shown below:
```lua
lua require'telescope'.extensions.project.project{ display_type = 'full' }
@@ -85,7 +91,7 @@ lua require'telescope'.extensions.project.project{ display_type = 'full' }
| `base_dirs` | Array of project base directory configurations | table (default: nil) |
| `hidden_files` | Show hidden files in selected project | bool (default: false) |
Setup settings can be added when requiring telescope, as shown below:
Setup settings can be added when requiring telescope, as shown below:
```lua
require('telescope').setup {

View File

@@ -6,7 +6,7 @@ if not has_telescope then
error('This plugins requires nvim-telescope/telescope.nvim')
end
utils.init_file()
utils.init_files()
return telescope.register_extension{
setup = main.setup,

View File

@@ -60,6 +60,24 @@ M.rename_project = function(prompt_bufnr)
io.close(file)
end
-- Change the selected projects workspace within the `telescope_projects_file`.
M.change_workspace = function(prompt_bufnr)
local selected_path = M.get_selected_path(prompt_bufnr)
local projects = _utils.get_project_objects()
local new_workspace = vim.fn.input('Move project to workspace: ')
local file = io.open(_utils.telescope_projects_file, "w")
for _, project in pairs(projects) do
if project.path == selected_path then
project.workspace = 'w' .. new_workspace
end
_utils.store_project(file, project)
end
io.close(file)
end
-- Delete (deactivate) the selected project from the `telescope_projects_file`
M.delete_project = function(prompt_bufnr)
local projects = _utils.get_project_objects()

View File

@@ -35,12 +35,14 @@ M.project_finder = function(opts, projects)
separator = " ",
items = {
{ width = widths.title },
{ width = widths.workspace },
{ width = widths.display_path },
}
}
local make_display = function(project)
return displayer {
{ project.title },
{ project.workspace },
{ project.display_path }
}
end

View File

@@ -47,6 +47,7 @@ M.project = function(opts)
_actions.delete_project:enhance({ post = refresh_projects })
_actions.rename_project:enhance({ post = refresh_projects })
-- Project key mappings
map('n', 'd', _actions.delete_project)
map('n', 'r', _actions.rename_project)
map('n', 'c', _actions.add_project)
@@ -63,7 +64,10 @@ M.project = function(opts)
map('i', '<c-b>', _actions.browse_project_files)
map('i', '<c-s>', _actions.search_in_project_files)
map('i', '<c-r>', _actions.recent_project_files)
map('i', '<c-w>', _actions.change_working_directory)
map('i', '<c-l>', _actions.change_working_directory)
-- Workspace key mappings
map('i', '<c-w>', _actions.change_workspace)
local on_project_selected = function()
_actions.find_project_files(prompt_bufnr, hidden_files)

View File

@@ -4,12 +4,18 @@ local M = {}
-- The file path to telescope projects
M.telescope_projects_file = vim.fn.stdpath('data') .. '/telescope-projects.txt'
-- The file path to telescope workspaces
M.telescope_workspaces_file = vim.fn.stdpath('data') .. '/telescope-workspaces.txt'
-- Initialize file if does not exist
M.init_file = function()
local file_path = Path:new(M.telescope_projects_file)
if not file_path:exists() then
file_path:touch()
M.init_files = function()
local projects_file_path = Path:new(M.telescope_projects_file)
if not projects_file_path:exists() then
projects_file_path:touch()
end
local workspaces_file_path = Path:new(M.telescope_workspaces_file)
if not workspaces_file_path:exists() then
workspaces_file_path:touch()
end
end
@@ -49,14 +55,19 @@ end
-- Extracts information from telescope projects line
M.parse_project_line = function(line)
local title, path, activated = line:match("^(.-)=(.-)=(.-)$")
if not activated then
local title, path, workspace, activated = line:match("^(.-)=(.-)=(.-)=(.-)$")
if not workspace then
title, path = line:match("^(.-)=(.-)$")
workspace = 'w0'
end
if not activated then
title, path, workspace = line:match("^(.-)=(.-)=(.-)$")
activated = 1
end
return {
title = title,
path = path,
workspace = workspace,
last_accessed = M.get_last_accessed_time(path),
activated = activated
}
@@ -64,9 +75,11 @@ end
-- Parses path into project object (activated by default)
M.get_project_from_path = function(path)
-- `tostring` to use plenary path and paths defined as strings
local title = tostring(path):match("[^/]+$")
local workspace = 'w0'
local activated = 1
local line = title .. "=" .. path .. "=" .. activated
local line = title .. "=" .. path .. "=" .. workspace .. "=" .. activated
return M.parse_project_line(line)
end
@@ -79,7 +92,7 @@ end
-- Standardized way of storing project to file
M.store_project = function(file, project)
local line = project.title .. "=" .. project.path .. "=" .. project.activated .. "\n"
local line = project.title .. "=" .. project.path .. "=" .. project.workspace .. "=" .. project.activated .. "\n"
file:write(line)
end

View File

@@ -6,11 +6,11 @@ describe("git", function()
local git = require("telescope._extensions.project.git")
local path_to_projects = path:new("/tmp/git_spec_projects")
local project_names = {
"project1",
"project2",
"project3",
"project4",
local project_names = {
"project1",
"project2",
"project3",
"project4",
}
-- Create test projects
local project_paths = iter.iter(project_names)
@@ -28,14 +28,17 @@ describe("git", function()
it("try and find path", function()
local path = project_paths[2]
vim.fn.execute("cd " .. path.filename, "silent")
local pathproject = project_paths[2]
vim.fn.execute("cd " .. pathproject.filename, "silent")
local git_path = git.try_and_find_git_path()
assert.equal(path.filename, git_path)
assert.equal(pathproject.filename, git_path)
end)
it("search for repos", function()
local repo_paths = git.search_for_git_repos({{path = path_to_projects.filename, max_depth = 2}})
for index,_ in ipairs(repo_paths) do
assert.equal(repo_paths[index]._absolute, "/tmp/git_spec_projects/" .. project_names[index])
end
local git_projects = git.parse_git_repo_paths(repo_paths)
local found_all_projects = true

View File

@@ -41,7 +41,7 @@ describe("utils", function()
-- initialize projects file where projects are stored
local test_projects_file = "/tmp/telescope-projects-test.txt"
utils.telescope_projects_file = test_projects_file
utils.init_file()
utils.init_files()
local test_projects_path = path:new(test_projects_file)
-- extract project information from path