Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,3 @@ end_of_line = lf
indent_style = tab
insert_final_newline = true
trim_trailing_whitespace = true

[*.lua]
indent_size = 3
indent_style = tab
10 changes: 10 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,13 @@ clean: clear_dependencies
.PHONY: test
test: install_dependencies
$(NVIM_HEADLESS) -c "call Test()"

.PHONY: docs
docs:
@echo "Generating documentation..."
@nvim --headless --noplugin -u ./scripts/minimal-init.lua -c "luafile scripts/minidoc.lua" -c "qa!"

.PHONY: clean
clean:
@echo "Removing temporary directories..."
@rm -rf "/tmp/nvim/site/pack/test/start/mini.doc"
72 changes: 72 additions & 0 deletions doc/modes.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
*modes.nvim* Prismatic line decorations for the adventurous vim user
*Modes*

MIT License Copyright (c) mvllow

==============================================================================

Features:

- Highlight UI elements based on the current mode.

# Setup ~

Modes setup can be called with your `config` table to modify default
behaviour.

See |Modes.config| for `config` options and default values.

------------------------------------------------------------------------------
*default_config*
`default_config`
Module config

Default values:
>lua
local default_config = {
colors = {},
line_opacity = {
copy = 0.15,
delete = 0.15,
change = 0.15,
format = 0.15,
insert = 0.15,
visual = 0.15,
},
set_cursor = true,
set_cursorline = true,
set_number = true,
set_signcolumn = true,
ignore = {
'NvimTree',
'lspinfo',
'packer',
'checkhealth',
'help',
'man',
'TelescopePrompt',
'TelescopeResults',
'!minifiles',
},
}
<
------------------------------------------------------------------------------
*H.highlight()*
`H.highlight`({scene})
highlights
Parameters ~
{scene} '`(default)`'|'copy'|'delete'|'change'|'format'|'insert'|'visual'

------------------------------------------------------------------------------
*Modes.setup()*
`Modes.setup`({opts})
Module setup

Parameters ~
{config} `(table|nil)` Module config table. See |Modes.config|.

Usage ~
`require('modes').setup({})` (replace `{}` with your `config` table)


