summary refs log tree commit diff
path: root/.vim
diff options
context:
space:
mode:
authorRobert Günzler <r@gnzler.io>2022-06-15 04:37:59 +0200
committerRobert Günzler <r@gnzler.io>2022-06-15 04:39:51 +0200
commitc41fa8be2cb3d86ca78e36fd7dca198e1b554520 (patch)
tree18a786ca09158a9f1bd0485d6cedfa4df1b7dd7c /.vim
parenteeb2d0c528851b61f9c790f5afe33f4083c9264a (diff)
vim: replace easy-align with small lua module
with support for inccommand preview
Diffstat (limited to '.vim')
-rw-r--r--.vim/init.lua1
-rw-r--r--.vim/lua/align/init.lua103
-rw-r--r--.vim/lua/plugins.lua5
3 files changed, 104 insertions, 5 deletions
diff --git a/.vim/init.lua b/.vim/init.lua
index c71c82c..91e3708 100644
--- a/.vim/init.lua
+++ b/.vim/init.lua
@@ -104,6 +104,7 @@ g.did_load_filetypes = 0
 
 require('globals')
 require('plugins')
+require('align').setup { bindings = true }
 require('hardmode')
 
 -- Configure builtin diagnositics {{{
diff --git a/.vim/lua/align/init.lua b/.vim/lua/align/init.lua
new file mode 100644
index 0000000..bcb8437
--- /dev/null
+++ b/.vim/lua/align/init.lua
@@ -0,0 +1,103 @@
+-- based on the ideas from:
+-- https://github.com/RRethy/nvim-align
+
+local M = {}
+
+function M.align_lines(pat, line1, line2, preview_ns, preview_bufnr)
+  local re = vim.regex(pat)
+  local bufnr = vim.api.nvim_get_current_buf()
+  local lines = vim.api.nvim_buf_get_lines(bufnr, line1 - 1, line2, false)
+  local newlines = {}
+  local preview_buf_line = 0
+
+  -- find the longest match
+  local max = -1
+  for _, line in pairs(lines) do
+    local s = re:match_str(line)
+    if s and max < s then max = s end
+  end
+
+  -- exit if nothing was found
+  if max == -1 then return error('nothing found') end
+
+  for i, line in pairs(lines) do
+    local s = re:match_str(line)
+    if s then
+      local rep = max - s
+      local changeset = {
+        string.sub(line, 1, s),
+        string.rep(' ', rep),
+        string.sub(line, s+1),
+      }
+      local newline = table.concat(changeset)
+
+      -- append to changse if not inside the preview callback
+      if not preview_ns then
+        newlines[#newlines+1] = newline
+      end
+
+      if preview_ns ~= nil then
+        -- set extmarks inside the live buffer
+        vim.api.nvim_buf_set_extmark(bufnr, preview_ns, line1+i - 2, 0,
+          {
+            hl_mode = 'combine',
+            virt_text_pos = 'overlay',
+            virt_text = {
+              {changeset[1]},
+              {changeset[2], 'Substitute'},
+              {changeset[3]},
+            },
+          })
+
+        -- modify preview buffer
+        if preview_bufnr ~= nil then
+          local prefix = string.format('|%d| ', line1 + i - 1)
+          vim.api.nvim_buf_set_lines(preview_bufnr, preview_buf_line, preview_buf_line, 0, { prefix .. newline })
+          vim.api.nvim_buf_add_highlight(preview_bufnr, preview_ns, 'Substitute', preview_buf_line, #prefix + s, #prefix + s + #changeset[2])
+          preview_buf_line = preview_buf_line + 1
+        end
+      end
+    end
+  end
+
+  -- only change buffer when not previewing
+  if not preview_ns then
+    -- exit if nothing was changed
+    if #newlines == 0 then return error('nothing changed') end
+
+    vim.api.nvim_buf_set_lines(bufnr, line1 - 1, line2, 0, newlines)
+  end
+
+  -- return magic number when called as preview callback
+  if preview_ns ~= nil then
+    return 2
+  end
+end
+
+function M.align(pat)
+    local top, bot = vim.fn.getpos("'<"), vim.fn.getpos("'>")
+    M.align_lines(pat, top[2]-1, bot[2])
+    vim.fn.setpos("'<", top)
+    vim.fn.setpos("'>", bot)
+end
+
+local function aligncmd(opts, preview_ns, preview_bufnr)
+  return M.align_lines(opts.fargs[1], opts.line1, opts.line2, preview_ns, preview_bufnr)
+end
+
+local default_opts = {
+  bindings = true
+}
+
+function M.setup(opts)
+  opts = vim.tbl_extend('keep', opts or {}, default_opts)
+
+  vim.api.nvim_create_user_command('SimpleAlign', aligncmd,
+    {nargs = 1, range = '%', preview = aligncmd})
+
+  if opts.bindings then
+    vim.keymap.set('v', '<enter>', ':SimpleAlign ')
+  end
+end
+
+return M
diff --git a/.vim/lua/plugins.lua b/.vim/lua/plugins.lua
index 52588d5..b3b8d75 100644
--- a/.vim/lua/plugins.lua
+++ b/.vim/lua/plugins.lua
@@ -717,11 +717,6 @@ require('packer').startup({function()
       }
     end} -- }}}
 
-  use {'junegunn/vim-easy-align', cmd = {'EasyAlign', 'LiveEasyAlign'}, -- {{{
-    config = function()
-      vim.keymap.set('v', '<enter>', ':LiveEasyAlign<cr>')
-    end} -- }}}
-
   use {'tpope/vim-surround'}
   use {'tpope/vim-repeat'} -- extend '.' to plugins
   use {'michaeljsmith/vim-indent-object'} -- indentation text-objects