Commit Diff


commit - 60e1b851d9eaef063c50b64c27f1c1c0ad4efcde
commit + 076f13abe43fdd57cd7d2e8b1920ca6caead8e2b
blob - /dev/null
blob + 3e81c40527435d22cd0680eb42fda45c862eab9b (mode 644)
--- /dev/null
+++ aestel/browse.lua
@@ -0,0 +1,165 @@
+-- aestel/browse.lua
+-- A module for browsing directory structure and content.
+
+local M = {}
+
+-- Dependencies
+local lfs = require("lfs")
+local colors = require("aestel.colors")
+local display = require("aestel.display")
+local input = require("aestel.input")
+local menu = require("aestel.menu")
+
+local home_dir = os.getenv("HOME")
+
+local function normalize_path(p)
+	p = p:gsub("//+", "/")
+	if p == "/." or p == "./" then p = "/" end
+	return p:gsub("/+$", "")
+end
+
+local function join_path(base, name)
+	if base == "/" then
+		return normalize_path("/" .. name)
+	end
+	return normalize_path(base .. "/" .. name)
+end
+
+local function change_dir(cur, target, base_dir)
+	local new_path
+	if target == ".." then
+		local cur_no_trail = normalize_path(cur):gsub("/+$", "")
+		if cur_no_trail == "/" then
+			return nil, "Cannot go above root directory (/)"
+		end
+		new_path = cur_no_trail:match("(.+)/[^/]+$") or "/"
+	else
+		new_path = join_path(cur, target)
+	end
+
+	new_path = normalize_path(new_path)
+
+	if base_dir then
+		local normalized_base = normalize_path(base_dir) .. "/"
+		local normalized_new = new_path .. "/"
+		if not normalized_new:find(normalized_base, 1, true) then
+			return nil, "Access denied -- cannot navigate above base directory."
+		end
+	end
+
+	if new_path ~= "/" then
+		local attr = lfs.attributes(new_path)
+		if not attr then
+			return nil, "Path does not exist: " .. (new_path or "unknown")
+		end
+		if attr.mode ~= "directory" then
+			return nil, new_path .. " is not a directory."
+		end
+	end
+	return new_path
+end
+
+local function build_list(path, show_hidden)
+	local dirs, files = {}, {}
+	for item in lfs.dir(path) do
+		if item ~= "." and item ~= ".." then
+			if not show_hidden and item:sub(1,1) == "." then
+				-- skip hidden
+			else
+			local full = join_path(path, item)
+			local attr = lfs.attributes(full)
+			if attr then
+				if attr.mode == "directory" then
+					table.insert(dirs, item)
+				elseif attr.mode == "file" then
+					table.insert(files, item)
+				end
+			end
+			end
+		end
+	end
+	table.sort(dirs)
+	table.sort(files)
+
+	local combined = {}
+	for _, d in ipairs(dirs) do
+		table.insert(combined, {name = d, type = "dir"})
+	end
+	for _, f in ipairs(files) do
+		table.insert(combined, {name = f, type = "file"})
+	end
+	return combined
+end
+
+function M.browse(start_dir, base_dir, title)
+	title = title or ""
+	local cwd = normalize_path(start_dir or lfs.currentdir() or home_dir)
+	local show_hidden = false
+	local header_lines = display.write_header(title)
+
+	local running = true
+	local selected_file = nil
+
+	while running do
+		local items = build_list(cwd, show_hidden)
+		if #items == 0 then
+			local selected_index = menu.menu(title, items, header_lines + 1, header_lines, "Empty directory. Press 'h' to go up, 'q' to quit.")
+			if selected_index == 0 then
+				local new_cwd, err = change_dir(cwd, "..", base_dir)
+				if new_cwd then
+					cwd = new_cwd
+					display.write_header(title)
+				else
+					display.status_line("Error: " .. (err or "unknown"), colors.REVERSE)
+					os.execute("sleep 1")
+				end
+			else
+				running = false
+			end
+		else
+			local selected_index = menu.menu(title, items, header_lines + 1, header_lines, nil, cwd)
+
+			if not selected_index then
+				running = false
+			elseif selected_index == -1 then
+				show_hidden = not show_hidden
+			elseif selected_index == 0 then
+				local new_cwd, err = change_dir(cwd, "..", base_dir)
+				if new_cwd then
+					cwd = new_cwd
+					display.write_header(title)
+				else
+                    display.status_line("Error: " .. (err or "unknown"), colors.REVERSE)
+                    os.execute("sleep 2")
+                end
+
+			else
+				local sel = items[selected_index]
+				if sel.type == "dir" then
+					local new_cwd, err = change_dir(cwd, sel.name, base_dir)
+					if new_cwd then
+						cwd = new_cwd
+						display.write_header(title, cwd)
+					else
+						display.write_header(title, cwd)
+						local height = input.get_terminal_height()
+						io.write(string.format("\27[%d;1H\27[K", height))
+						io.write("Error: " .. (err or "unknown") .. "\n")
+						io.flush()
+						os.execute("sleep 1")
+						io.write(string.format("\27[%d;1H\27[K", height))
+						io.flush()
+					end
+				else
+					selected_file = join_path(cwd, sel.name)
+					running = false
+				end
+			end
+		end
+	end
+
+	return selected_file, cwd
+end
+
+return M
+
blob - 1ae918510c51a162be90f8426c383b4913c331ef (mode 644)
blob + /dev/null
--- aestel/navigate.lua
+++ /dev/null
@@ -1,175 +0,0 @@
--- aestel/navigate.lua
--- A Lua module for navigating directories
-
-local M = {}
-
--- Dependencies
-local lfs = require("lfs")
-local colors = require("aestel.colors")
-local display = require("aestel.display")
-local input = require("aestel.input")
-local menu = require("aestel.menu")
-
-local home_dir = os.getenv("HOME")
-
--- Path utilities (unchanged)
-local function normalize_path(p)
-	p = p:gsub("//+", "/")
-	if p == "/." or p == "./" then p = "/" end
-	return p:gsub("/+$", "")
-end
-
-local function join_path(base, name)
-	if base == "/" then
-		return normalize_path("/" .. name)
-	end
-	return normalize_path(base .. "/" .. name)
-end
-
-local function change_dir(cur, target, base_dir)
-	local new_path
-	if target == ".." then
-		local cur_no_trail = normalize_path(cur):gsub("/+$", "")
-		if cur_no_trail == "/" then
-			return nil, "Cannot go above root directory (/)"
-		end
-		new_path = cur_no_trail:match("(.+)/[^/]+$") or "/"
-	else
-		new_path = join_path(cur, target)
-	end
-
-	new_path = normalize_path(new_path)
-
-	if base_dir then
-		local normalized_base = normalize_path(base_dir) .. "/"
-		local normalized_new = new_path .. "/"
-		if not normalized_new:find(normalized_base, 1, true) then
-			return nil, "Access denied -- cannot navigate above base directory."
-		end
-	end
-
-	-- Attr check: Skip for "/", assume exists
-	if new_path ~= "/" then
-		local attr = lfs.attributes(new_path)
-		if not attr then
-			return nil, "Path does not exist: " .. (new_path or "unknown")
-		end
-		if attr.mode ~= "directory" then
-			return nil, new_path .. " is not a directory."
-		end
-	end
-	return new_path
-end
-
-local function build_list(path, show_hidden)
-	local dirs, files = {}, {}
-	for item in lfs.dir(path) do
-		if item ~= "." and item ~= ".." then
-			if not show_hidden and item:sub(1,1) == "." then
-				-- skip hidden
-			else
-			local full = join_path(path, item)
-			local attr = lfs.attributes(full)
-			if attr then
-				if attr.mode == "directory" then
-					table.insert(dirs, item)
-				elseif attr.mode == "file" then
-					table.insert(files, item)
-				end
-			end
-			end
-		end
-	end
-	table.sort(dirs)
-	table.sort(files)
-
-	local combined = {}
-	for _, d in ipairs(dirs) do
-		table.insert(combined, {name = d, type = "dir"})
-	end
-	for _, f in ipairs(files) do
-		table.insert(combined, {name = f, type = "file"})
-	end
-	return combined
-end
-
-function M.browse(start_dir, base_dir, title)
-	title = title or ""
-	local cwd = normalize_path(start_dir or lfs.currentdir() or home_dir)
-	local show_hidden = false
-	local header_lines = display.write_header(title)
-
-	local running = true
-	local selected_file = nil
-
-	while running do
-		local items = build_list(cwd, show_hidden)
-		if #items == 0 then
-			local selected_index = menu.menu(title, items, header_lines + 1, header_lines, "Empty directory. Press 'h' to go up, 'q' to quit.")
-			if selected_index == 0 then
-				local new_cwd, err = change_dir(cwd, "..", base_dir)
-				if new_cwd then
-					cwd = new_cwd
-					display.write_header(title)
-				else
-					display.status_line("Error: " .. (err or "unknown"), colors.REVERSE)
-					os.execute("sleep 1")
-				end
-			else
-				running = false
-			end
-		else
-			local selected_index = menu.menu(title, items, header_lines + 1, header_lines, nil, cwd)
-
-			if not selected_index then
-				running = false
-			elseif selected_index == -1 then
-				show_hidden = not show_hidden
-			elseif selected_index == 0 then
-				local new_cwd, err = change_dir(cwd, "..", base_dir)
-				if new_cwd then
-					cwd = new_cwd
-					display.write_header(title)
-				else
---					display.write_header(title)
---					local height = input.get_terminal_height()
---					io.write(string.format("\27[%d;1H\27[K", height))
---					io.write("Error: " .. (err or "unknown") .. "\n")
---					io.flush()
---					os.execute("sleep 1")
---					io.write(string.format("\27[%d;1H\27[K", height))
---					io.flush()
-                    display.status_line("Error: " .. (err or "unknown"), colors.REVERSE)
-                    os.execute("sleep 2")
-                end
-
-			else
-				local sel = items[selected_index]
-				if sel.type == "dir" then
-					local new_cwd, err = change_dir(cwd, sel.name, base_dir)
-					if new_cwd then
-						cwd = new_cwd
-						display.write_header(title, cwd)
-					else
-						display.write_header(title, cwd)
-						local height = input.get_terminal_height()
-						io.write(string.format("\27[%d;1H\27[K", height))
-						io.write("Error: " .. (err or "unknown") .. "\n")
-						io.flush()
-						os.execute("sleep 1")
-						io.write(string.format("\27[%d;1H\27[K", height))
-						io.flush()
-					end
-				else
-					selected_file = join_path(cwd, sel.name)
-					running = false
-				end
-			end
-		end
-	end
-
-	return selected_file, cwd
-end
-
-return M
-