Skip to content

Commit c4068a2

Browse files
authored
Merge pull request #453 from CKolkey/add_settings
Initial implementation for persisting state
2 parents 7be1e93 + 029726a commit c4068a2

File tree

6 files changed

+127
-2
lines changed

6 files changed

+127
-2
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,13 @@ neogit.setup {
129129
console_timeout = 2000,
130130
-- Automatically show console if a command takes more than console_timeout milliseconds
131131
auto_show_console = true,
132+
-- Persist the values of switches/options within and across sessions
133+
remember_settings = true,
134+
-- Scope persisted settings on a per-project basis
135+
use_per_project_settings = true,
136+
-- Array-like table of settings to never persist. Uses format "Filetype--cli-value"
137+
-- ie: `{ "NeogitCommitPopup--author", "NeogitCommitPopup--no-verify" }`
138+
ignored_settings = {},
132139
-- Change the default way of opening the commit popup
133140
commit_popup = {
134141
kind = "split",

lua/neogit.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ local lib = require("neogit.lib")
44
local signs = require("neogit.lib.signs")
55
local hl = require("neogit.lib.hl")
66
local status = require("neogit.status")
7+
local state = require("neogit.lib.state")
78

89
local neogit = {
910
lib = require("neogit.lib"),
@@ -57,6 +58,7 @@ local neogit = {
5758
config.values.mappings.status["p"] = ""
5859
end
5960
hl.setup()
61+
state.setup()
6062

6163
require("neogit.autocmds").setup()
6264
end,

lua/neogit/config.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ M.values = {
77
disable_commit_confirmation = false,
88
disable_builtin_notifications = false,
99
disable_insert_on_commit = true,
10+
use_per_project_settings = true,
11+
remember_settings = true,
1012
use_magit_keybindings = false,
1113
auto_refresh = true,
1214
sort_branches = "-committerdate",
@@ -61,6 +63,7 @@ M.values = {
6163
folded = true,
6264
},
6365
},
66+
ignored_settings = {},
6467
mappings = {
6568
status = {
6669
["q"] = "Close",

lua/neogit/lib/popup.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ local Ui = require("neogit.lib.ui")
55
local logger = require("neogit.logger")
66
local util = require("neogit.lib.util")
77
local config = require("neogit.config")
8+
local state = require("neogit.lib.state")
89

910
local col = Ui.col
1011
local row = Ui.row
@@ -86,6 +87,7 @@ function M:toggle_switch(switch)
8687
return c.options.id == switch.id
8788
end)
8889
c.options.highlight = get_highlight_for_switch(switch)
90+
state.set({ self.state.name, switch.cli }, switch.enabled)
8991
self.buffer.ui:update()
9092
end
9193

@@ -100,6 +102,7 @@ function M:set_option(option)
100102
end)
101103
c.options.highlight = get_highlight_for_option(option)
102104
c.children[#c.children].value = option.value
105+
state.set({ self.state.name, option.cli }, option.value)
103106
self.buffer.ui:update()
104107
end
105108

lua/neogit/lib/popup/builder.lua

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
local a = require("plenary.async")
2+
local state = require("neogit.lib.state")
23

34
local M = {}
45

@@ -50,7 +51,7 @@ function M:switch(key, cli, description, enabled, parse)
5051
key = key,
5152
cli = cli,
5253
description = description,
53-
enabled = enabled,
54+
enabled = state.get({ self.state.name, cli }, enabled),
5455
parse = parse,
5556
})
5657

@@ -62,7 +63,7 @@ function M:option(key, cli, value, description)
6263
id = "=" .. key,
6364
key = key,
6465
cli = cli,
65-
value = value,
66+
value = state.get({ self.state.name, cli }, value),
6667
description = description,
6768
})
6869

lua/neogit/lib/state.lua

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
local logger = require("neogit.logger")
2+
local config = require("neogit.config")
3+
local Path = require("plenary.path")
4+
5+
local M = {}
6+
7+
M.loaded = false
8+
9+
local function log(message)
10+
logger.debug("State: " .. message .. ": '" .. M.path:absolute() .. "'")
11+
end
12+
13+
---@return Path
14+
function M.filepath()
15+
local base_path = vim.fn.stdpath("state") .. "/neogit/"
16+
local filename = "state"
17+
18+
if config.values.use_per_project_settings then
19+
filename = vim.loop.cwd():gsub("/", "%%")
20+
end
21+
22+
return Path:new(base_path .. filename)
23+
end
24+
25+
---Initializes state
26+
function M.setup()
27+
if M.loaded then
28+
return
29+
end
30+
31+
M.path = M.filepath()
32+
M.loaded = true
33+
M.state = M.read()
34+
log("Loaded")
35+
end
36+
37+
---@return boolean
38+
function M.enabled()
39+
return M.loaded and config.values.remember_settings
40+
end
41+
42+
---Reads state from disk
43+
---@return table
44+
function M.read()
45+
if not M.enabled() then
46+
return {}
47+
end
48+
49+
if not M.path:exists() then
50+
log("Creating file")
51+
M.path:touch { parents = true }
52+
M.path:write(vim.mpack.encode {}, "w")
53+
end
54+
55+
log("Reading file")
56+
return vim.mpack.decode(M.path:read())
57+
end
58+
59+
---Writes state to disk
60+
function M.write()
61+
if not M.enabled() then
62+
return
63+
end
64+
65+
log("Writing file")
66+
M.path:write(vim.mpack.encode(M.state), "w")
67+
end
68+
69+
---Construct a cache-key from a table
70+
---@param key_table table
71+
---@return string
72+
local function gen_key(key_table)
73+
return table.concat(key_table, "--")
74+
end
75+
76+
---Set option and write to disk
77+
---@param key table
78+
---@param value any
79+
function M.set(key, value)
80+
if not M.enabled() then
81+
return
82+
end
83+
84+
if not vim.tbl_contains(config.values.ignored_settings, gen_key(key)) then
85+
M.state[gen_key(key)] = value
86+
M.write()
87+
end
88+
end
89+
90+
---Get option. If value isn't set, return provided default.
91+
---@param key table
92+
---@param default any
93+
---@return any
94+
function M.get(key, default)
95+
if not M.enabled() then
96+
return default
97+
end
98+
99+
return M.state[gen_key(key)] or default
100+
end
101+
102+
---Reset current state, removing whats written to disk
103+
function M._reset()
104+
log("Reset file")
105+
M.path:write(vim.mpack.encode {}, "w")
106+
M.state = {}
107+
end
108+
109+
return M

0 commit comments

Comments
 (0)