summary refs log tree commit diff
path: root/.vim/lua/internal/sortline.lua
diff options
context:
space:
mode:
Diffstat (limited to '.vim/lua/internal/sortline.lua')
-rw-r--r--.vim/lua/internal/sortline.lua78
1 files changed, 78 insertions, 0 deletions
diff --git a/.vim/lua/internal/sortline.lua b/.vim/lua/internal/sortline.lua
new file mode 100644
index 0000000..69f7f64
--- /dev/null
+++ b/.vim/lua/internal/sortline.lua
@@ -0,0 +1,78 @@
+local M = {}
+
+local function get_visual_selection(intact)
+  intact = intact or false
+  local top = vim.fn.getpos("'<")
+  top = { ln = top[2], col = top[3] }
+  local bot = vim.fn.getpos("'>")
+  bot = { ln = bot[2], col = bot[3] }
+  local lines = vim.api.nvim_buf_get_lines(0, (top.ln - 1), bot.ln, false)
+  if not intact then
+    if vim.opt.selection:get() == 'inclusive' then
+      lines[#lines] = lines[#lines]:sub(1, bot.col)
+    else
+      lines[#lines] = lines[#lines]:sub(1, (bot.col - 1))
+    end
+    lines[1] = lines[1]:sub(top.col)
+  end
+  return top, bot, lines
+end
+
+local function sortline(line, a, o, separator)
+  separator = separator or ' '
+  local result, _ = string.gsub(line, string.sub(line, a, o),
+    table.concat(vim.fn.sort(vim.fn.split(string.sub(line, a, o), separator)), separator), 1)
+  return result
+end
+
+function M.sort_lines(_, preview_ns, preview_bufnr)
+  local bufnr = vim.api.nvim_get_current_buf()
+
+  local top, bot, lines = get_visual_selection(true)
+  vim.pretty_print(top, bot, lines)
+  for i = 1, #lines do
+    local a = 0; if i == 1 then a = top.col end
+    local o = -1; if i == #lines then o = bot.col end
+    lines[i] = sortline(lines[i], a, o, ' ')
+  end
+
+  if not preview_ns then
+    vim.api.nvim_buf_set_lines(bufnr, top.ln - 1, bot.ln, false, lines)
+    return 0
+  end
+
+  -- inccommand preview
+  if preview_ns ~= nil then
+    for i, line in ipairs(lines) do
+      vim.api.nvim_buf_set_extmark(bufnr, preview_ns, top.ln + i - 2, 0, {
+        hl_mode = 'combine',
+        virt_text_pos = 'overlay',
+        virt_text = { { line, 'Substitute' } },
+      })
+
+      if preview_bufnr ~= nil then
+        local prefix = string.format('|%d| ', top.ln + i - 1)
+        vim.api.nvim_buf_set_lines(preview_bufnr, i - 1, -1, false, { prefix .. line })
+        vim.api.nvim_buf_add_highlight(
+          preview_bufnr,
+          preview_ns,
+          'Substitute',
+          i,
+          #prefix,
+          #prefix + #line
+        )
+      end
+    end
+    return (#lines > 1 and 2 or 1)
+  end
+end
+
+function M.setup(opts)
+  vim.api.nvim_create_user_command(
+    'SortLine',
+    M.sort_lines,
+    { desc = 'sort line', range = '%', preview = M.sort_lines }
+  )
+end
+
+return M