This commit is contained in:
teebarjunk 2021-12-19 10:43:24 -05:00
parent dfe30486d2
commit 4225903a92
14 changed files with 324 additions and 156 deletions

View File

@ -1,3 +1,19 @@
# 1.11
- Toggled `Low Processor Mode` to keep cpu/gpu usage down.
- Simplified *File List* filter display.
- *File List* filter now scans closed folders as well.
- Folder icon in *File List* changes when open/closed.
- *File Editor* now saves states of:
- Cursor position.
- Selection.
- Scroll position.
- Enabled hiding in *File Editor*.
- *Tag List* tags are sorted.
- Added `.rpy` *Renpy* file support.
- Added tab/spaces toggle.
- Fixed files with `.` in their name not showing up.
- Fixed error caused by clicking *File List* symbol for unopened file.
# 1.10
- Added cursor panel at bottom of Text Editor.
- Word counter.

View File

@ -1,5 +1,5 @@
# Text Editor
Version `1.10`
Version `1.11`
![](README/readme_preview.png)

View File

@ -13,7 +13,7 @@ const DNAME_TRASH:String = ".trash"
const FNAME_STATE:String = ".text_editor_state.json"
const MAIN_EXTENSIONS:PoolStringArray = PoolStringArray([
"txt", "md", "json", "csv", "cfg", "ini", "yaml"
"txt", "md", "json", "csv", "cfg", "ini", "yaml", "rpy"
])
const INTERNAL_EXTENSIONS:PoolStringArray = PoolStringArray([
"gd", "tres", "tscn", "import", "gdignore", "gitignore"
@ -26,6 +26,7 @@ const FILE_FILTERS:PoolStringArray = PoolStringArray([
"*.cfg ; Config",
"*.ini ; Config",
"*.yaml ; YAML",
"*.rpy; Renpy Script"
])
const DIR_COLORS:Dictionary = {
@ -289,6 +290,11 @@ func _process(delta):
progress_bar.visible = false
set_process(false)
func get_file_data(file_path:String) -> Dictionary:
if not file_path in file_data:
update_file_data(file_path)
return file_data.get(file_path, {})
func update_file_data(file_path:String):
var helper = get_extension_helper(file_path)
var text = TE_Util.load_text(file_path)
@ -300,6 +306,7 @@ func update_file_data(file_path:String):
data.tags = ftags
file_data[file_path] = data
# collect tags
tags.clear()
for d in file_data.values():
for tag in d.tags:
@ -307,8 +314,21 @@ func update_file_data(file_path:String):
tags[tag] = d.tags[tag]
else:
tags[tag] += d.tags[tag]
# sort tags
var unsorted:Array = []
for k in tags:
unsorted.append([k, tags[k]])
unsorted.sort_custom(self, "_sort_tags")
# repopulate
tags.clear()
for t in unsorted:
tags[t[0]] = t[1]
emit_signal("tags_updated")
func _sort_tags(a, b):
return a[1] > b[1]
# "001_file" -> ["001_", "file"]
func _split_header(fname:String):
var out = ["", ""]
@ -386,6 +406,7 @@ func save_state():
"shortcuts": shortcuts,
"file_list": file_list,
"file_data": file_data,
"div1": $c/div1.split_offset,
"div2": $c/div1/div2.split_offset,
@ -400,6 +421,7 @@ func save_state():
TE_Util.save_json(current_directory.plus_file(FNAME_STATE), state)
emit_signal("state_saved")
print("state saved")
func load_state():
var state:Dictionary = TE_Util.load_json(current_directory.plus_file(FNAME_STATE))
@ -421,6 +443,7 @@ func load_state():
self[k] = state[k]
_load_property(state, "file_list")
_load_property(state, "file_data")
var selected_file:String
for file_path in state.tabs:
@ -428,6 +451,7 @@ func load_state():
file_path = get_globalized_path(file_path)
var tab = _open_file(file_path)
tab.set_state(st)
# tab._load_file_data()
if file_path == state.selected:
selected_file = file_path
@ -643,7 +667,9 @@ func _menu_view_file(index:int):
exts_enabled[ext] = not exts_enabled[ext]
popup_view_file.set_item_checked(index, exts_enabled[ext])
else:
print("no %s in %s" % [ext, exts_enabled])
print("no %s in %s. adding..." % [ext, exts_enabled])
exts_enabled[ext] = true
popup_view_file.set_item_checked(index, exts_enabled[ext])
refresh_files()
save_state()
@ -1166,7 +1192,7 @@ func _sort_on_ext(a, b):
static func get_extension(file_path:String) -> String:
var file = file_path.get_file()
if "." in file:
return file.split(".", true, 1)[1]
return file.rsplit(".", true, 1)[1]
return ""
var complained_ext:Array = []
@ -1174,7 +1200,7 @@ var complained_ext:Array = []
func get_extension_helper(file_path:String) -> TE_ExtensionHelper:
var ext:String = get_extension(file_path).replace(".", "_")
var ext_path:String = "res://addons/text_editor/ext/ext_%s.gd" % ext
if ext in ["cfg", "csv", "ini", "json", "md", "yaml", "txt"]:
if ext in ["cfg", "csv", "ini", "json", "md", "yaml", "txt", "rpy"]:
return load(ext_path).new()
# only complain once

View File

@ -39,14 +39,15 @@ func _ready():
_e = editor.connect("file_renamed", self, "_file_renamed")
_e = editor.connect("dir_tint_changed", self, "_dir_tint_changed")
_e = connect("text_changed", self, "text_changed")
_e = connect("focus_entered", self, "set", ["in_focus", true])
_e = connect("focus_exited", self, "set", ["in_focus", false])
_e = connect("focus_entered", self, "_focus_entered")
_e = connect("focus_exited", self, "_focus_exited")
_e = connect("mouse_entered", self, "set", ["mouse_inside", true])
_e = connect("mouse_exited", self, "set", ["mouse_inside", false])
# _e = connect("cursor_changed", self, "_cursor_changed")
if get_parent() is TabContainer:
get_parent().connect("tab_changed", self, "_tab_changed")
get_parent().connect("tab_selected", self, "_tab_changed")
# if get_parent() is TabContainer:
# get_parent().connect("tab_changed", self, "_tab_changed")
# get_parent().connect("tab_selected", self, "_tab_changed")
add_font_override("font", editor.FONT)
var popup = get_menu()
@ -79,6 +80,37 @@ func _ready():
TE_Util.dig(self, self, "_node")
func set_visible(v):
prints(file_path, v)
.set_visible(v)
func _focus_entered():
if not in_focus:
in_focus = true
func _focus_exited():
if in_focus:
in_focus = false
func set_cursor_state(s:Array):
cursor_set_line(s[0], s[1])
if len(s) > 2:
select(s[2], s[3], s[4], s[5])
func get_cursor_state() -> Array:
if is_selection_active():
return [
cursor_get_line(),
cursor_get_column(),
get_selection_from_line(),
get_selection_from_column(),
get_selection_to_line(),
get_selection_to_column()]
else:
return [
cursor_get_line(),
cursor_get_column()]
func _dir_tint_changed(dir:String):
if file_path.get_base_dir() == dir:
update_name()
@ -90,51 +122,25 @@ func _popup_menu(index:int):
"Capitalize": selection_capitalize()
"Variable": selection_variable()
var cl
var cc
var isa
var sl1
var sc1
var sl2
var sc2
func _remember_selection():
cl = cursor_get_line()
cc = cursor_get_column()
isa = is_selection_active()
if isa:
sl1 = get_selection_from_line()
sc1 = get_selection_from_column()
sl2 = get_selection_to_line()
sc2 = get_selection_to_column()
func _remake_selection():
cursor_set_line(cl)
cursor_set_column(cc)
if isa:
select(sl1, sc1, sl2, sc2)
func selection_uppercase():
_remember_selection()
var s = get_cursor_state()
insert_text_at_cursor(get_selection_text().to_upper())
_remake_selection()
set_cursor_state(s)
func selection_lowercase():
_remember_selection()
var s = get_cursor_state()
insert_text_at_cursor(get_selection_text().to_lower())
_remake_selection()
set_cursor_state(s)
func selection_variable():
_remember_selection()
var s = get_cursor_state()
insert_text_at_cursor(TE_Util.to_var(get_selection_text()))
_remake_selection()
set_cursor_state(s)
func selection_capitalize():
_remember_selection()
var s = get_cursor_state()
insert_text_at_cursor(get_selection_text().capitalize())
_remake_selection()
set_cursor_state(s)
func _node(n):
var _e
@ -151,17 +157,12 @@ func _scroll_h(h:HScrollBar):
func _scroll_v(v:VScrollBar):
vscroll = v.value
func _tab_changed(index:int):
var myindex = get_index()
if index == myindex and visible:
# grab_focus()
# grab_click_focus()
yield(get_tree(), "idle_frame")
set_h_scroll(hscroll)
set_v_scroll(vscroll)
func get_state() -> Dictionary:
var state = { hscroll=scroll_horizontal, vscroll=scroll_vertical }
var state = {
hscroll=scroll_horizontal,
vscroll=scroll_vertical,
cursor=get_cursor_state()
}
# unsaved
if file_path == "":
state.text = text
@ -169,22 +170,21 @@ func get_state() -> Dictionary:
func set_state(state:Dictionary):
yield(get_tree(), "idle_frame")
hscroll = state.hscroll
vscroll = state.vscroll
set_h_scroll(state.hscroll)
set_v_scroll(state.vscroll)
if "hscroll" in state:
hscroll = state.hscroll
vscroll = state.vscroll
set_h_scroll(state.hscroll)
set_v_scroll(state.vscroll)
if "text" in state:
if state.text.strip_edges():
text = state.text
else:
editor._close_file(file_path)
func _file_renamed(old_path:String, new_path:String):
if old_path == file_path:
file_path = new_path
update_name()
update_colors()
if "cursor" in state:
set_cursor_state(state.cursor)
func _update_selected_line():
var l = cursor_get_line()
@ -216,6 +216,11 @@ func _input(e):
if not editor.is_plugin_active():
return
# custom tab system
if visible and in_focus and e is InputEventKey and e.pressed and e.scancode == KEY_TAB:
insert_text_at_cursor(helper.get_tab())
get_tree().set_input_as_handled()
if not visible or not in_focus or not mouse_inside:
return
@ -314,42 +319,23 @@ func _unhandled_key_input(e):
helper.toggle_comment(self)
get_tree().set_input_as_handled()
func _file_renamed(old_path:String, new_path:String):
if old_path == file_path:
file_path = new_path
update_name()
update_colors()
func _file_selected(p:String):
if not p:
if p != file_path:
return
if p == file_path:
update_symbols()
update_heading()
var cl = cursor_get_line()
var cc = cursor_get_column()
var fl
var fc
var tl
var tc
var had_selection = false
if is_selection_active():
had_selection = true
fl = get_selection_from_line()
fc = get_selection_from_column()
tl = get_selection_to_line()
tc = get_selection_to_column()
grab_focus()
grab_click_focus()
yield(get_tree(), "idle_frame")
cursor_set_line(cl)
cursor_set_column(cc)
if had_selection:
select(fl, fc, tl, tc)
grab_focus()
grab_click_focus()
update_symbols()
update_heading()
# yield(get_tree(), "idle_frame")
#
# grab_focus()
# grab_click_focus()
func goto_symbol(index:int):
var syms = symbols.keys()
@ -393,6 +379,8 @@ func set_temporary(t):
update_name()
func update_symbols():
update_helper()
symbols.clear()
tags.clear()
@ -438,12 +426,15 @@ func load_file(path:String):
clear_undo_history()
update_colors()
update_name()
func update_colors():
clear_colors()
func update_helper():
helper = editor.get_extension_helper(file_path)
helper.apply_colors(editor, self)
func update_colors():
clear_colors()
update_helper()
func _created_nonexisting(fp:String):
file_path = fp
modified = false

View File

@ -29,11 +29,11 @@ func _tab_changed(index:int):
tab = new_tab
var _e
_e = tab.connect("cursor_changed", self, "_cursor_changed")
_e = tab.connect("text_changed", self, "_text_changed")
func _text_changed():
# print("text changed")
pass
# _e = tab.connect("text_changed", self, "_text_changed")
#
#func _text_changed():
## print("text changed")
# pass
func _input(event):
if event is InputEventKey and event.pressed and tab and is_instance_valid(tab) and tab.has_focus():

View File

@ -2,6 +2,7 @@ extends TabContainer
onready var editor:TE_Editor = owner
var mouse:bool = false
var last_tab_index:int = -1
func _ready():
if not editor.is_plugin_active():
@ -10,9 +11,42 @@ func _ready():
var _e
_e = connect("mouse_entered", self, "set", ["mouse", true])
_e = connect("mouse_exited", self, "set", ["mouse", false])
_e = connect("tab_changed", self, "_tab_changed")
add_font_override("font", editor.FONT_R)
func _tab_changed(index):
var tab
var data
# if last_tab_index >= 0 and last_tab_index < get_child_count():
# tab = get_child(last_tab_index)
# data = editor.get_file_data(tab.file_path)
# data.hscroll = tab.hscroll
# data.vscroll = tab.vscroll
# data.cursor = tab.get_cursor_state()
# prints("SAVED", tab.file_path, tab.cursor_state)
#
# yield(get_tree(), "idle_frame")
#
# tab = get_child(index)
# data = editor.get_file_data(tab.file_path)
# if "cursor" in data:
# print("LOADED", data.cursor)
# tab.set_cursor_state(data.cursor)
# tab.set_h_scroll(data.hscroll)
# tab.set_v_scroll(data.vscroll)
tab = get_child(index)
# var s = tab.get_cursor_state()
tab.grab_focus()
# tab.grab_click_focus()
# yield(get_tree(), "idle_frame")
# tab.set_cursor_state(s)
last_tab_index = index
# prints(tab, tab.file_path)
func _input(e):
if not editor.is_plugin_active():
return

View File

@ -219,7 +219,7 @@ var lines:PoolStringArray = PoolStringArray()
func _redraw():
lines = PoolStringArray()
_draw_dir(editor.file_list[""], 0)
lines.append_array(_draw_dir(editor.file_list[""], 0))
set_bbcode(lines.join("\n"))
func _dull_nonwords(s:String, clr:Color, dull:Color) -> String:
@ -235,40 +235,50 @@ func _dull_nonwords(s:String, clr:Color, dull:Color) -> String:
out += clr(p[1], dull if p[0] else clr)
return out
const FOLDER:String = "🗀" # not visible in godot
func _draw_dir(dir:Dictionary, deep:int):
const FOLDER_CLOSED:String = "🗀" # not visible in Godot.
const FOLDER_OPEN:String = "🗁" # not visible in Godot.
func _draw_dir(dir:Dictionary, deep:int) -> Array:
var is_tagging = editor.is_tagging()
var dimmest:float = .5 if is_tagging else 0.0
var tint = editor.get_tint_color(dir.tint)
var dull = Color.white.darkened(.65)
var dull_tint = tint.darkened(.5)
var space = clr("".repeat(deep), Color.white.darkened(.8))
var space = ""
var file:String = dir.file_path
space = clr("".repeat(deep), Color.white.darkened(.8))
var head:String = "" if dir.open else ""
head = clr(space+FOLDER, Color.gold) + clr(head, Color.white.darkened(.5))
head += " " + b(_dull_nonwords(file.get_file(), tint.darkened(0 if editor.is_dir_tagged(dir) else 0.5), dull))
var fold:String = FOLDER_OPEN if dir.open else FOLDER_CLOSED
var dname = b(_dull_nonwords(file.get_file(), tint.darkened(0 if editor.is_dir_tagged(dir) else 0.5), dull))
dname = clr("", dull) + dname + clr("", dull)
head = clr(space+fold, Color.gold) + clr(head, Color.white.darkened(.5))
head += " %s" % dname
var link:String = meta(head, ["d", dir], editor.get_localized_path(file))
if editor.is_trash_path(file):
link += " " + meta(clr("", Color.yellowgreen), ["unrecycle", dir], file)
lines.append(link)
var out = []
var sel = editor.get_selected_tab()
sel = sel.file_path if sel else ""
if dir.open:
if dir.open or filter:
# draw dirs
for path in dir.dirs:
var file_path = dir.all[path]
if file_path is Dictionary and file_path.show:
_draw_dir(file_path, deep+1)
if file_path is Dictionary and (file_path.show or filter):
out.append_array(_draw_dir(file_path, deep+1))
# draw files
var last = len(dir.files)-1
for i in len(dir.files):
var file_path = dir.files[i]
file = file_path.get_file()
var fname = file_path.get_file()
file = fname
var p = [file, ""] if not "." in file else file.split(".", true, 1)
file = p[0]
var ext = p[1]
@ -276,9 +286,9 @@ func _draw_dir(dir:Dictionary, deep:int):
var is_selected = file_path == sel
var is_opened = editor.is_opened(file_path)
var color = tint
head = "┣╸" if i != last else "┗╸"
head = "" if filter else "┣╸" if i != last else "┗╸"
var fname_lower = file.to_lower()
var fname_lower = fname.to_lower()
if "readme" in fname_lower:
head = "🛈"
@ -308,21 +318,41 @@ func _draw_dir(dir:Dictionary, deep:int):
line = u(line)
var hint_path = editor.get_localized_path(file_path)
var symbol_lines = []
var file_lines = []
if not editor._scanning:
var fdata = editor.file_data[file_path]
var fdata = editor.get_file_data(file_path)
var symbols = fdata.symbols.values()
for j in range(1, len(symbols)):
if fdata.open or filter:
var sdata = symbols[j]
var sname = sdata.name
if filter and not filter in sname.to_lower():
var sdata:Dictionary = symbols[j]
var sname:String = sdata.name
var index = sname.to_lower().find(filter)
if filter and index == -1:
continue
var s = clr("|%s %s) " % [" ".repeat(sdata.deep), j], dull) + clr(sname, dull_tint)
var h = hint_path + " #" + sname
symbol_lines.append(meta(space + s, ["fs", file_path, j], h))
var sname_highlighted = TE_Util.highlight(sname, index, len(filter), TE_Util.hue_shift(dull_tint, -.075), Color.white)
var s = clr(" @ " + "-".repeat(sdata.deep), dull) + sname_highlighted
var h = hint_path + " @" + sname
file_lines.append(meta(space + s, ["fs", file_path, j], h))
if symbol_lines or not (filter and not filter in fname_lower):
lines.append(meta(space + head + line, ["f", file_path], hint_path))
lines.append_array(symbol_lines)
if filter:
var index = fname_lower.find(filter)
if index != -1:
line = TE_Util.highlight(fname, index, len(filter), dull_tint, Color.white)
# show file name if not filtering, or if
if not filter or file_lines:
file_lines.push_front(meta(space + head + line, ["f", file_path], hint_path))
# file_lines.push_front(space + head + line)
out.append_array(file_lines)
# show folder name if not filtering, or if filter catches a sub file or subsymbol
if not filter or out:
out.push_front(link)
return out

View File

@ -73,14 +73,17 @@ func _text_entered(search_for:String):
var ltext = got_lines[i][2]
if highlight:
var line:String = ltext
var head:String = line.substr(0, char_index)
var midd:String = line.substr(char_index, len(search_for))
var tail:String = line.substr(char_index+len(search_for))
head = clr(head, Color.white.darkened(.25))
midd = b(clr(midd, Color.white))
tail = clr(tail, Color.white.darkened(.25))
l = "\t" + clr(str(lindex) + ": ", Color.white.darkened(.25)) + (head+midd+tail)
# var line:String = ltext
# var head:String = line.substr(0, char_index)
# var midd:String = line.substr(char_index, len(search_for))
# var tail:String = line.substr(char_index+len(search_for))
# head = clr(head, Color.white.darkened(.25))
# midd = b(clr(midd, Color.white))
# tail = clr(tail, Color.white.darkened(.25))
var h = TE_Util.highlight(ltext, char_index, len(search_for), Color.white.darkened(.25), Color.white)
l = "\t" + clr(str(lindex) + ": ", Color.white.darkened(.25)) + h
else:
l = "\t" + clr(str(lindex) + ": ", Color.white.darkened(.65)) + clr(ltext, Color.white.darkened(.5))
@ -91,6 +94,8 @@ func _text_entered(search_for:String):
set_bbcode(bbcode.join("\n"))
# get a list of files containging lines
func _search(search_for:String) -> Dictionary:
var out = {}

View File

@ -26,27 +26,27 @@ func _clicked(args:Array):
editor.enable_tag(tag, not was_enabled)
func sort_tags(tags:Dictionary):
var sorter:Array = []
for tag in tags:
sorter.append([tag, tags[tag]])
sorter.sort_custom(self, "_sort_tags")
tags.clear()
for item in sorter:
tags[item[0]] = item[1]
return tags
func _sort_tags(a, b):
return a[0] < b[0]
#func sort_tags(tags:Dictionary):
# var sorter:Array = []
# for tag in tags:
# sorter.append([tag, tags[tag]])
#
# sorter.sort_custom(self, "_sort_tags")
#
# tags.clear()
# for item in sorter:
# tags[item[0]] = item[1]
# return tags
#
#func _sort_tags(a, b):
# return a[0] < b[0]
func _redraw():
var tab = editor.get_selected_tab()
var tags = editor.tags
var tab_tags = {} if not tab else tab.tags
sort_tags(tags)
# sort_tags(tags)
if not tags:
set_bbcode("[color=#%s][i][center]*No tags*" % [Color.webgray.to_html()])

View File

@ -200,6 +200,18 @@ static func file_size(path:String) -> String:
static func hue_shift(c:Color, h:float) -> Color:
return c.from_hsv(wrapf(c.h + h, 0.0, 1.0), c.s, c.v, c.a)
static func highlight(line:String, start:int, length:int, default_color:Color, highlight_color:Color) -> String:
var head:String = line.substr(0, start)
var midd:String = line.substr(start, length)
var tail:String = line.substr(start + length)
head = clr(head, default_color)
midd = b(clr(midd, highlight_color))
tail = clr(tail, default_color)
return head + midd + tail
static func b(t:String) -> String: return "[b]%s[/b]" % t
static func clr(t:String, c:Color) -> String: return "[color=#%s]%s[/color]" % [c.to_html(), t]
#static func saturate(c:Color, s:float=1.0, v:float=1.0) -> Color:
# return c.from_hsv(c.h, c.s * s, c.v * v, c.a)

View File

@ -79,6 +79,7 @@ show_line_numbers = true
draw_tabs = true
fold_gutter = true
highlight_all_occurrences = true
hiding_enabled = true
minimap_draw = true
script = ExtResource( 4 )
@ -171,7 +172,7 @@ margin_top = 3.0
margin_right = 1010.0
margin_bottom = 20.0
custom_fonts/font = ExtResource( 12 )
text = "v1.10"
text = "v1.11"
align = 2
[node name="div1" type="HSplitContainer" parent="c"]
@ -211,7 +212,7 @@ margin_right = 192.0
margin_bottom = 27.0
custom_fonts/font = ExtResource( 12 )
clear_button_enabled = true
placeholder_text = "Filter"
placeholder_text = "File Filter"
[node name="list_files" type="RichTextLabel" parent="c/div1/c2/c/c"]
margin_top = 31.0
@ -541,7 +542,7 @@ margin_right = 166.0
margin_bottom = 27.0
custom_fonts/font = ExtResource( 12 )
clear_button_enabled = true
placeholder_text = "Filter"
placeholder_text = "Symbol Filter"
[node name="list_symbols" type="RichTextLabel" parent="c/div1/div2/c2/c/c/c"]
margin_top = 31.0

View File

@ -4,6 +4,9 @@ class_name TE_ExtensionHelper
var symbols:Dictionary = {}
func get_tab() -> String:
return " "
func generate_meta(t:TextEdit, r:RichTextLabel):
var chars = TE_Util.commas(len(t.text))
var words = TE_Util.commas(len(t.text.split(" ", false)))

View File

@ -0,0 +1,50 @@
tool
extends TE_ExtensionHelper
func get_tab() -> String:
return " "
func apply_colors(e:TE_Editor, t:TextEdit):
.apply_colors(e, t)
for k in "label menu define default scene show with play return jump call".split(" "):
t.add_keyword_color(k, e.color_symbol)
# strings
t.add_color_region('"', '"', e.color_var)
# bools
t.add_keyword_color("True", e.color_var)
t.add_keyword_color("False", e.color_var)
# comments
t.add_color_region("#", "", e.color_comment, true)
t.add_color_region("$ ", "", e.color_comment, true)
func get_symbols(t:String):
var out = .get_symbols(t)
var last = add_symbol()
var lines = t.split("\n")
var i = 0
while i < len(lines):
# symbols
if lines[i].begins_with("label "):
var key = lines[i].substr(len("label ")).strip_edges()
key = key.substr(0, len(key)-1)
last = add_symbol(i, 0, key)
elif lines[i].begins_with("menu "):
var key = lines[i].substr(len("menu ")).strip_edges()
key = key.substr(0, len(key)-1)
last = add_symbol(i, 0, key)
# tags
elif "#" in lines[i]:
var p = lines[i].rsplit("#", true, 1)[1]
if "#" in p:
for tag in p.split("#"):
last.tags.append(tag)
i += 1
return out

View File

@ -3,5 +3,5 @@
name="TextEditor"
description="A text editor for Godot."
author="teebar"
version="1.10"
version="1.11"
script="plugin.gd"