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
41 changes: 41 additions & 0 deletions lua/bullets/actions.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
local M = {}

local function feed(keys)
vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(keys, true, false, true), "n", false)
end

function M.insert_new_bullet()
if vim.fn.mode() == "n" then
vim.cmd.startinsert({ bang = true })
else
feed("<CR>")
end

return ""
end

function M.renumber_list() end

function M.renumber_selection() end

function M.toggle_checkbox() end

function M.recompute_checkboxes() end

function M.demote() end

function M.promote() end

function M.demote_visual() end

function M.promote_visual() end

function M.select_checkbox() end

function M.select_checkbox_inside() end

function M.select_bullet() end

function M.select_bullet_text() end

return M
31 changes: 31 additions & 0 deletions lua/bullets/config.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
local M = {}

M.defaults = {
enabled_file_types = { "markdown", "text", "gitcommit" },
enable_in_empty_buffers = false,
set_mappings = true,
mapping_leader = "",
custom_mappings = {},
delete_last_bullet_if_empty = 1,
line_spacing = 1,
pad_right = true,
max_alpha_characters = 2,
enable_roman_list = true,
list_item_styles = { "-", "*+", ".+", "#.", "+", "\\item" },
outline_levels = { "ROM", "ABC", "num", "abc", "rom", "std-", "std*", "std+" },
renumber_on_change = true,
nested_checkboxes = true,
enable_wrapped_lines = true,
checkbox_markers = " .oOX",
checkbox_partials_toggle = 1,
auto_indent_after_colon = true,
}

M.options = vim.deepcopy(M.defaults)

function M.setup(options)
M.options = vim.tbl_deep_extend("force", vim.deepcopy(M.defaults), options or {})
return M.options
end

return M
160 changes: 160 additions & 0 deletions lua/bullets/init.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
local config = require("bullets.config")

local M = {}

local augroup = vim.api.nvim_create_augroup("bullets.nvim", { clear = true })

local function actions()
return require("bullets.actions")
end

local function command(name, fn, opts)
vim.api.nvim_create_user_command(name, fn, vim.tbl_extend("force", { force = true }, opts or {}))
end

local function map(mode, lhs, rhs, opts)
vim.keymap.set(mode, lhs, rhs, vim.tbl_extend("force", { silent = true }, opts or {}))
end

local function map_buffer(buf, mode, lhs, rhs, opts)
vim.keymap.set(mode, lhs, rhs, vim.tbl_extend("force", { buffer = buf, silent = true }, opts or {}))
end

local function add_commands()
command("InsertNewBullet", function()
actions().insert_new_bullet()
end)
command("RenumberList", function()
actions().renumber_list()
end)
command("RenumberSelection", function()
actions().renumber_selection()
end, { range = true })
command("ToggleCheckbox", function()
actions().toggle_checkbox()
end)
command("RecomputeCheckboxes", function()
actions().recompute_checkboxes()
end)
command("BulletDemote", function()
actions().demote()
end)
command("BulletPromote", function()
actions().promote()
end)
command("BulletDemoteVisual", function()
actions().demote_visual()
end, { range = true })
command("BulletPromoteVisual", function()
actions().promote_visual()
end, { range = true })
command("SelectCheckbox", function()
actions().select_checkbox()
end)
command("SelectCheckboxInside", function()
actions().select_checkbox_inside()
end)
command("SelectBullet", function()
actions().select_bullet()
end)
command("SelectBulletText", function()
actions().select_bullet_text()
end)
end

local function add_plug_mappings()
map("i", "<Plug>(bullets-newline)", function()
return actions().insert_new_bullet()
end, { expr = true })
map("n", "<Plug>(bullets-newline)", function()
actions().insert_new_bullet()
end)
map("n", "<Plug>(bullets-renumber)", function()
actions().renumber_list()
end)
map("x", "<Plug>(bullets-renumber)", function()
actions().renumber_selection()
end)
map("n", "<Plug>(bullets-toggle-checkbox)", function()
actions().toggle_checkbox()
end)
map("n", "<Plug>(bullets-recompute-checkboxes)", function()
actions().recompute_checkboxes()
end)
map({ "i", "n" }, "<Plug>(bullets-demote)", function()
actions().demote()
end)
map("x", "<Plug>(bullets-demote)", function()
actions().demote_visual()
end)
map({ "i", "n" }, "<Plug>(bullets-promote)", function()
actions().promote()
end)
map("x", "<Plug>(bullets-promote)", function()
actions().promote_visual()
end)
end

local function add_default_mappings(buf)
local opts = config.options
local leader = opts.mapping_leader

map_buffer(buf, "i", leader .. "<CR>", "<Plug>(bullets-newline)", { remap = true })
map_buffer(buf, "i", leader .. "<C-CR>", "<CR>")
map_buffer(buf, "n", leader .. "o", "<Plug>(bullets-newline)", { remap = true })
map_buffer(buf, "n", leader .. "gN", "<Plug>(bullets-renumber)", { remap = true })
map_buffer(buf, "x", leader .. "gN", "<Plug>(bullets-renumber)", { remap = true })
map_buffer(buf, "n", leader .. "<leader>x", "<Plug>(bullets-toggle-checkbox)", { remap = true })
map_buffer(buf, "i", leader .. "<C-t>", "<Plug>(bullets-demote)", { remap = true })
map_buffer(buf, "n", leader .. ">>", "<Plug>(bullets-demote)", { remap = true })
map_buffer(buf, "x", leader .. ">", "<Plug>(bullets-demote)", { remap = true })
map_buffer(buf, "i", leader .. "<C-d>", "<Plug>(bullets-promote)", { remap = true })
map_buffer(buf, "n", leader .. "<<", "<Plug>(bullets-promote)", { remap = true })
map_buffer(buf, "x", leader .. "<", "<Plug>(bullets-promote)", { remap = true })
end

