mirror of
https://github.com/Relintai/Godot-TextEditor.git
synced 2025-01-26 16:59:19 +01:00
1.11
This commit is contained in:
parent
dfe30486d2
commit
4225903a92
16
CHANGES.md
16
CHANGES.md
@ -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.
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Text Editor
|
||||
Version `1.10`
|
||||
Version `1.11`
|
||||
|
||||
![](README/readme_preview.png)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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():
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 = {}
|
||||
|
@ -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()])
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)))
|
||||
|
50
addons/text_editor/ext/ext_rpy.gd
Normal file
50
addons/text_editor/ext/ext_rpy.gd
Normal 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
|
@ -3,5 +3,5 @@
|
||||
name="TextEditor"
|
||||
description="A text editor for Godot."
|
||||
author="teebar"
|
||||
version="1.10"
|
||||
version="1.11"
|
||||
script="plugin.gd"
|
||||
|
Loading…
Reference in New Issue
Block a user