forked from folke/zen-mode.nvim
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit be5b6b6
Showing
8 changed files
with
398 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
local util = require("zen.util") | ||
local M = {} | ||
|
||
--- @type ZenOptions | ||
M.options = {} | ||
|
||
--- @class ZenOptions | ||
local defaults = { | ||
zindex = 40, -- zindex of the zen window. Should be less than 50, which is the float default | ||
window = { | ||
backdrop = 0.95, -- shade the backdrop of the zen window. Set to 1 to keep the same as Normal | ||
-- height and width can be: | ||
-- * an asbolute number of cells when > 1 | ||
-- * a percentage of the width / height of the editor when <= 1 | ||
width = 120, -- width of the zen window | ||
height = 1, -- height of the zen window | ||
-- by default, no options are changed in for the zen window | ||
-- uncomment any of the options below, or add other vim.wo options you want to apply | ||
options = { | ||
-- signcolumn = "no", -- disable signcolumn | ||
-- number = false, -- disable number column | ||
-- relativenumber = false, -- disable relative numbers | ||
-- cursorline = false, -- disable cursorline | ||
-- cursorcolumn = false, -- disable cursor column | ||
-- foldcolumn = "0", -- disable fold column | ||
-- list = false, -- disable whitespace characters | ||
}, | ||
}, | ||
plugins = { | ||
gitsigns = true, -- disables git signs | ||
tmux = true, -- disables the tmux statusline | ||
-- this will change the font size on kitty when in zen mode | ||
-- to make this work, you need to set the following kitty options: | ||
-- - allow_remote_control socket-only | ||
-- - listen_on unix:/tmp/kitty | ||
kitty = { | ||
enabled = false, | ||
font = "+4", -- font size increment | ||
}, | ||
}, | ||
-- callback where you can add custom code when the zen window opens | ||
on_open = function(_win) | ||
end, | ||
-- callback where you can add custom code when the zen window closes | ||
on_close = function() | ||
end, | ||
} | ||
|
||
function M.setup(options) | ||
M.options = vim.tbl_deep_extend("force", {}, defaults, options or {}) | ||
local normal = util.get_hl("Normal") | ||
if normal and normal.background then | ||
local bg = util.darken(normal.background, M.options.window.backdrop) | ||
vim.cmd(("highlight ZenBg guibg=%s guifg=%s"):format(bg, bg)) | ||
end | ||
for plugin, plugin_opts in pairs(M.options.plugins) do | ||
if type(plugin_opts) == "boolean" then | ||
M.options.plugins[plugin] = { enabled = plugin_opts } | ||
end | ||
if M.options.plugins[plugin].enabled == nil then | ||
M.options.plugins[plugin].enabled = true | ||
end | ||
end | ||
end | ||
|
||
M.setup() | ||
|
||
return M |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
local view = require("zen.view") | ||
local config = require("zen.config") | ||
|
||
local M = {} | ||
|
||
M.setup = config.setup | ||
M.toggle = view.toggle | ||
M.open = view.open | ||
M.close = view.close | ||
|
||
function M.reset() | ||
M.close() | ||
require("plenary.reload").reload_module("zen") | ||
require("zen").toggle() | ||
end | ||
|
||
return M |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
local M = {} | ||
|
||
function M.gitsigns(state, disable) | ||
local gs = require("gitsigns") | ||
local config = gs._get_config() | ||
if disable then | ||
state.signcolumn = config.signcolumn | ||
state.numhl = config.numhl | ||
state.linehl = config.linehl | ||
config.signcolumn = false | ||
config.numhl = false | ||
config.linehl = false | ||
else | ||
config.signcolumn = state.signcolumn | ||
config.numhl = state.numhl | ||
config.linehl = state.linehl | ||
end | ||
gs.refresh() | ||
end | ||
|
||
-- changes the kitty font size | ||
-- it's a bit glitchy, but it works | ||
function M.kitty(state, disable, opts) | ||
if not vim.fn.executable("kitty") then | ||
return | ||
end | ||
local cmd = "kitty @ --to %s set-font-size %s" | ||
local socket = vim.fn.expand("$KITTY_LISTEN_ON") | ||
if disable then | ||
vim.fn.system(cmd:format(socket, opts.font)) | ||
else | ||
vim.fn.system(cmd:format(socket, "0")) | ||
end | ||
vim.cmd([[redraw]]) | ||
end | ||
|
||
function M.tmux(state, disable, opts) | ||
if not vim.env.TMUX then | ||
return | ||
end | ||
if disable then | ||
vim.fn.system([[tmux set -g status off]]) | ||
else | ||
vim.fn.system([[tmux set -g status on]]) | ||
end | ||
end | ||
|
||
return M |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
local M = {} | ||
|
||
function M.get_hl(name) | ||
local ok, hl = pcall(vim.api.nvim_get_hl_by_name, name, true) | ||
if not ok then | ||
return | ||
end | ||
for _, key in pairs({ "foreground", "background", "special" }) do | ||
if hl[key] then | ||
hl[key] = string.format("#%06x", hl[key]) | ||
end | ||
end | ||
return hl | ||
end | ||
|
||
function M.hex2rgb(hex) | ||
hex = hex:gsub("#", "") | ||
return tonumber("0x" .. hex:sub(1, 2)), tonumber("0x" .. hex:sub(3, 4)), tonumber("0x" .. hex:sub(5, 6)) | ||
end | ||
|
||
function M.rgb2hex(r, g, b) | ||
return string.format("#%02x%02x%02x", r, g, b) | ||
end | ||
|
||
function M.darken(hex, amount) | ||
local r, g, b = M.hex2rgb(hex) | ||
return M.rgb2hex(r * amount, g * amount, b * amount) | ||
end | ||
|
||
function M.is_dark(hex) | ||
local r, g, b = M.hex2rgb(hex) | ||
local lum = (0.299 * r + 0.587 * g + 0.114 * b) / 255 | ||
return lum <= 0.5 | ||
end | ||
|
||
function M.log(msg, hl) | ||
vim.api.nvim_echo({ { "Todo: ", hl }, { msg } }, true, {}) | ||
end | ||
|
||
function M.warn(msg) | ||
M.log(msg, "WarningMsg") | ||
end | ||
|
||
function M.error(msg) | ||
M.log(msg, "ErrorMsg") | ||
end | ||
|
||
return M |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,211 @@ | ||
local config = require("zen.config") | ||
local plugins = require("zen.plugins") | ||
local M = {} | ||
|
||
M.bg_win = nil | ||
M.bg_buf = nil | ||
M.win = nil | ||
--- @type ZenOptions | ||
M.opts = nil | ||
M.state = {} | ||
M.closed = false | ||
|
||
function M.is_open() | ||
return M.win and vim.api.nvim_win_is_valid(M.win) | ||
end | ||
|
||
function M.plugins_on_open() | ||
for name, opts in pairs(M.opts.plugins) do | ||
if opts and opts.enabled then | ||
local plugin = plugins[name] | ||
M.state[name] = {} | ||
pcall(plugin, M.state[name], true, opts) | ||
end | ||
end | ||
end | ||
|
||
function M.plugins_on_close() | ||
for name, opts in pairs(M.opts.plugins) do | ||
if opts and opts.enabled then | ||
local plugin = plugins[name] | ||
pcall(plugin, M.state[name], false, opts) | ||
end | ||
end | ||
end | ||
|
||
function M.close() | ||
pcall(vim.cmd, [[autocmd! Zen]]) | ||
pcall(vim.cmd, [[augroup! Zen]]) | ||
if M.win and vim.api.nvim_win_is_valid(M.win) then | ||
vim.api.nvim_win_close(M.win, { force = true }) | ||
M.win = nil | ||
end | ||
if M.bg_win and vim.api.nvim_win_is_valid(M.bg_win) then | ||
vim.api.nvim_win_close(M.bg_win, { force = true }) | ||
M.bg_win = nil | ||
end | ||
if M.bg_buf and vim.api.nvim_buf_is_valid(M.bg_buf) then | ||
vim.api.nvim_buf_delete(M.bg_buf, { force = true }) | ||
M.bg_buf = nil | ||
end | ||
if M.opts then | ||
M.plugins_on_close() | ||
M.opts.on_close() | ||
M.opts = nil | ||
end | ||
end | ||
|
||
function M.open(opts) | ||
if not M.is_open() then | ||
-- close any possible remnants from a previous session | ||
-- shouldn't happen, but just in case | ||
M.close() | ||
M.create(opts) | ||
end | ||
end | ||
|
||
function M.toggle(opts) | ||
if M.is_open() then | ||
M.close() | ||
else | ||
M.open(opts) | ||
end | ||
end | ||
|
||
function M.round(num) | ||
return math.floor(num + 0.5) | ||
end | ||
|
||
--- @param opts ZenOptions | ||
function M.layout(opts) | ||
local width = vim.o.columns | ||
if opts.window.width > 1 then | ||
width = opts.window.width | ||
else | ||
width = width * opts.window.width | ||
end | ||
width = math.min(width, vim.o.columns) | ||
|
||
local height = vim.o.lines | ||
if opts.window.height > 1 then | ||
height = opts.window.height | ||
else | ||
height = height * opts.window.height | ||
end | ||
height = math.min(height, vim.o.lines) | ||
|
||
return { | ||
width = M.round(width), | ||
height = M.round(height), | ||
col = M.round((vim.o.columns - width) / 2), | ||
row = M.round((vim.o.lines - height) / 2), | ||
} | ||
end | ||
|
||
-- adjusts col/row if window was resized | ||
function M.fix_layout(win_resized) | ||
if M.is_open() then | ||
if win_resized then | ||
vim.api.nvim_win_set_config(M.bg_win, { width = vim.o.columns, height = vim.o.lines }) | ||
end | ||
local height = vim.api.nvim_win_get_height(M.win) | ||
local width = vim.api.nvim_win_get_width(M.win) | ||
local col = M.round((vim.o.columns - width) / 2) | ||
local row = M.round((vim.o.lines - height) / 2) | ||
local cfg = vim.api.nvim_win_get_config(M.win) | ||
-- HACK: col is an array? | ||
local wcol = type(cfg.col) == "number" and cfg.col or cfg.col[false] | ||
local wrow = type(cfg.row) == "number" and cfg.row or cfg.row[false] | ||
if wrow ~= row or wcol ~= col then | ||
vim.api.nvim_win_set_config(M.win, { col = col, row = row, relative = "editor" }) | ||
end | ||
end | ||
end | ||
|
||
--- @param opts ZenOptions | ||
function M.create(opts) | ||
opts = vim.tbl_deep_extend("force", {}, config.options, opts or {}) | ||
M.opts = opts | ||
M.state = {} | ||
|
||
M.bg_buf = vim.api.nvim_create_buf(false, true) | ||
M.bg_win = vim.api.nvim_open_win(M.bg_buf, false, { | ||
relative = "editor", | ||
width = vim.o.columns, | ||
height = vim.o.lines, | ||
focusable = false, | ||
row = 0, | ||
col = 0, | ||
style = "minimal", | ||
zindex = opts.zindex - 10, | ||
}) | ||
M.fix_hl(M.bg_win, "ZenBg") | ||
|
||
local win_opts = vim.tbl_extend("keep", { | ||
relative = "editor", | ||
zindex = opts.zindex, | ||
}, M.layout(opts)) | ||
|
||
local buf = vim.api.nvim_get_current_buf() | ||
M.win = vim.api.nvim_open_win(buf, true, win_opts) | ||
vim.cmd([[norm! zz]]) | ||
M.fix_hl(M.win) | ||
|
||
for k, v in pairs(opts.window.options or {}) do | ||
vim.api.nvim_win_set_option(M.win, k, v) | ||
end | ||
|
||
M.plugins_on_open() | ||
if type(opts.on_open) == "function" then | ||
opts.on_open(M.win) | ||
end | ||
|
||
-- fix layout since some plugins might have altered the window | ||
M.fix_layout() | ||
|
||
-- TODO: listen for WinNew and BufEnter. When a new window, or bufenter in a new window, close zen mode | ||
-- unless it's in a float | ||
-- TODO: when the cursor leaves the window, we close zen mode, or prevent leaving the window | ||
local augroup = [[ | ||
augroup Zen | ||
autocmd! | ||
autocmd WinClosed %d ++once ++nested lua require("zen.view").close() | ||
autocmd WinEnter * lua require("zen.view").on_win_enter() | ||
autocmd CursorMoved * lua require("zen.view").fix_layout() | ||
autocmd VimResized * lua require("zen.view").fix_layout(true) | ||
autocmd CursorHold * lua require("zen.view").fix_layout() | ||
autocmd BufWinEnter %d lua require("zen.view").on_buf_win_enter() | ||
augroup end]] | ||
|
||
vim.api.nvim_exec(augroup:format(M.win, M.win), false) | ||
end | ||
|
||
function M.fix_hl(win, normal) | ||
normal = normal or "Normal" | ||
vim.api.nvim_win_set_option(win, "winhighlight", "NormalFloat:" .. normal) | ||
vim.api.nvim_win_set_option(win, "fcs", "eob: ") | ||
end | ||
|
||
function M.is_float(win) | ||
local opts = vim.api.nvim_win_get_config(win) | ||
return opts and opts.relative and opts.relative ~= "" | ||
end | ||
|
||
function M.on_buf_win_enter() | ||
-- M.fix_hl(M.win) | ||
end | ||
|
||
function M.on_win_enter() | ||
local win = vim.api.nvim_get_current_win() | ||
if win ~= M.win and not M.is_float(win) then | ||
-- HACK: when returning from a float window, vim initially enters the parent window. | ||
-- give 10ms to get back to the zen window before closing | ||
vim.defer_fn(function() | ||
if vim.api.nvim_get_current_win() ~= M.win then | ||
M.close() | ||
end | ||
end, 10) | ||
end | ||
end | ||
|
||
return M |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
std="lua51+vim" |
Oops, something went wrong.