vis-tables - Vis plugin for writing tables
ssh://anon@thyssentishman.com/vis-tables
Log | Files | Refs | Feed | Contribute | README | LICENSE

Commit: ad38d9a972b7d6d5cf7af0872791e2d0b7b5a88e
Parent: 9355c01b0203164d8eea4d91806f36857711903f
Author: Johannes Thyssen Tishman
Date:   Mon, 28 Aug 2023 09:08:58 +0000

Refactor {next,prev}cell functions

Diffstat:
M init.lua | 63 +++++++++++++++++++++++++++++++++------------------------------

1 file changed, 33 insertions(+), 30 deletions(-)

diff --git a/init.lua b/init.lua
@@ -144,67 +144,70 @@ local function printtable(tbl, lines)
 	end
 end
 
+local function gotocell(tbl, lines, row, col)
+	local pos
+	local c = 0
+	local i = 1
+
+	for _, p in utf8.codes(lines[tbl.start + row - 1]) do
+		if c == col then
+			pos = pos and pos or i + M.npad
+			local m = utf8.char(p):match('%S')
+			if m then
+				pos = m == M.csep and pos or i
+				break
+			end
+		end
+		if utf8.char(p) == M.csep then c = c + 1 end
+		i = i + 1
+	end
+	vis.win.selection:to(tbl.start + row - 1, pos)
+end
+
 local function nextcell(tbl, ln, lines)
-	local nr, nc
 	local bot = tbl.finish
 
 	for i = tbl.finish, tbl.start, -1 do
-		bot = i
+		bot = i - tbl.start + 1
 		if not smatch(lines[i], M.csep .. M.rsep) then break end
 	end
 
 	if tbl.icol >= tbl.ncols or smatch(lines[ln], M.csep .. M.rsep) then
-		if tbl.irow == tbl.nrows or ln >= bot then
+		if tbl.irow == tbl.nrows or tbl.irow >= bot then
 			newrow(tbl, ln, lines)
 		end
-		local skip = 0
-		while smatch(lines[ln + skip + 1], M.csep .. M.rsep) do
+		local skip = 1
+		while smatch(lines[ln + skip], M.csep .. M.rsep) do
 			skip = skip + 1
 		end
-		nr = tbl.start + tbl.irow + skip
-		nc = #tbl.indent + M.npad + 2
-		vis.win.selection:to(nr, nc)
+		gotocell(tbl, lines, tbl.irow + skip, 1)
 	else
-		nc = #tbl.indent + M.npad + 2
-		nr = tbl.start + tbl.irow - 1
-		for i = 1, tbl.icol do 
-			nc = nc + tbl.colw[i] + (M.npad * 2) + 1
-		end
-		vis.win.selection:to(nr, nc)
+		gotocell(tbl, lines, tbl.irow, tbl.icol + 1)
 	end
 end
 
 local function prevcell(tbl, ln, lines)
-	local nr, nc
 	local top = tbl.start
 
 	for i = tbl.start, tbl.finish do
-		top = i
+		top = i - tbl.start + 1
 		if not smatch(lines[i], M.csep .. M.rsep) then break end
 	end
 
-	if tbl.icol == 1 or smatch(lines[ln], M.csep .. M.rsep) then
-		if tbl.irow == 1 or ln <= top then
+	if tbl.icol <= 1 or smatch(lines[ln], M.csep .. M.rsep) then
+		if tbl.irow == 1 or tbl.irow <= top then
 			vis:info('No previous cells'); 
+			gotocell(tbl, lines, top, 1)
 		else
 			local skip = 1
 			while smatch(lines[ln - skip], M.csep .. M.rsep) do
 				skip = skip + 1
 			end
-			tbl.icol = tbl.ncols + 1
-			tbl.irow = tbl.irow - skip
+			gotocell(tbl, lines, tbl.irow - skip, tbl.ncols)
 		end
-	end 
-	nc = #tbl.indent + M.npad + 2 
-	if ln < top then
-		nr = top
 	else
-		nr = tbl.start + tbl.irow - 1 
-		for i = 1, tbl.icol - 2 do
-			nc = nc + tbl.colw[i] + (M.npad * 2) + 1
-		end 
-	end
-	vis.win.selection:to(nr, nc)
+		gotocell(tbl, lines, tbl.irow, tbl.icol - 1)
+	end 
 end
 
 local function tablemode(n)