changeset 15:93e46dadb694

add indent
author Franklin Schmidt <fschmidt@gmail.com>
date Sun, 06 Apr 2025 16:34:58 -0600
parents 357fdbf446cb
children 90abee9e07d5
files editor.luan
diffstat 1 files changed, 66 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
diff -r 357fdbf446cb -r 93e46dadb694 editor.luan
--- a/editor.luan	Sat Apr 05 22:50:38 2025 -0600
+++ b/editor.luan	Sun Apr 06 16:34:58 2025 -0600
@@ -1,6 +1,11 @@
 local Luan = require "luan:Luan.luan"
 local error = Luan.error
 local ipairs = Luan.ipairs or error()
+local stringify = Luan.stringify or error()
+local String = require "luan:String.luan"
+local sub_string = String.sub or error()
+local replace = String.replace or error()
+local starts_with = String.starts_with or error()
 local Io = require "luan:Io.luan"
 local print = Io.print or error()
 local new_file = Io.schemes.file or error()
@@ -114,6 +119,21 @@
 		end
 		edit_menu.add_separator()
 		do
+			local indent = new_menu_item()
+			indent.text = "Indent"
+			indent.accelerator = "meta CLOSE_BRACKET"
+			indent.add_action_listener(window.indent)
+			edit_menu.add(indent)
+		end
+		do
+			local unindent = new_menu_item()
+			unindent.text = "Unindent"
+			unindent.accelerator = "meta OPEN_BRACKET"
+			unindent.add_action_listener(window.unindent)
+			edit_menu.add(unindent)
+		end
+		edit_menu.add_separator()
+		do
 			local select_all = new_menu_item()
 			select_all.text = "Select All"
 			select_all.accelerator = "meta A"
@@ -190,7 +210,7 @@
 	text_area.line_wrap = true
 	text_area.tab_size = 4
 	text_area.set_font{ family="Monospaced", size=13 }
-	text_area.caret_position = 0
+	text_area.set_selection(0)
 	--print(text_area.line_count)
 	local scroll_pane = new_scroll_pane(text_area)
 	local line_numbers = new_text_area_line_numbers(text_area)
@@ -226,12 +246,55 @@
 		return true
 	end
 	function window.revert()
-		local caret_position = text_area.caret_position
+		local selection = text_area.get_selection()
 		local text = file.read_text()
 		text_area.text = text
-		text_area.caret_position = min(caret_position,#text)
+		text_area.set_selection(min(selection,#text+1))
 		text_area.document.set_unedited()
 	end
+	local function selection_lines()
+		local start_seletion, end_selection = text_area.get_selection()
+		local end_ = end_selection == start_seletion and end_selection or end_selection - 1
+		local start_line = text_area.get_line_from_position(start_seletion)
+		local end_line = text_area.get_line_from_position(end_)
+		local start_pos = text_area.get_line_start_position(start_line)
+		local end_pos = text_area.get_line_end_position(end_line)
+		local text = text_area.text
+		text = sub_string(text,start_pos,end_pos-2)
+		return {
+			text = text
+			start_pos = start_pos
+			length = #text
+			lines = end_line - start_line + 1
+			start_seletion = start_seletion
+			end_selection = end_selection
+		}
+	end
+	function window.indent()
+		local r = selection_lines()
+		local text = r.text
+		local start_pos = r.start_pos
+		text = "\t"..replace(text,"\n","\n\t")
+		text_area.replace(start_pos,r.length,text)
+		--logger.info(stringify{text_area.get_selection()})
+		text_area.set_selection( r.start_seletion+1, r.end_selection+r.lines )
+	end
+	function window.unindent()
+		local r = selection_lines()
+		local text = r.text
+		text = "\n"..text
+		local start_seletion = r.start_seletion
+		if starts_with(text,"\n\t") then
+			start_seletion = start_seletion - 1
+		end
+		local len1 = #text
+		text = replace(text,"\n\t","\n")
+		local len2 = #text
+		local end_selection = r.end_selection - (len1 - len2)
+		text = sub_string(text,2)
+		text_area.replace(r.start_pos,r.length,text)
+		text_area.set_selection(start_seletion,end_selection)
+	end
 	local menu_bar = make_menu_bar(window)
 	frame.set_menu_bar(menu_bar)
 	frame.pack()