local function add_custom_mappings(buf)
for _, item in ipairs(config.options.custom_mappings) do
map_buffer(buf, item[1], item[2], item[3], { remap = true })
end
end

local function configure_buffer(buf)
if config.options.set_mappings then
add_default_mappings(buf)
end
add_custom_mappings(buf)
end

local function add_autocmds()
vim.api.nvim_clear_autocmds({ group = augroup })

vim.api.nvim_create_autocmd("FileType", {
group = augroup,
pattern = config.options.enabled_file_types,
callback = function(event)
configure_buffer(event.buf)
end,
})

if config.options.enable_in_empty_buffers then
vim.api.nvim_create_autocmd({ "BufNew", "BufRead" }, {
group = augroup,
pattern = "*",
callback = function(event)
if vim.bo[event.buf].filetype == "" then
configure_buffer(event.buf)
end
end,
})
end
end

function M.setup(options)
config.setup(options)
add_commands()
add_plug_mappings()
add_autocmds()
end

return M
12 changes: 6 additions & 6 deletions mise.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ if [ ! -d "$PLENARY_PATH" ]; then
git clone --depth=1 https://github.com/nvim-lua/plenary.nvim "$PLENARY_PATH"
fi
status=0
for spec in test/*_spec.lua; do
nvim --headless \
-c "set rtp+=.,${PLENARY_PATH} | runtime plugin/plenary.vim | runtime plugin/bullets.vim" \
--noplugin \
-c "lua require('plenary.busted').run('${spec}')" || status=1
done
for spec in test/*_spec.lua; do
nvim --headless \
-c "set rtp+=.,${PLENARY_PATH} | runtime plugin/plenary.vim | runtime plugin/bullets.lua" \
--noplugin \
-c "lua require('plenary.busted').run('${spec}')" || status=1
done
exit $status
"""
7 changes: 7 additions & 0 deletions plugin/bullets.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
if vim.g.loaded_bullets_nvim then
return
end

vim.g.loaded_bullets_nvim = true

Comment on lines +1 to +6
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need this for neovim plugins - right?

require("bullets").setup()
36 changes: 19 additions & 17 deletions test/helpers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,27 @@ function M.test_bullet_inserted(second_bullet, initial_lines, expected_lines)
assert.are.same(expected_lines, M.get_lines())
end

-- Resets all bullets.vim globals to their plugin defaults.
-- Resets bullets.nvim to the plugin defaults used by the specs.
-- Call in before_each for any describe block that mutates config.
function M.reset_config()
vim.g.bullets_enabled_file_types = { "markdown", "text", "gitcommit", "scratch" }
vim.g.bullets_enable_in_empty_buffers = 1
vim.g.bullets_set_mappings = 1
vim.g.bullets_mapping_leader = ""
vim.g.bullets_custom_mappings = {}
vim.g.bullets_max_alpha_characters = 2
vim.g.bullets_auto_indent_after_colon = 1
vim.g.bullets_line_spacing = 1
vim.g.bullets_renumber_on_change = 1
vim.g.bullets_nested_checkboxes = 1
vim.g.bullets_checkbox_markers = " .oOX"
vim.g.bullets_checkbox_partials_toggle = 1
vim.g.bullets_outline_levels = { "ROM", "ABC", "num", "abc", "rom", "std-", "std*", "std+" }
vim.g.bullets_enable_roman_list = 1
vim.g.bullets_pad_right = 1
vim.g.bullets_delete_last_bullet_if_empty = 1
require("bullets").setup({
enabled_file_types = { "markdown", "text", "gitcommit", "scratch" },
enable_in_empty_buffers = true,
set_mappings = true,
mapping_leader = "",
custom_mappings = {},
max_alpha_characters = 2,
auto_indent_after_colon = true,
line_spacing = 1,
renumber_on_change = true,
nested_checkboxes = true,
checkbox_markers = " .oOX",
checkbox_partials_toggle = 1,
outline_levels = { "ROM", "ABC", "num", "abc", "rom", "std-", "std*", "std+" },
enable_roman_list = true,
pad_right = true,
delete_last_bullet_if_empty = 1,
})
end

return M
2 changes: 1 addition & 1 deletion test/minimal_init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ vim.opt.rtp:prepend(plenary_path)
vim.opt.rtp:prepend(repo_root)

vim.cmd("filetype plugin on")
vim.cmd("runtime plugin/bullets.vim")
vim.cmd("runtime plugin/bullets.lua")
vim.cmd("set formatoptions=")
vim.cmd("set noexpandtab")
4 changes: 1 addition & 3 deletions test/poc_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@ local function feedkeys(keys)
vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(keys, true, false, true), "tx", false)
end

local it = pending

describe("Bullets.vim", function()
it("loads the plugin", function()
assert.equals(2, vim.fn.exists(":InsertNewBullet"))
end)

it("inserts a new bullet on <CR>", function()
pending("inserts a new bullet on <CR>", function()
vim.cmd("enew")
vim.bo.filetype = "text"
vim.api.nvim_buf_set_lines(0, 0, -1, false, { "- first item" })
Expand Down