summary refs log tree commit diff
path: root/.config/micro/plug/sort-plugin
diff options
context:
space:
mode:
Diffstat (limited to '.config/micro/plug/sort-plugin')
-rw-r--r--.config/micro/plug/sort-plugin/repo.json3
-rw-r--r--.config/micro/plug/sort-plugin/sort.lua125
2 files changed, 128 insertions, 0 deletions
diff --git a/.config/micro/plug/sort-plugin/repo.json b/.config/micro/plug/sort-plugin/repo.json
new file mode 100644
index 0000000..0ea2b4e
--- /dev/null
+++ b/.config/micro/plug/sort-plugin/repo.json
@@ -0,0 +1,3 @@
+[{
+  "Name": "sort"
+}]
diff --git a/.config/micro/plug/sort-plugin/sort.lua b/.config/micro/plug/sort-plugin/sort.lua
new file mode 100644
index 0000000..607d9f3
--- /dev/null
+++ b/.config/micro/plug/sort-plugin/sort.lua
@@ -0,0 +1,125 @@
+VERSION = "1.0.0"
+
+local buffer = import("micro/buffer")
+local config = import("micro/config")
+local micro = import("micro")
+-- local posix = import("posix")
+
+
+-- Returns Loc-tuple w/ current marked text or whole line (begin, end)
+function getTextLoc(c)
+	local v = micro.CurPane()
+	local a, b = nil, nil
+	if c:HasSelection() then
+		if c.CurSelection[1]:GreaterThan(-c.CurSelection[2]) then
+			a, b = c.CurSelection[2], c.CurSelection[1]
+		else
+			a, b = c.CurSelection[1], c.CurSelection[2]
+		end
+	else
+		local eol = string.len(v.Buf:Line(c.Loc.Y))
+		a, b = c.Loc, buffer.Loc(eol, c.Y)
+	end
+	return buffer.Loc(a.X, a.Y), buffer.Loc(b.X, b.Y)
+end
+
+-- Returns the current marked text or whole line
+function getText(a, b)
+	local txt, buf = {}, micro.CurPane().Buf
+
+	-- Editing a single line?
+	if a.Y == b.Y then return buf:Line(a.Y):sub(a.X + 1, b.X) end
+
+	-- Add first part of text selection (a.X+1 as Lua is 1-indexed)
+	table.insert(txt, buf:Line(a.Y):sub(a.X + 1))
+
+	-- Stuff in the middle
+	for lineNo = a.Y + 1, b.Y - 1 do
+		table.insert(txt, buf:Line(lineNo))
+	end
+
+	-- Insert last part of selection
+	table.insert(txt, buf:Line(b.Y):sub(1, b.X))
+
+	return table.concat(txt, "\n")
+end
+
+-- Calls 'manipulator'-function on text matching 'regex'
+function manipulate(regex, manipulator, num)
+	local num = math.inf or num
+	local v = micro.CurPane()
+	-- perform the replacement for each cursor
+	local cs = v.Buf:GetCursors()
+	for i = 1, #cs do
+		local c = cs[i]
+		local a, b = getTextLoc(c)
+		local oldTxt = getText(a, b)
+		local newTxt = string.gsub(oldTxt, regex, manipulator, num)
+		local sel = nil
+		if c:HasSelection() then
+			-- copied from comment plugin
+			sel = -c.CurSelection
+		end
+		v.Buf:Replace(a, b, newTxt)
+
+		-- Fix selection, if transformation changes text length (e.g. base64)
+		local d = string.len(newTxt) - string.len(oldTxt)
+		if sel ~= nil then
+			-- copied from comment plugin
+
+			c.CurSelection[1].Y = sel[1].Y
+			c.CurSelection[2].Y = sel[2].Y
+			c.CurSelection[1].X = sel[1].X
+			c.CurSelection[2].X = sel[2].X
+
+			if c.CurSelection[1]:GreaterThan(-c.CurSelection[2]) then
+				c.CurSelection[1].X = sel[1].X + d
+			else
+				c.CurSelection[2].X = sel[2].X + d
+			end
+		end
+		c:Relocate()
+		c.LastVisualX = c:GetVisualX() -- called with false
+	end
+end
+
+-- https://stackoverflow.com/questions/1242572/how-do-you-construct-a-read-write-pipe-with-lua
+
+function os_pipe(input, cmd)
+    os.setenv("LUA_X",input)
+	local f = assert(io.popen('printf "%s" "$LUA_X" | ' .. cmd, 'r'))
+	local s = assert(f:read('*a'))
+	f:close()
+	return s
+end
+
+
+function sort()
+	manipulate("(.*)", function(lines)
+	    return os_pipe(lines, 'sort')
+	end)
+end
+function sortu()
+	manipulate("(.*)", function(lines)
+	    return os_pipe(lines, 'sort -u')
+	end)
+end
+function jq()
+	manipulate("(.*)", function(lines)
+	    return os_pipe(lines, 'jq')
+	end)
+end
+
+function pipe(bp, args)
+    manipulate("(.*)", function(lines)
+        return os_pipe(lines, table.concat(args, " "))
+    end)
+end
+
+
+function init()
+	config.MakeCommand("sort", sort, config.NoComplete)
+	config.MakeCommand("sortu", sortu, config.NoComplete)
+	config.MakeCommand("jq", jq, config.NoComplete)
+	config.MakeCommand("pipe", pipe, config.NoComplete)
+end