generated from ellisonleao/nvim-plugin-template
-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathinit.lua
More file actions
624 lines (562 loc) · 24.3 KB
/
init.lua
File metadata and controls
624 lines (562 loc) · 24.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
local defaults = require("checkmate.config.defaults")
local validate = require("checkmate.config.validate")
---@class checkmate.Config.mod
local M = {}
M.ns = vim.api.nvim_create_namespace("checkmate")
-- extmarks for specifically tracking todos (i.e. their "stable" ids)
M.ns_todos = vim.api.nvim_create_namespace("checkmate_todos")
-- primary highlights namespace
M.ns_hl = vim.api.nvim_create_namespace("checkmate_hl")
-- Buffer local checkmate state
-- e.g. `vim.b[bufnr]._checkmate`
M.buffer_local_ns = "_checkmate"
M._state = {
user_style = nil, -- Track user-provided style settings (to reapply after colorscheme changes)
}
-- The active configuration
---@type checkmate.Config
---@diagnostic disable-next-line: missing-fields
M.options = {}
-----------------------------------------------------
---Checkmate configuration
---@class checkmate.Config
---
---Whether the plugin is enabled
---@field enabled boolean
---
---Whether to show notifications
---@field notify boolean
---
--- Filenames or patterns to activate Checkmate on when the filetype is 'markdown'
---
--- Uses Unix-style glob patterns with the following rules:
--- - Patterns are CASE-SENSITIVE (e.g., "TODO" won't match "todo")
--- - Basename patterns (no slash): Match against filename only
--- - "TODO" matches any file named "TODO" regardless of path
--- - "*.md" matches any markdown file in any directory
--- - "*todo*" matches any file with "todo" in the name
--- - Path patterns (has slash):
--- - "docs/*.md" matches markdown files in any "docs" directory
--- - "/home/user/*.md" matches only in that specific directory (absolute)
--- - Both "docs/*.md" and "**/docs/*.md" behave the same (match at any depth)
--- - Glob syntax (refer to `h: vim.glob`):
--- - `*` matches any characters except /
--- - `**` matches any characters including / (recursive)
--- - `?` matches any single character
--- - `[abc]` matches any character in the set
--- - `{foo,bar}` matches either "foo" or "bar"
---
--- Examples:
--- - {"TODO", "todo"} - files named TODO (case variations)
--- - {"*.md"} - all markdown files
--- - {"*todo*", "*TODO*"} - files with "todo" in the name
--- - {"docs/*.md", "notes/*.md"} - markdown in specific directories
--- - {"project/**/todo.md"} - todo.md under any project directory
---@field files string[]
---
---Logging settings
---@field log checkmate.LogSettings
---
---Define the keymap as a dict-style table or a sequence of { rhs, desc, { modes } }
---See `h: vim.set.keymap` for how 'rhs' is treated, including being able to pass a Lua function directly
---Default modes is {"n"}
---@alias checkmate.KeymapConfig {rhs: string|function, desc?: string, modes?: string[]} | table<integer, any>
---
---Keymappings (false to disable)
---
---Setting `keys` to false will not register any keymaps.
---
---IMPORTANT: This table overwrites the defaults (does not merge). If you make edits
---and want to keep some defaults, you will need to copy the default configuration
---into your own `keys` table.
---
---Note: mappings for metadata are set separately in the `metadata` table
---@field keys ( table<string, checkmate.KeymapConfig>| false )
---
---The states that a todo item may have
---Default: "unchecked" and "checked"
---Note that Github-flavored Markdown specification only includes "checked" and "unchecked".
---
---If you add additional states here, they may not work in other Markdown apps without special configuration.
---@field todo_states table<string, checkmate.TodoStateDefinition>
---
---Default list item marker to be used when creating new Todo items
---@field default_list_marker "-" | "*" | "+"
---
---@field ui? checkmate.UISettings
---
---Highlight settings (merges with defaults, user config takes precedence)
---Default style will attempt to integrate with current colorscheme
---
---#### Disabling highlights
---To disable *all* checkmate.nvim highlight groups, set to false. _This will include metadata highlighting_.
---This may be helpful when integrating with Markdown rendering plugins.
---@field style? checkmate.StyleSettings|false
---
---Enter insert mode after `:Checkmate create`, require("checkmate").create()
---Default: true
---@field enter_insert_after_new boolean
---
---List continuation refers to the automatic creation of new todo lines when insert mode keymaps are fired, i.e., typically <CR>
---This does not apply to regular list items (you would need to implement your own or use a separate plugin)
---
---To offer optimal configurability and integration with other plugins, you can set the exact keymaps and their functions via the `keys` option.
---The list continuation functionality can also be toggled via the `enabled` option.
--- - When enabled and keymap calls `create()`, it will create a new todo line, using the origin/current row with reasonable defaults
--- - Works for both raw Markdown (e.g. `- [ ]`) and Unicode style (e.g. `- ☐`) todos.
---@field list_continuation checkmate.ListContinuationSettings
---
---Smart toggle provides intelligent parent-child todo state propagation
---
---When you change a todo's state, it can automatically update related todos based on their
---hierarchical relationship. Only "checked" and "unchecked" states are propagated - custom
---states remain unchanged but influence the propagation logic based on their type.
---@field smart_toggle checkmate.SmartToggleSettings
---
---Enable/disable the todo count indicator (shows number of child todo items incomplete vs complete)
---@field show_todo_count boolean
---
---Options for todo count indicator position
---@alias checkmate.TodoCountPosition "eol" | "inline"
---
---Position to show the todo count indicator (if enabled)
--- `eol` = End of the todo item line
--- `inline` = After the todo marker, before the todo item text
---@field todo_count_position checkmate.TodoCountPosition
---
---Formatter function for displaying the todo count indicator
---@field todo_count_formatter? fun(completed: integer, total: integer): string
---
---Whether to count child todo items recursively in the todo_count
---If true, all nested todo items will count towards the parent todo's count
---@field todo_count_recursive boolean
---
---Whether to register keymappings defined in each metadata definition.
---When false, default metadata keymaps are not created; you can still call require('checkmate').toggle_metadata() or bind keys manually.
---@field use_metadata_keymaps boolean
---
---Custom @tag(value) fields that can be toggled on todo items
---To add custom metadata tag, add a new field to this table with the metadata properties
---
---Note: When setting metadata in config, entire metadata entries are replaced,
---not deep-merged. To modify only specific fields of default metadata,
---you will need to manually merge the default implementation.
---@field metadata checkmate.Metadata
---
---Settings for the archived todos section
---@field archive checkmate.ArchiveSettings?
---
---Config for the linter
---@field linter checkmate.LinterConfig?
---
---Turn off treesitter highlights (on by default)
---Buffer local (for Checkmate buffers)
---See `:h treesitter-highlight`
---@field disable_ts_highlights? boolean
-----------------------------------------------------
---@class checkmate.LogSettings
--- Any messages above this level will be logged
---@field level ("trace" | "debug" | "info" | "warn" | "error" | "fatal" | vim.log.levels.DEBUG | vim.log.levels.ERROR | vim.log.levels.INFO | vim.log.levels.TRACE | vim.log.levels.WARN)?
---
--- Should print log output to a file
--- Default: true
---@field use_file boolean
---
--- The default path on-disk where log files will be written to.
--- Defaults to `vim.fn.stdpath("log") .. "checkmate.log"`
---@field file_path string?
---
--- Max file size (kilobytes)
--- When file size exceeds max, a new file will be overwritten
--- Default: 5120 kb (5 mb)
---@field max_file_size? number
-----------------------------------------------------
---The broad categories used internally that give semantic meaning to each todo state
---See details in checkmate.TodoStateDefinition |type|
---@alias checkmate.TodoStateType "incomplete" | "complete" | "inactive"
---@class checkmate.TodoStateDefinition
---
--- The glyph or text string used for a todo marker is expected to be 1 character length.
--- Multiple characters _may_ work but are not currently supported and could lead to unexpected results.
---@field marker string
---
--- Markdown checkbox representation (custom states only)
--- For custom states, this determines how the todo state is written to file in Markdown syntax.
--- Important:
--- - Must be unique among all todo states. If two states share the same Markdown representation, there will
--- be unpredictable behavior when parsing the Markdown into the Checkmate buffer
--- - Not guaranteed to work in other apps/plugins as custom `[.]`, `[/]`, etc. are not standard Github-flavored Markdown
--- - This field is ignored for default `checked` and `unchecked` states as these are always represented per Github-flavored
--- Markdown spec, e.g. `[ ]` and `[x]`
---@field markdown string | string[]
---
--- Defines how a custom todo state relates to an intended task (custom states only)
---
--- The helps the custom state integrate with plugin behaviors like `smart toggle` and `todo count indicator`.
---
--- Options:
--- - "incomplete" - active/ongoing task (like unchecked)
--- - "complete" - finished task (like checked)
--- - "inactive" - paused/deferred task (neither)
---
--- Defaults:
--- - the "checked" state is always "complete" and the "unchecked" state is always "incomplete"
--- - custom states without a defined `type` will default to "inactive"
---@field type? checkmate.TodoStateType
---
--- The order in which this state is cycled (lower = first)
---@field order? number
-----------------------------------------------------
---@class checkmate.UISettings
---
---Sets the default picker
---Default behavior: attempt to use an installed plugin, if found
--- - see `checkmate.Picker` values
---If nil or "native", will use vim.ui.select
---
---Note, some Checkmate API functions provide additional levels of picker configuration that
---may override or bypass this option:
--- - `picker_opts`: used to set picker and opts for that call. See `checkmate.PickerOpts`
--- - `custom_picker`: a function that receives Checkmate data and a `complete(value)` callback that can be used
--- to run an arbitrary picker and run the Checkmate behavior on complete()
---@field picker? checkmate.Picker
-----------------------------------------------------
---@class checkmate.ListContinuationSettings
---
--- Whether to enable list continuation behavior
---
--- Default: true
---@field enabled? boolean
---
--- Control behavior when cursor is mid-line (not at the end).
---
--- When `true` (default):
--- - Text after cursor moves to the new todo line
--- - Original line is truncated at cursor position
--- - Example: "- ☐ Buy |milk and eggs" → "- ☐ Buy" + "- ☐ milk and eggs"
---
--- When `false`:
--- - List continuation only works when cursor is at end of line
---
--- Default: true
---@field split_line? boolean
---
--- Define which keys trigger list continuation and their behavior.
---
--- Each key can map to either:
--- - A function that creates the new todo
--- - A table with `rhs` (function) and optional `desc` (description)
---
--- Default keys:
--- - `<CR>`: Create sibling todo (same indentation)
--- - `<S-CR>`: Create nested todo (indented as child)
---
--- **Important**: This field completely replaces the default keys (no merging).
--- To keep some defaults while adding custom keys, explicitly include them in your config.
---@field keys? table<string, {rhs: function, desc?: string}|function>
---
-----------------------------------------------------
---@class checkmate.SmartToggleSettings
---
---Whether to enable smart toggle behavior
---
---What is 'smart toggle'?
--- - Attempts to propagate a change in state (i.e. checked ←→ unchecked) up and down the hierarchy in a intelligent manner
--- - E.g., if all children have just become checked, then check the parent too.
--- - In this mode, changing the state of a todo maybe also affect nearby todos
---Default: true
---@field enabled boolean?
---
---Whether to use smart toggle behavior with `cycle` commands/API
---
---If enabled, this may inadvertently toggle nearby todos as you cycle through, depending on `smart_toggle` rules.
---If you would like to cascade/propagate when setting a custom state, use the `toggle(target_state)` api.
---
---Default: false (cycling through states won't trigger propagation)
---@field include_cycle boolean?
---
---How checking a parent affects its children
--- - "all_children": Check all descendants, including nested
--- - "direct_children": Only check immediate unchecked children (default)
--- - "none": Don't propagate down
---@field check_down "all_children"|"direct_children"|"none"?
---
---How unchecking a parent affects its children
--- - "all_children": Uncheck all descendants, including nested
--- - "direct_children": Only uncheck immediate checked children
--- - "none": Don't propagate down (default)
---@field uncheck_down "all_children"|"direct_children"|"none"?
---
---When a parent should become checked
---i.e, how a checked child affects its parent
---
---Note: Custom states with "complete" type count as done, "incomplete" as not done,
---and "inactive" states are ignored (as if they don't exist for completion purposes).
---
--- - "all_children": When ALL descendants are complete or inactive, including nested
--- - "direct_children": When all immediate children are complete/inactive (default)
--- - "none": Never auto-check parents
---@field check_up "all_children"|"direct_children"|"none"?
---
---When a parent should become unchecked
---i.e, how a unchecked child affects its parent
--- - "all_children": When ANY descendant is incomplete
--- - "direct_children": When any immediate child is incomplete (default)
--- - "none": Never auto-uncheck parents
---@field uncheck_up "all_children"|"direct_children"|"none"?
-----------------------------------------------------
--- Style
---@alias checkmate.HighlightGroup
---| "CheckmateListMarkerUnordered" -- unordered list markers (-,+,*)
---| "CheckmateListMarkerOrdered" -- ordered (numerical) list markers (1.,2.)
---| "CheckmateUncheckedMarker" -- unchecked markers (□)
---| "CheckmateUncheckedMainContent" -- main content of unchecked todo items (typically 1st paragraph)
---| "CheckmateUncheckedAdditionalContent" -- additional content of unchecked todo items (subsequent paragraphs or list items)
---| "CheckmateCheckedMarker" -- checked markers (✔)
---| "CheckmateCheckedMainContent" -- main content of checked todo items (typically 1st paragraph)
---| "CheckmateCheckedAdditionalContent" -- additional content of checked todo items (subsequent paragraphs or list items)
---| "CheckmateTodoCountIndicator" -- the todo count indicator (e.g. x/x)
---Customize the style of markers and content
---@alias checkmate.StyleSettings table<checkmate.HighlightGroup, vim.api.keyset.highlight>
-----------------------------------------------------
--- Metadata
---A table of canonical metadata tag names and associated properties that define the look and function of the tag
---
---A 'canonical' name is the main lookup name for a metadata tag; additional 'aliases' can be used that point to this name
---@alias checkmate.Metadata table<string, checkmate.MetadataProps>
---@class checkmate.MetadataProps
---
---Additional string values that can be used interchangably with the canonical tag name.
---E.g. @started could have aliases of `{"initiated", "began"}` so that @initiated and @began could
---also be used and have the same styling/functionality
---@field aliases? string[]
---
---@alias checkmate.StyleFn fun(context?: checkmate.MetadataContext):vim.api.keyset.highlight
---
---Highlight settings table, or a function that returns highlight settings (being passed metadata context)
---@field style? vim.api.keyset.highlight|checkmate.StyleFn
---
---@alias checkmate.GetValueFn fun(context?: checkmate.MetadataContext):string
---
---Function that returns the default value for this metadata tag
---i.e. what is used after insertion
---@field get_value? checkmate.GetValueFn
---
---@alias checkmate.ChoicesFn fun(context?: checkmate.MetadataContext, cb?: fun(items: string[])): string[]|nil
---
---Values that are populated during completion or select pickers
---Can be either:
--- - An array of items (string[])
--- - A function that returns items
---@field choices? string[]|checkmate.ChoicesFn
---
---Keymapping for toggling (adding/removing) this metadata tag
---Can also pass a tuple (key, desc) to include a description
---@field key? string|string[]
---
---Used for displaying metadata in a consistent order
---@field sort_order? integer
---
---Moves the cursor to the metadata after it is inserted
--- - "tag" - moves to the beginning of the tag
--- - "value" - moves to the beginning of the value
--- - false - disables jump (default)
---@field jump_to_on_insert? "tag" | "value" | false
---
---Selects metadata text in visual mode after metadata is inserted
---The `jump_to_on_insert` field must be set (not false)
---The selected text will be the tag or value, based on jump_to_on_insert setting
---Default (false) - off
---@field select_on_insert? boolean
---
---Callback to run when this metadata tag is added to a todo item
---E.g. can be used to change the todo item state
---@field on_add? fun(todo: checkmate.Todo)
---
---Callback to run when this metadata tag is removed from a todo item
---E.g. can be used to change the todo item state
---@field on_remove? fun(todo: checkmate.Todo)
---
---Callback to run when this metadata tag's value is programatically changed (not on initial add or removal)
---Receives the todo item, old value, and new value
---@field on_change? fun(todo: checkmate.Todo, old_value: string, new_value: string)
-----------------------------------------------------
---@class checkmate.ArchiveSettings
---
---Defines the header section for the archived todos
---@field heading checkmate.ArchiveHeading
---
---Number of blank lines between archived todo items (root only)
---@field parent_spacing integer?
---
---How to arrange newly added archived todos
---If true, newly added todos will be added to the top of the archive section
---Default: true
---@field newest_first boolean?
---@class checkmate.ArchiveHeading
---
---Name for the archived todos section
---Default: "Archived"
---@field title string?
---
---The heading level (e.g. #, ##, ###, ####)
---Integers 1 to 6
---Default: 2 (##)
---@field level integer?
-----------------------------------------------------
---@class checkmate.LinterConfig
---
---Whether to enable the linter (vim.diagnostics)
---Default: true
---@field enabled boolean
---
---Map of issues to diagnostic severity level
---@field severity table<string, vim.diagnostic.Severity>?
---
---Whether to use verbose linter/diagnostic messages
---Default: false
---@field verbose boolean?
-----------------------------------------------------
--- Returns list of deprecation warnings
function M.get_deprecations(user_opts)
if type(user_opts) ~= "table" then
return {}
end
local res = {}
---@diagnostic disable-next-line: unused-local
local function add(msg)
table.insert(res, msg)
end
-- [add deprecations here]
-- NOTE: deprecated v0.12
local user_picker = vim.tbl_get(user_opts, "ui", "picker")
if user_picker == false then
add("ui.picker 'false' is deprecated since v0.12. Use 'native' to use vim.ui.select as the default picker.")
end
return res
end
---Handles merging of deprecated config opts into current config to maintain backwards compatibility
---@param current_opts checkmate.Config
---@param user_opts? checkmate.Config
local function merge_deprecated_opts(current_opts, user_opts)
user_opts = user_opts or {}
-----------------------
---@deprecated ui.picker "false" opt deprecated v0.12
-- convert false to "native"
local user_picker = vim.tbl_get(user_opts, "ui", "picker")
if user_picker == false then
current_opts.ui = vim.tbl_extend("force", current_opts.ui or {}, { picker = "native" })
end
-----------------------
--[[ Kept as an example (commented out in v0.12)
-----------------------
--- todo_markers
---@deprecated v0.10
-- if the user set todo_markers but did not explicitly override todo_states,
-- build a new todo_states table from their markers, preserving the default order.
if user_opts.todo_markers and not user_opts.todo_states then
local default_states = require("checkmate.config").get_defaults().todo_states
current_opts.todo_states = {
---@diagnostic disable-next-line: missing-fields
unchecked = {
marker = user_opts.todo_markers.unchecked,
order = default_states.unchecked.order,
},
---@diagnostic disable-next-line: missing-fields
checked = {
marker = user_opts.todo_markers.checked,
order = default_states.checked.order,
},
}
elseif user_opts.todo_markers and user_opts.todo_states then
-- vim.notify("Checkmate: `todo_markers` ignored because `todo_states` is set", vim.log.levels.WARN)
end
---@diagnostic disable-next-line: deprecated
current_opts.todo_markers = {
unchecked = current_opts.todo_states.unchecked.marker,
checked = current_opts.todo_states.checked.marker,
}
-----------------------
]]
end
---@param opts? checkmate.Config
---@return checkmate.Config config
function M.setup(opts)
local success, result = pcall(function()
local config = vim.deepcopy(defaults)
--- Some config options should not be merged but rather overriden
local prevent_merge = function(o)
-- we can't merge `keys` because they are keyed on unique strings, e.g. `<leader>Tt` vs `<leader>Ct`
-- thus we end up with duplicate mappings if the user changes the lhs, see issue #201
if o.keys then
config.keys = nil
end
if o.list_continuation and o.list_continuation.keys then
config.list_continuation.keys = nil
end
-- don't merge metadata definitions as this leads to unexpected behavior (user configured + possibly unintended defaults)
if o.metadata then
for meta_name, _ in pairs(o.metadata) do
config.metadata[meta_name] = nil
end
end
end
-- then merge global config if present
if type(vim.g.checkmate_config) == "table" then
prevent_merge(vim.g.checkmate_config)
config = vim.tbl_deep_extend("force", config, vim.g.checkmate_config)
end
-- then merge user options after validating
if type(opts) == "table" then
local ok, errors = validate.validate_options(opts)
if not ok then
local msg = ("Checkmate: config validation failed:\n %s"):format(
table.concat(errors or { "unknown error" }, "\n ")
)
vim.notify(msg, vim.log.levels.WARN)
return {}
end
prevent_merge(opts)
config = vim.tbl_deep_extend("force", config, opts)
end
-- maintain backwards compatibility
merge_deprecated_opts(config, opts)
-- OVERRIDES
-- ensure that checked and unchecked todo states always have GFM representation
-- ensure that type is never altered
config.todo_states.checked.markdown = { "x", "X" }
config.todo_states.checked.type = "complete"
config.todo_states.unchecked.markdown = " "
config.todo_states.unchecked.type = "incomplete"
-- save user style for colorscheme updates
M._state.user_style = config.style and vim.deepcopy(config.style) or {}
-- make theme-aware style defaults
if config.style ~= false then
local theme_style = require("checkmate.theme").generate_style_defaults()
config.style = vim.tbl_deep_extend("keep", config.style or {}, theme_style)
end
M.options = config
return config
end)
if not success then
vim.notify("Checkmate: Config error: " .. tostring(result), vim.log.levels.ERROR)
return {}
end
---@cast result checkmate.Config
return result
end
function M.get_defaults()
return vim.deepcopy(defaults)
end
function M.get_todo_state_type(state_name)
local state_def = M.options.todo_states[state_name]
return state_def and state_def.type or "inactive"
end
-- Determines the line count threshold for what constitutes a "region", for
-- region-scoped processing vs. full buffer
-- I.e, if a region is too large, it may warrant a full re-process
function M.get_region_limit(bufnr)
local line_count = vim.api.nvim_buf_line_count(bufnr)
return math.max(200, math.floor(line_count * 0.25))
end
return M