vim:tw=78:ts=8:noet:ft=help:norl:
5 changes: 5 additions & 0 deletions doc/tags
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
H.highlight() modes.txt /*H.highlight()*
Modes modes.txt /*Modes*
Modes.setup() modes.txt /*Modes.setup()*
default_config modes.txt /*default_config*
modes.nvim modes.txt /*modes.nvim*
97 changes: 65 additions & 32 deletions lua/modes.lua
Original file line number Diff line number Diff line change
@@ -1,7 +1,33 @@
local utils = require('modes.utils')
--- *modes.nvim* Prismatic line decorations for the adventurous vim user
--- *Modes*
---
--- MIT License Copyright (c) mvllow
---
--- ==============================================================================
---
--- Features:
---
--- - Highlight UI elements based on the current mode.
---
--- # Setup ~
---
--- Modes setup can be called with your `config` table to modify default
--- behaviour.
---
--- See |Modes.config| for `config` options and default values.

---@alias Scene 'copy'|'delete'|'insert'|'normal'|'replace'|'visual'

local Modes = {}
local H = {}

local M = {}
local config = {}
local utils = require('modes.utils')

--- Module config
---
--- Default values:
---@eval return MiniDoc.afterlines_to_code(MiniDoc.current.eval_section)
local default_config = {
colors = {},
line_opacity = {
Expand All @@ -28,6 +54,8 @@ local default_config = {
'!minifiles',
},
}
--minidoc_afterlines_end
--
local winhighlight = {
default = {
CursorLine = 'CursorLine',
Expand Down Expand Up @@ -81,24 +109,24 @@ local in_ignored_buffer = function()
return config.ignore()
end
return not vim.tbl_contains(config.ignore, '!' .. vim.bo.filetype)
and (vim.api.nvim_get_option_value('buftype', { buf = 0 }) ~= '' -- not a normal buffer
or not vim.api.nvim_get_option_value('buflisted', { buf = 0 }) -- unlisted buffer
or vim.tbl_contains(config.ignore, vim.bo.filetype))
and (vim.api.nvim_get_option_value('buftype', { buf = 0 }) ~= '' -- not a normal buffer
or not vim.api.nvim_get_option_value('buflisted', { buf = 0 }) -- unlisted buffer
or vim.tbl_contains(config.ignore, vim.bo.filetype))
end

M.reset = function()
M.highlight('default')
H.reset = function()
H.highlight('default')
vim.cmd.redraw()
end

M.restore = function()
local scene = M.get_scene()
M.highlight(scene)
H.restore = function()
local scene = H.get_scene()
H.highlight(scene)
end

---Update highlights
---@param scene 'default'|'copy'|'delete'|'change'|'format'|'insert'|'visual'
M.highlight = function(scene)
H.highlight = function(scene)
if in_ignored_buffer() then
return
end
Expand All @@ -122,7 +150,7 @@ M.highlight = function(scene)
if not config.set_number then
winhl_map.CursorLineNr = nil
elseif not config.set_cursorline then
local detected_scene = M.get_scene()
local detected_scene = H.get_scene()
if scene == 'default' and detected_scene == 'visual' then
winhl_map.CursorLineNr = 'ModesVisualUnfocusedCursorLineNr'
end
Expand Down Expand Up @@ -167,7 +195,7 @@ M.highlight = function(scene)
end
end

M.get_scene = function()
H.get_scene = function()
local mode = vim.api.nvim_get_mode().mode
if mode:match('[iR]') then
return 'insert'
Expand All @@ -179,7 +207,7 @@ M.get_scene = function()
return 'default'
end

M.define = function()
H.define = function()
colors = {
bg = config.colors.bg or utils.get_bg('Normal', 'Normal'),
copy = config.colors.copy or utils.get_bg('ModesCopy', '#f5c359'),
Expand Down Expand Up @@ -278,7 +306,7 @@ M.define = function()
end
end

M.enable_managed_ui = function()
H.enable_managed_ui = function()
if in_ignored_buffer() then
if config.set_cursorline then
vim.o.cursorline = false
Expand All @@ -294,11 +322,11 @@ M.enable_managed_ui = function()
vim.opt.guicursor:append('r-o:ModesOperator')
end

M.restore()
H.restore()
end
end

M.disable_managed_ui = function()
H.disable_managed_ui = function()
if config.set_cursorline then
vim.o.cursorline = false
end
Expand All @@ -315,10 +343,15 @@ M.disable_managed_ui = function()
vim.o.guicursor = cursor
end

M.reset()
H.reset()
end

M.setup = function(opts)
--- Module setup
---
---@param config table|nil Module config table. See |Modes.config|.
---
---@usage `require('modes').setup({})` (replace `{}` with your `config` table)
Modes.setup = function(opts)
opts = vim.tbl_extend('keep', opts or {}, default_config)
if opts.focus_only then
vim.notify(
Expand Down Expand Up @@ -352,13 +385,13 @@ M.setup = function(opts)
}
end

M.define()
M.enable_managed_ui() -- ensure enabled initially
H.define()
H.enable_managed_ui() -- ensure enabled initially

---Reset normal highlight
vim.api.nvim_create_autocmd('ModeChanged', {
pattern = '*:n,*:ni*',
callback = M.reset,
callback = H.reset,
})

---Set operator highlights
Expand All @@ -367,52 +400,52 @@ M.setup = function(opts)
callback = function()
local operator = vim.v.operator
if operator == 'y' then
M.highlight('copy')
H.highlight('copy')
elseif operator == 'd' then
M.highlight('delete')
H.highlight('delete')
elseif operator == 'c' then
M.highlight('change')
H.highlight('change')
elseif operator:match('[=!><g]') then
M.highlight('format')
H.highlight('format')
end
end,
})

---Set highlights when colorscheme changes
vim.api.nvim_create_autocmd('ColorScheme', {
pattern = '*',
callback = M.define,
callback = H.define,
})

---Set insert highlight
vim.api.nvim_create_autocmd('InsertEnter', {
pattern = '*',
callback = function()
M.highlight('insert')
H.highlight('insert')
end,
})

---Set visual highlight
vim.api.nvim_create_autocmd('ModeChanged', {
pattern = '*:[vVsS\x16\x13]',
callback = function()
M.highlight('visual')
H.highlight('visual')
end,
})

---Enable managed UI for current window
vim.api.nvim_create_autocmd({ 'WinEnter', 'FocusGained' }, {
pattern = '*',
callback = function()
vim.schedule(M.enable_managed_ui)
vim.schedule(H.enable_managed_ui)
end,
})

---Disable managed UI
vim.api.nvim_create_autocmd({ 'WinLeave', 'FocusLost' }, {
pattern = '*',
callback = M.disable_managed_ui,
callback = H.disable_managed_ui,
})
end

return M
return Modes
26 changes: 19 additions & 7 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
## Usage

```lua
use({
'mvllow/modes.nvim',
tag = 'v0.2.1',
{
"mvllow/modes.nvim",
tag = "v0.2.1",
config = function()
require('modes').setup()
require("modes").setup()
end
})
}
```

![modes.nvim](https://user-images.githubusercontent.com/1474821/127896095-6da221cf-3327-4eed-82be-ce419bdf647c.gif)
Expand Down Expand Up @@ -53,7 +53,7 @@ require('modes').setup({
-- Disable modes highlights for specified filetypes
-- or enable with prefix "!" if otherwise disabled (please PR common patterns)
-- Can also be a function fun():boolean that disables modes highlights when true
ignore = { 'NvimTree', 'TelescopePrompt', '!minifiles' }
ignore = { "NvimTree", "TelescopePrompt", "!minifiles" }
})
```

Expand All @@ -75,9 +75,21 @@ require('modes').setup({
_Workaround:_

```lua
require('which-key').setup({
require("which-key").setup({
triggers_blacklist = {
n = { "d", "y" }
}
})
```

## Contributing

Pull requests are welcome and appreciated!

### Generating documentation

Run `make docs` or inside of Neovim, with [mini.doc](https://github.com/echasnovski/mini.doc) in your runtimepath:

```lua
:luafile scripts/minidoc.lua
```
17 changes: 17 additions & 0 deletions scripts/minidoc.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
local minidoc = require("mini.doc")

if _G.MiniDoc == nil then
minidoc.setup()
end

local hooks = vim.deepcopy(minidoc.default_hooks)

hooks.write_pre = function(lines)
-- Remove first two lines with `======` and `------` delimiters to comply
-- with `:h local-additions` template
table.remove(lines, 1)
table.remove(lines, 1)
return lines
end

minidoc.generate({ "lua/modes.lua" }, "doc/modes.txt", { hooks = hooks })
Loading