VERSION = "1.0.0" local uutil = import("micro/util") local utf8 = import("utf8") local autoclose_pairs = {'""', "''", "``", "()", "{}", "[]"} local conditional_autoclose_pairs = {"<>", "||"} local auto_newline_pairs = {"()", "{}", "[]"} function char_at(str, i) -- lua indexing is one off from go return uutil.RuneAt(str, i - 1) end function onRune(bp, r) for i = 1, #autoclose_pairs do local pair_at_index = autoclose_pairs[i] if r == char_at(pair_at_index, 2) then local cur_line = bp.Buf:Line(bp.Cursor.Y) if char_at(cur_line, bp.Cursor.X + 1) == char_at(pair_at_index, 2) then bp:Backspace() bp:CursorRight() break end if bp.Cursor.X > 1 and (uutil.IsWordChar(char_at(cur_line, bp.Cursor.X - 1)) or char_at(cur_line, bp.Cursor.X - 1) == char_at(pair_at_index, 1)) then break end end if r == char_at(pair_at_index, 1) then local cur_line = bp.Buf:Line(bp.Cursor.Y) if bp.Cursor.X == uutil.CharacterCountInString(cur_line) or not uutil.IsWordChar(char_at(cur_line, bp.Cursor.X + 1)) then -- the '-' here is to derefence the pointer to bp.Cursor.Loc which is automatically made -- when converting go structs to lua -- It needs to be dereferenced because the function expects a non pointer struct bp.Buf:Insert(bp.Cursor.Loc * -1, char_at(pair_at_index, 2)) bp:CursorLeft() break end end end return true end function preInsertNewline(bp) local cur_line = bp.Buf:Line(bp.Cursor.Y) local curRune = char_at(cur_line, bp.Cursor.X) local nextRune = char_at(cur_line, bp.Cursor.X + 1) local ws = uutil.GetLeadingWhitespace(cur_line) for i = 1, #auto_newline_pairs do local autoNewLinePairsAtIndex = auto_newline_pairs[i] if curRune == char_at(autoNewlinePairsAtIndex, 1) then if nextRune == char_at(autoNewlinePairsAtIndex, 2) then bp:InsertNewline() bp:InsertTab() bp.Buf:Insert(bp.Cursor.Loc * -1, "\n" .. ws) bp:StartOfLine() bp:CursorLeft() return false end end end return true end function preBackspace(bp) for i = 1, #autoclose_pairs do local pair_at_index = autoclose_pairs[i] local cur_line = bp.Buf:Line(bp.Cursor.Y) if char_at(cur_line, bp.Cursor.X + 1) == char_at(pair_at_index, 2) and char_at(cur_line, bp.Cursor.X) == char_at(pair_at_index, 1) then bp:Delete() end end return true end