Skip to content

Commit

Permalink
Add default to take string key in setup that is a path to a nested ke…
Browse files Browse the repository at this point in the history
…y; clean up readme a little bit
  • Loading branch information
chipsenkbeil committed Jul 20, 2023
1 parent d6a6ba5 commit b9f649a
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 46 deletions.
53 changes: 10 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
A wrapper around [`distant`](https://github.com/chipsenkbeil/distant) that
enables users to edit remote files from the comfort of their local environment.

- **Requires neovim 0.7+**
- **Requires distant 0.20.0-alpha.4**
- **Requires neovim 0.8+**
- **Requires distant 0.20.x**

🚧 **(Alpha stage software) This plugin is in rapid development and may
break or change frequently!** 🚧
Expand All @@ -26,36 +26,25 @@ Supports the following features against remote machines:
## Installation & Setup

> It is **highly** recommended to not use the master branch of this plugin.
> Instead, prefer either a branch (`v0.1` or `v0.2`) or a specific tag (`v0.1.1`)
> to lock in the plugin. When using a branch, you will get rolling updates to
> that branch. When using a tag, you are locked into the features and stability
> of the plugin at that point!
> Instead, prefer either a branch (`v0.3`) or a specific tag (`v0.3.0`) to lock
> in the plugin. When using a branch, you will get rolling updates to that
> branch. When using a tag, you are locked into the features and stability of
> the plugin at that point!
Using [packer.nvim](https://github.com/wbthomason/packer.nvim), the quickest
way to get up and running is the following:

```lua
use {
'chipsenkbeil/distant.nvim',
branch = 'v0.2',
branch = 'v0.3',
config = function()
require('distant').setup {
-- Applies Chip's personal settings to every machine you connect to
--
-- 1. Ensures that distant servers terminate with no connections
-- 2. Provides navigation bindings for remote directories
-- 3. Provides keybinding to jump into a remote file's parent directory
['*'] = require('distant.settings').chip_default()
}
local distant = require('distant')
distant:setup()
end
}
```

The above will initialize the plugin with the following:

1. Any spawned distant server will shutdown after 60 seconds of inactivity
2. Standard keybindings are assigned for remote buffers (described below)

#### Within a file

| Key | Action |
Expand Down Expand Up @@ -98,29 +87,7 @@ all of the contents of the specified directory.
## Documentation

For more details on available functions, settings, commands, and more,
please check out the vim help documentation via
[`:help distant.txt`](doc/distant.txt).

## Demo

### Intro Video

Demonstrates using distant.nvim to edit files and use a language server on a
remote machine.

[![Intro Video](https://img.youtube.com/vi/BuW2b1Ii0RI/0.jpg)](https://www.youtube.com/watch?v=BuW2b1Ii0RI)

### v0.1.0 Update

Demonstrates the new release of distant.nvim (v0.1.0) leveraging distant's new
lua module (v0.15.0). Main highlights include:

- integrated ssh authentication
- ssh mode
- refactored and simplified vim & Lua APIs
- complete help documentation

[![v0.1.0 update](https://img.youtube.com/vi/wVAsbpByQ3o/0.jpg)](https://www.youtube.com/watch?v=wVAsbpByQ3o)
please check out the [online help documentation](https://distant.dev/editors/neovim/).

## License

Expand Down
4 changes: 2 additions & 2 deletions lua/distant/default.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
--- @class distant.plugin.Settings
local DEFAULT_SETTINGS = {
--- Buffer-specific settings that are applied to buffers this plugin controls.
--- @class distnat.plugin.settings.BufferSettings
--- @class distant.plugin.settings.BufferSettings
buffer = {
--- Settings that apply to watching a buffer for remote changes.
--- @class distnat.plugin.settings.buffer.WatchSettings
--- @class distant.plugin.settings.buffer.WatchSettings
watch = {
--- If true, will watch buffers for changes.
--- @type boolean
Expand Down
55 changes: 54 additions & 1 deletion lua/distant/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -513,12 +513,16 @@ end

--- Applies provided settings to overall settings available. By default, this runs asynchronously.
---
--- When given a root-level key with dots, they will be expanded into a nested table. For instance,
--- providing `"buffer.watch.enabled" = true` will get expanded into `{buffer = {watch = {enabled = true}}}`.
---
--- ### Options
---
--- * `verbatim` - if true, will not modify the settings in any way.
--- * `wait` - if provided, will wait up to the specified maximum milliseconds for the setup to complete.
---
--- @param settings distant.plugin.Settings
--- @param opts? {wait?:integer}
--- @param opts? {verbatim?:boolean, wait?:integer}
function M:setup(settings, opts)
-- Ensure something is populated
opts = opts or {}
Expand Down Expand Up @@ -560,6 +564,55 @@ function M:setup(settings, opts)
}
end

-- Transform root settings keys with dots into nested tables
if opts.verbatim ~= true then
for key, value in pairs(settings) do
if type(key) == 'string' then
local tokens = vim.split(key, '.', { plain = true })

-- If we have more than one token, this means there was a dot
if #tokens > 1 then
-- Clear the setting so we can expand it
settings[key] = nil

--- @type table<string, any>
local tbl = settings
for idx, token in ipairs(tokens) do
local is_last = idx == #tokens

-- If we have reached the last part of the path,
-- set it as a key=value in our table
--
-- Otherwise, continue iterating
if is_last then
tbl[token] = value
else
-- If we don't have anything at this point,
-- provide an empty table to fill in
if tbl[token] == nil then
tbl[token] = {}
end

-- If we don't have a table as our value,
-- this is an error and we should fail
if type(tbl[token]) ~= 'table' then
error(
'Cannot overwrite non-table value in path: ' ..
table.concat(tokens, '.', 1, idx)
)
end

-- Otherwise, update our settings to point
-- to the nested table so we can continue
--- @type table<string, any>
tbl = tbl[token]
end
end
end
end
end
end

-- Ensure that we are properly initialized with user-provided settings
self:__setup(settings)

Expand Down
90 changes: 90 additions & 0 deletions spec/unit/distant/plugin_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
local plugin = require('distant')

describe('distant.setup', function()
it('should split keys containing dots into nested tables', function()
local settings = nil

-- Stub out the actual setup logic
--- @diagnostic disable-next-line
plugin.__setup = function(_, _settings)
settings = _settings
end

-- Create a setup where we have tables that exist
-- before and after nested keys to ensure that
-- creating new nested tables and injecting into
-- existing nested tables work
plugin:setup({
-- This will get created from scratch
['path.to.key'] = 123,
-- Create a table to be injected into
other = {
value = true
},
-- This will inject into an existing table
['other.path.to.key'] = {
['hello'] = 'world'
},
-- This will create a table, but it actually
-- injects into the table coming after it in
-- the list
['lazy.path.to.key'] = 'hello',
-- Create a table that comes after injection,
-- but still gets injected into
lazy = {
value = 456
},
-- Demonstrate that multiple nested keys
-- can get merged together
['nested.key'] = 'abc',
['nested.key2'] = 789
})

assert.are.same(settings, {
path = {
to = {
key = 123,
}
},
other = {
path = {
to = {
key = {
hello = 'world'
}
}
},
value = true
},
lazy = {
path = {
to = {
key = 'hello'
}
},
value = 456
},
nested = {
key = 'abc',
key2 = 789
}
})
end)

it('should fail to split keys containing dots if path includes a non-table value', function()
-- Stub out the actual setup logic
--- @diagnostic disable-next-line
plugin.__setup = function()
end

-- Setup with a conflict that is not a table, so we cannot merge
assert.has.error(function()
plugin:setup({
['path.to.key'] = 123,
path = {
to = 'hello'
}
})
end)
end)
end)

0 comments on commit b9f649a

Please sign in to comment.