Skip to content

Commit

Permalink
(mini.cursorpos) NEW MODULE: initial commit.
Browse files Browse the repository at this point in the history
This module implements `:help last-position-jump`
  • Loading branch information
cryptomilk committed Jan 15, 2023
1 parent 96e648c commit c0fbb87
Showing 1 changed file with 161 additions and 0 deletions.
161 changes: 161 additions & 0 deletions lua/mini/cursorpos.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
-- MIT License Copyright (c) 2023 Andreas Schneider

-- Documentation ==============================================================
--- Open files with the cursor set to your last edit position.
---
--- If you reopen a file and have neovim shada configured correctly, the cursor
--- will be postioned at the line and column were you left.
---
--- Features:
---
--- - Remembers the curser position of an edited file.
--- - For git commit messages and rebases the cursor is positoned at the
--- beginning.
---
--- # Setup-
---
--- This module doesn't need setup, but it can be done to improve usability.
--- Setup with `require('mini.cursorpos').setup({})` (replace `{}` with your
--- `config` table). It will create global Lua table `MiniBufremove` which you
--- can use for scripting or manually (with `:lua MiniBufremove.*`).
---
--- See |MiniCursorPos.config| for `config` structure and default values.
---
--- If you want to lazy load the plubin, use the BufReadPre event.
---
---@tag mini.cursorpos
---@tag MiniCursorPos

---
-- Module definition ==========================================================
local MiniCursorPos = {}
local H = {}

--- Module setup
---
---@param config table Module config table. See |MiniCursorPos.config|.
---
---@usage `require('mini.cursorpos').setup({})` (replace `{}` with your `config` table)
MiniCursorPos.setup = function(config)
-- Export module
_G.MiniCursorPos = MiniCursorPos

-- Setup config
config = H.setup_config(config)

-- Apply config
H.apply_config(config)

-- Module behavior
if vim.fn.has("nvim-0.7.0") then
print("foo")
local group_name = "MiniCursorPos"

vim.api.nvim_create_augroup(group_name, { clear = true })
vim.api.nvim_create_autocmd("BufWinEnter", { callback = MiniCursorPos.auto_cursor, group = group_name })
vim.api.nvim_create_autocmd("FileType", { callback = MiniCursorPos.auto_cursor, group = group_name })
else
vim.api.nvim_command([[augroup MiniCursorPos]])
vim.api.nvim_command([[ autocmd!]])
vim.api.nvim_command([[ autocmd BufWinEnter * lua require('mini.cursorpos').auto_cursor()]])
vim.api.nvim_command([[ autocmd FileType * lua require('mini.cusorpos').auto_cursor()]])
vim.api.nvim_command([[augroup end]])
end
end

--- Module config
---
--- Default values:
---@eval return MiniDoc.afterlines_to_code(MiniDoc.current.eval_section)
MiniCursorPos.config = {
-- Table of buffer types to be ignored.
ignore_buftype = { "quickfix", "nofile", "help" },
-- Table of file types to be ignored.
ignore_filetype = { "gitcommit", "gitrebase", "svn", "hgcommit" },
-- Closed folds are automatically opened when jumping to the last edit position.
open_folds = true,
}

MiniCursorPos.place_cursor = function()
local config = H.get_config()
local last_line = vim.fn.line([['"]])
local buff_last_line = vim.fn.line("$")

if last_line > 0 and last_line <= buff_last_line then
local window_first_line = vim.fn.line("w0")
local window_last_line = vim.fn.line("w$")

-- Check if the last line of the buffer is the same as the window
if window_last_line == buff_last_line then
-- Set line to last line edited
vim.api.nvim_command([[normal! g`"]])
elseif buff_last_line - last_line > ((window_last_line - window_first_line) / 2) - 1 then
-- Try to center
vim.api.nvim_command([[normal! g`"zz]])
else
vim.api.nvim_command([[normal! G'"<c-e>]])
end
end

if vim.fn.foldclosed(".") ~= -1 and config.open_folds == true then
vim.api.nvim_command([[normal! zvzz]])
end
end

MiniCursorPos.auto_cursor = function()
local config = H.get_config()

-- Check if the buffer should be ignored
if vim.tbl_contains(config.ignore_buftype, vim.api.nvim_buf_get_option(0, "buftype")) then
return
end

-- Check if the filetype should be ignored
if vim.tbl_contains(config.ignore_filetype, vim.api.nvim_buf_get_option(0, "filetype")) then
-- reset cursor to first line
vim.api.nvim_command([[normal! gg]])
return
end

-- If a line has already been specified on the command line, we are done
-- nvim file +num
if vim.fn.line(".") > 1 then
return
end

MiniCursorPos.place_cursor()
end

-- Helper data ================================================================
-- Module default config
H.default_config = MiniCursorPos.config

-- Helper functionality =======================================================
-- Settings -------------------------------------------------------------------
H.setup_config = function(config)
-- General idea: if some table elements are not present in user-supplied
-- `config`, take them from default config
vim.validate({ config = { config, 'table', true } })

config = vim.tbl_deep_extend('force', H.default_config, config or {})

vim.validate({
ignore_buftype = { config.ignore_buftype, 'table' },
ignore_filetype = { config.ignore_filetype, 'table' },
open_folds = { config.open_folds, 'boolean' },
})

return config
end

H.apply_config = function(config)
MiniCursorPos.config = config
end

H.is_disabled = function() return vim.g.minicursorpos_disable == true or vim.b.minicursorpos_disable == true end

H.get_config = function(config)
return vim.tbl_deep_extend('force', MiniCursorPos.config, vim.b.minicursorpos_config or {}, config or {})
end

return MiniCursorPos

0 comments on commit c0fbb87

Please sign in to comment.