Skip to content

Commit

Permalink
feat(Commands): adds user commands to interact with the plugin
Browse files Browse the repository at this point in the history
Several commands are added:

ReactiveStart - starts listeners (for mode/window changes)
ReactiveStop - remove all listeners
ReactiveToggle - toggles state between above 2 commands

Reactive enable <preset>
Reactive disable <preset>
Reactive toggle <preset>

These 3 commands help to enable/disable presets right from the command line
  • Loading branch information
rasulomaroff committed Sep 28, 2023
1 parent 3d99a2c commit c2d15c1
Show file tree
Hide file tree
Showing 2 changed files with 162 additions and 62 deletions.
161 changes: 161 additions & 0 deletions lua/reactive/commands.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
local api = vim.api
local aucmd = api.nvim_create_autocmd
local user_cmd = api.nvim_create_user_command

local M = {
listeners_initialized = nil,
}

---@param line string
---@return string[]
local function parse_cmd(line)
local cmd_parts = vim.split(vim.trim(line), '%s+')

if cmd_parts[1]:find 'Reactive' then
table.remove(cmd_parts, 1)
end

if line:sub(-1) == ' ' then
table.insert(cmd_parts, '')
end

return cmd_parts
end

M.commands = {
-- todo:
-- health = function() end,
enable = function(preset)
require('reactive.state'):enable_preset(preset)
end,
toggle = function(preset)
require('reactive.state'):toggle_preset(preset)
end,
disable = function(preset)
require('reactive.state'):disable_preset(preset)
end,
}

M.cached_presets = {}

function M:init()
local function init_listeners()
if self.listeners_initialized then
return
end
self.listeners_initialized = true

local group = api.nvim_create_augroup('reactive.nvim', { clear = true })

local Highlight = require 'reactive.highlight'
local Snapshot = require 'reactive.snapshot'

aucmd('ModeChanged', {
group = group,
pattern = '*:*',
desc = 'Reactive: watches for mode changes to update highlights and run callbacks',
callback = function(opts)
local from, to = unpack(vim.split(opts.match, ':'))

Snapshot:set_modes(from, to)

Highlight:apply(Snapshot:gen())
end,
})

-- We need BufWinEnter event to successfully handle cases where you open a window
-- then through telescope go to another one and then go back through Ctrl + o
aucmd({ 'WinEnter', 'BufWinEnter' }, {
group = group,
desc = 'Reactive: applies active window highlights',
callback = function()
Highlight:apply(Snapshot:gen())
end,
})

aucmd('WinLeave', {
group = group,
desc = 'Reactive: applies inactive window highlights',
callback = function()
Highlight:apply(Snapshot:gen(true))
end,
})
end

local function clear_listeners()
if not self.listeners_initialized then
return
end
self.listeners_initialized = nil

vim.api.nvim_del_augroup_by_name 'reactive.nvim'

local Snapshot = require 'reactive.snapshot'

for hl in pairs(Snapshot.cache.applied_hl) do
vim.cmd('highlight clear ' .. hl)
end

Snapshot:clear_cache()
end

local function toggle_listeners()
if self.listeners_initialized then
clear_listeners()
else
init_listeners()
end
end

init_listeners()

user_cmd('ReactiveStart', init_listeners, {})
user_cmd('ReactiveStop', clear_listeners, {})
user_cmd('ReactiveToggle', toggle_listeners, {})
user_cmd('Reactive', function(opts)
local cmd, val = unpack(vim.split(vim.trim(opts.args), '%s+'))

if not self.commands[cmd] then
vim.notify('reactive.nvim: There\'s no such a command: ' .. cmd, vim.log.levels.ERROR)
elseif not require('reactive.state').presets[val] then
vim.notify('reactive.nvim: There\'s no such a preset: ' .. val, vim.log.levels.ERROR)
else
self.commands[cmd](val)
end
end, {
complete = function(_, line)
local cmd = parse_cmd(line)

if #cmd == 1 then
-- we only do this once
if cmd[1] == '' then
local State = require 'reactive.state'
local Util = require 'reactive.util'

self.cached_presets.toggle = {}
self.cached_presets.enable = {}
self.cached_presets.disable = {}

Util.each(State.presets, function(name, preset)
table.insert(self.cached_presets.toggle, name)

if preset.lazy == true then
table.insert(self.cached_presets.enable, name)
else
table.insert(self.cached_presets.disable, name)
end
end)
end

return vim.tbl_keys(M.commands)
end

if #cmd > 1 and M.commands[cmd[1]] then
return self.cached_presets[cmd[1]]
end
end,
nargs = '?',
})
end

return M
63 changes: 1 addition & 62 deletions plugin/reactive.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,65 +3,4 @@ if vim.g.loaded_reactive then
end
vim.g.loaded_reactive = true

local api = vim.api
local aucmd = api.nvim_create_autocmd

local function clear_aucmds()
-- pcall to prevent errors when double disabling a plugin
local ok = pcall(api.nvim_del_augroup_by_name, 'reactive.nvim')

if not ok then
return
end

local Snapshot = require 'reactive.snapshot'

for hl in pairs(Snapshot.cached_hl) do
vim.cmd('highlight clear ' .. hl)
end

Snapshot.cached_hl = {}
end

local function init_aucmds()
local group = api.nvim_create_augroup('reactive.nvim', { clear = true })

local Highlight = require 'reactive.highlight'
local Snapshot = require 'reactive.snapshot'

aucmd('ModeChanged', {
group = group,
pattern = '*:*',
desc = 'Reactive: watches for mode changes to update highlights and run callbacks',
callback = function(opts)
local from, to = unpack(vim.split(opts.match, ':'))

Snapshot:set_modes(from, to)

Highlight:apply(Snapshot:gen())
end,
})

-- We need BufWinEnter event to successfully handle cases where you open a window
-- then through telescope go to another one and then go back through Ctrl + o
aucmd({ 'WinEnter', 'BufWinEnter' }, {
group = group,
desc = 'Reactive: applies active window highlights',
callback = function()
Highlight:apply(Snapshot:gen())
end,
})

aucmd('WinLeave', {
group = group,
desc = 'Reactive: applies inactive window highlights',
callback = function()
Highlight:apply(Snapshot:gen(true))
end,
})
end

init_aucmds()

api.nvim_create_user_command('ReactiveEnable', init_aucmds, {})
api.nvim_create_user_command('ReactiveDisable', clear_aucmds, {})
require('reactive.commands'):init()

0 comments on commit c2d15c1

Please sign in to comment.