mirror of
https://github.com/Relintai/Godot-TextEditor.git
synced 2025-02-04 19:15:54 +01:00
1.4
This commit is contained in:
parent
ba5e9148cb
commit
8fd5a31874
14
CHANGES.md
14
CHANGES.md
@ -1,3 +1,16 @@
|
|||||||
|
# 1.4
|
||||||
|
- Added `sys` info tab.
|
||||||
|
- Added `console` info tab. (wip)
|
||||||
|
- Changing extension updates colors.
|
||||||
|
- Fixed exported build not styling things properly.
|
||||||
|
- Fixed symbols/tags not showing when first booting editor.
|
||||||
|
- Tweaked colors.
|
||||||
|
- Internal rewriting.
|
||||||
|
|
||||||
|
# 1.3
|
||||||
|
- Basic search implemented. `Ctrl + F`
|
||||||
|
- Can create links inside `()` which makes markdown links clickable.: `Ctrl + Click`
|
||||||
|
|
||||||
# 1.2
|
# 1.2
|
||||||
- Can unrecycle now. (Make sure `view/Directories/.trash` is toggled, then press arrow.
|
- Can unrecycle now. (Make sure `view/Directories/.trash` is toggled, then press arrow.
|
||||||
- Added folder recycle option
|
- Added folder recycle option
|
||||||
@ -7,6 +20,7 @@
|
|||||||
- Settings are saved more frequently.
|
- Settings are saved more frequently.
|
||||||
- Fixed file dragging.
|
- Fixed file dragging.
|
||||||
- Fixed meta table not resizing.
|
- Fixed meta table not resizing.
|
||||||
|
- Tweaked symbol colorizer to emphasize depth.
|
||||||
- Bug fixes.
|
- Bug fixes.
|
||||||
|
|
||||||
# 1.1
|
# 1.1
|
||||||
|
@ -58,7 +58,8 @@ This will then highlight *Files* and *Symbols* that have that tag.
|
|||||||
|
|
||||||
# Todo
|
# Todo
|
||||||
- [x] `1.1` Preserve folders open/close state.
|
- [x] `1.1` Preserve folders open/close state.
|
||||||
- [ ] Search.
|
- [x] `1.3` Search all files.
|
||||||
|
- [ ] Search file.
|
||||||
- [ ] Find and replace.
|
- [ ] Find and replace.
|
||||||
- [ ] Improve meta data based on format.
|
- [ ] Improve meta data based on format.
|
||||||
- [x] `1.2` Recycle folders.
|
- [x] `1.2` Recycle folders.
|
||||||
|
13
addons/text_editor/TE_Console.gd
Normal file
13
addons/text_editor/TE_Console.gd
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
extends "res://addons/text_editor/TE_RichTextLabel.gd"
|
||||||
|
|
||||||
|
func msg(msg):
|
||||||
|
append_bbcode(str(msg))
|
||||||
|
newline()
|
||||||
|
|
||||||
|
func err(err):
|
||||||
|
append_bbcode(clr(err, Color.tomato))
|
||||||
|
newline()
|
||||||
|
|
||||||
|
func info(info):
|
||||||
|
append_bbcode(clr(info, Color.aquamarine))
|
||||||
|
newline()
|
@ -1,7 +1,7 @@
|
|||||||
tool
|
tool
|
||||||
extends RichTextLabel
|
extends RichTextLabel
|
||||||
|
|
||||||
var editor:TextEditor
|
var editor:TE_TextEditor
|
||||||
var click_pos:Vector2
|
var click_pos:Vector2
|
||||||
|
|
||||||
func _init(text):
|
func _init(text):
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
tool
|
tool
|
||||||
extends TextEdit
|
extends TextEdit
|
||||||
|
|
||||||
var editor:TextEditor
|
var editor:TE_TextEditor
|
||||||
var _hscroll:HScrollBar
|
var _hscroll:HScrollBar
|
||||||
var _vscroll:VScrollBar
|
var _vscroll:VScrollBar
|
||||||
|
|
||||||
@ -82,6 +82,7 @@ func _file_renamed(old_path:String, new_path:String):
|
|||||||
if old_path == file_path:
|
if old_path == file_path:
|
||||||
file_path = new_path
|
file_path = new_path
|
||||||
update_name()
|
update_name()
|
||||||
|
update_colors()
|
||||||
|
|
||||||
func _input(e):
|
func _input(e):
|
||||||
if not editor.is_plugin_active():
|
if not editor.is_plugin_active():
|
||||||
@ -90,6 +91,22 @@ func _input(e):
|
|||||||
if not visible or not in_focus:
|
if not visible or not in_focus:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if e is InputEventMouseButton and not e.pressed and e.control:
|
||||||
|
var line:String = get_line(cursor_get_line())
|
||||||
|
var ca = line.find("(")
|
||||||
|
var cb = line.find_last(")")
|
||||||
|
if ca != -1 and cb != -1:
|
||||||
|
var a:int = cursor_get_column()
|
||||||
|
var b:int = cursor_get_column()
|
||||||
|
if ca < a and cb >= b:
|
||||||
|
while a > 0 and not line[a] in "(": a -= 1
|
||||||
|
while b <= len(line) and not line[b] in ")": b += 1
|
||||||
|
var file = line.substr(a+1, b-a-1)
|
||||||
|
var link = file_path.get_base_dir().plus_file(file)
|
||||||
|
editor.open_file(link)
|
||||||
|
editor.select_file(link)
|
||||||
|
# print(link)
|
||||||
|
|
||||||
if e is InputEventKey and e.pressed and e.control:
|
if e is InputEventKey and e.pressed and e.control:
|
||||||
# tab to next
|
# tab to next
|
||||||
if e.scancode == KEY_TAB:
|
if e.scancode == KEY_TAB:
|
||||||
@ -172,6 +189,11 @@ func _file_selected(p:String):
|
|||||||
update_symbols()
|
update_symbols()
|
||||||
update_heading()
|
update_heading()
|
||||||
|
|
||||||
|
func goto_line(line:int):
|
||||||
|
# force scroll to bottom so selected line will be at top
|
||||||
|
cursor_set_line(get_line_count())
|
||||||
|
cursor_set_line(line)
|
||||||
|
|
||||||
func text_changed():
|
func text_changed():
|
||||||
if last_selected:
|
if last_selected:
|
||||||
match last_key:
|
match last_key:
|
||||||
@ -241,17 +263,19 @@ func load_file(path:String):
|
|||||||
file_path = path
|
file_path = path
|
||||||
text = TE_Util.load_text(path)
|
text = TE_Util.load_text(path)
|
||||||
update_name()
|
update_name()
|
||||||
|
update_colors()
|
||||||
|
|
||||||
# update colors
|
func update_colors():
|
||||||
clear_colors()
|
clear_colors()
|
||||||
|
helper = editor.get_extension_helper(file_path)
|
||||||
helper = TextEditor.get_extension_helper(file_path)
|
|
||||||
helper.apply_colors(editor, self)
|
helper.apply_colors(editor, self)
|
||||||
|
|
||||||
func save_file():
|
func save_file():
|
||||||
if modified:
|
if modified:
|
||||||
if not file_path.begins_with("res://"):
|
if not file_path.begins_with(editor.current_directory):
|
||||||
push_error("can't save to %s" % file_path)
|
var err_msg = "can't save to %s" % file_path
|
||||||
|
push_error(err_msg)
|
||||||
|
editor.console.err(err_msg)
|
||||||
return
|
return
|
||||||
|
|
||||||
modified = false
|
modified = false
|
||||||
|
@ -1,13 +1,18 @@
|
|||||||
extends TabContainer
|
extends TabContainer
|
||||||
|
|
||||||
onready var editor:TextEditor = owner
|
onready var editor:TE_TextEditor = owner
|
||||||
var mouse:bool = false
|
var mouse:bool = false
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
|
if not editor.is_plugin_active():
|
||||||
|
return
|
||||||
|
|
||||||
var _e
|
var _e
|
||||||
_e = connect("mouse_entered", self, "set", ["mouse", true])
|
_e = connect("mouse_entered", self, "set", ["mouse", true])
|
||||||
_e = connect("mouse_exited", self, "set", ["mouse", false])
|
_e = connect("mouse_exited", self, "set", ["mouse", false])
|
||||||
|
|
||||||
|
add_font_override("font", editor.FONT_R)
|
||||||
|
|
||||||
func _input(e):
|
func _input(e):
|
||||||
if not editor.is_plugin_active():
|
if not editor.is_plugin_active():
|
||||||
return
|
return
|
||||||
|
@ -1,21 +1,16 @@
|
|||||||
tool
|
tool
|
||||||
extends RichTextLabel
|
extends "res://addons/text_editor/TE_RichTextLabel.gd"
|
||||||
|
|
||||||
onready var editor:TextEditor = owner
|
|
||||||
onready var file_popup:PopupMenu = $file_popup
|
onready var file_popup:PopupMenu = $file_popup
|
||||||
onready var dir_popup:PopupMenu = $dir_popup
|
onready var dir_popup:PopupMenu = $dir_popup
|
||||||
|
|
||||||
const DragLabel = preload("res://addons/text_editor/TE_DragLabel.gd")
|
const DragLabel = preload("res://addons/text_editor/TE_DragLabel.gd")
|
||||||
var drag_label:RichTextLabel
|
var drag_label:RichTextLabel
|
||||||
|
|
||||||
var files:Array = []
|
var selected:Array = []
|
||||||
var dirs:Array = []
|
var dragging:Array = []
|
||||||
var selected
|
|
||||||
var hovered:String = ""
|
|
||||||
var dragging:String = ""
|
|
||||||
var drag_start:Vector2
|
var drag_start:Vector2
|
||||||
|
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
var _e
|
var _e
|
||||||
_e = editor.connect("updated_file_list", self, "_redraw")
|
_e = editor.connect("updated_file_list", self, "_redraw")
|
||||||
@ -24,12 +19,6 @@ func _ready():
|
|||||||
_e = editor.connect("file_closed", self, "_file_closed")
|
_e = editor.connect("file_closed", self, "_file_closed")
|
||||||
_e = editor.connect("file_selected", self, "_file_selected")
|
_e = editor.connect("file_selected", self, "_file_selected")
|
||||||
_e = editor.connect("file_renamed", self, "_file_renamed")
|
_e = editor.connect("file_renamed", self, "_file_renamed")
|
||||||
_e = connect("meta_hover_started", self, "_meta_entered")
|
|
||||||
_e = connect("meta_hover_ended", self, "_meta_exited")
|
|
||||||
|
|
||||||
# hint
|
|
||||||
theme = Theme.new()
|
|
||||||
theme.set_font("font", "TooltipLabel", editor.FONT_R)
|
|
||||||
|
|
||||||
# file popup
|
# file popup
|
||||||
file_popup.clear()
|
file_popup.clear()
|
||||||
@ -38,7 +27,7 @@ func _ready():
|
|||||||
file_popup.add_separator()
|
file_popup.add_separator()
|
||||||
file_popup.add_item("Remove")
|
file_popup.add_item("Remove")
|
||||||
_e = file_popup.connect("index_pressed", self, "_file_popup")
|
_e = file_popup.connect("index_pressed", self, "_file_popup")
|
||||||
file_popup.add_font_override("font", TextEditor.FONT)
|
file_popup.add_font_override("font", editor.FONT)
|
||||||
|
|
||||||
# dir popup
|
# dir popup
|
||||||
dir_popup.clear()
|
dir_popup.clear()
|
||||||
@ -48,7 +37,7 @@ func _ready():
|
|||||||
dir_popup.add_separator()
|
dir_popup.add_separator()
|
||||||
dir_popup.add_item("Remove")
|
dir_popup.add_item("Remove")
|
||||||
_e = dir_popup.connect("index_pressed", self, "_dir_popup")
|
_e = dir_popup.connect("index_pressed", self, "_dir_popup")
|
||||||
dir_popup.add_font_override("font", TextEditor.FONT)
|
dir_popup.add_font_override("font", editor.FONT)
|
||||||
|
|
||||||
add_font_override("normal_font", editor.FONT_R)
|
add_font_override("normal_font", editor.FONT_R)
|
||||||
add_font_override("bold_font", editor.FONT_B)
|
add_font_override("bold_font", editor.FONT_B)
|
||||||
@ -56,9 +45,10 @@ func _ready():
|
|||||||
add_font_override("bold_italics_font", editor.FONT_BI)
|
add_font_override("bold_italics_font", editor.FONT_BI)
|
||||||
|
|
||||||
func _dir_popup(index:int):
|
func _dir_popup(index:int):
|
||||||
var p = _meta_to_file(selected)
|
var type = selected[0]
|
||||||
var type = p[0]
|
var file = selected[1]
|
||||||
var file = p[1]
|
if type == "d":
|
||||||
|
file = file.file_path
|
||||||
|
|
||||||
match dir_popup.get_item_text(index):
|
match dir_popup.get_item_text(index):
|
||||||
"New File": editor.popup_create_file(file)
|
"New File": editor.popup_create_file(file)
|
||||||
@ -66,9 +56,10 @@ func _dir_popup(index:int):
|
|||||||
"Remove": editor.recycle(file)
|
"Remove": editor.recycle(file)
|
||||||
|
|
||||||
func _file_popup(index:int):
|
func _file_popup(index:int):
|
||||||
var p = _meta_to_file(selected)
|
var type = selected[0]
|
||||||
var type = p[0]
|
var file = selected[1]
|
||||||
var file = p[1]
|
if type == "d":
|
||||||
|
file = file.file_path
|
||||||
|
|
||||||
match file_popup.get_item_text(index):
|
match file_popup.get_item_text(index):
|
||||||
"Rename":
|
"Rename":
|
||||||
@ -82,62 +73,61 @@ func _file_popup(index:int):
|
|||||||
editor.recycle(file)
|
editor.recycle(file)
|
||||||
|
|
||||||
_:
|
_:
|
||||||
selected = {}
|
selected = []
|
||||||
|
|
||||||
func _renamed(new_file:String):
|
func _renamed(new_file:String):
|
||||||
var p = _meta_to_file(selected)
|
var type = selected[0]
|
||||||
var type = p[0]
|
var file = selected[1]
|
||||||
var file = p[1]
|
|
||||||
|
|
||||||
var old_path:String = file
|
var old_path:String = file
|
||||||
var old_file:String = old_path.get_file()
|
var old_file:String = old_path.get_file()
|
||||||
if new_file != old_file:
|
if new_file != old_file:
|
||||||
var new_path:String = old_path.get_base_dir().plus_file(new_file)
|
var new_path:String = old_path.get_base_dir().plus_file(new_file)
|
||||||
editor.rename_file(old_path, new_path)
|
editor.rename_file(old_path, new_path)
|
||||||
selected = {}
|
selected = []
|
||||||
|
|
||||||
func _input(e:InputEvent):
|
func _input(e:InputEvent):
|
||||||
if not editor.is_plugin_active():
|
if not editor.is_plugin_active():
|
||||||
return
|
return
|
||||||
|
|
||||||
if e is InputEventMouseButton and hovered:
|
if e is InputEventMouseButton and meta_hovered:
|
||||||
var p = _meta_to_file(hovered)
|
var type = meta_hovered[0]
|
||||||
var type = p[0]
|
var file = meta_hovered[1]
|
||||||
var file = p[1]
|
|
||||||
|
|
||||||
if e.button_index == BUTTON_LEFT:
|
if e.button_index == BUTTON_LEFT:
|
||||||
|
|
||||||
if e.pressed:
|
if e.pressed:
|
||||||
if type in ["f", "d"]:
|
if type in ["f", "d"]:
|
||||||
if file.begins_with(editor.PATH_TRASH):
|
var file_path = file if type == "f" else file.file_path
|
||||||
|
|
||||||
|
if file_path.begins_with(editor.PATH_TRASH):
|
||||||
return # can't move recycling
|
return # can't move recycling
|
||||||
|
|
||||||
else:
|
else:
|
||||||
dragging = hovered
|
dragging = meta_hovered
|
||||||
|
|
||||||
drag_label = DragLabel.new(file.get_file())
|
drag_label = DragLabel.new(file_path.get_file())
|
||||||
drag_label.editor = editor
|
drag_label.editor = editor
|
||||||
editor.add_child(drag_label)
|
editor.add_child(drag_label)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if dragging and dragging != hovered:
|
if dragging and dragging != meta_hovered:
|
||||||
var p2 = _meta_to_file(dragging)
|
var drag_type = dragging[0]
|
||||||
var drag_type = p2[0]
|
var drag_file = dragging[1]
|
||||||
var drag_file = p2[1]
|
|
||||||
|
|
||||||
if type == "d":
|
if type == "d":
|
||||||
var dir:String = file
|
var dir:String = file.file_path
|
||||||
var old_path:String = drag_file
|
var old_path:String = drag_file
|
||||||
var new_path:String = dir.plus_file(old_path.get_file())
|
var new_path:String = dir.plus_file(old_path.get_file())
|
||||||
editor.rename_file(old_path, new_path)
|
editor.rename_file(old_path, new_path)
|
||||||
|
|
||||||
dragging = ""
|
dragging = []
|
||||||
|
|
||||||
else:
|
else:
|
||||||
match type:
|
match type:
|
||||||
# toggle directory
|
# toggle directory
|
||||||
"d":
|
"d":
|
||||||
p[2].open = not p[2].open
|
file.open = not file.open
|
||||||
_redraw()
|
_redraw()
|
||||||
|
|
||||||
# unrecycle
|
# unrecycle
|
||||||
@ -152,7 +142,7 @@ func _input(e:InputEvent):
|
|||||||
|
|
||||||
elif e.button_index == BUTTON_RIGHT:
|
elif e.button_index == BUTTON_RIGHT:
|
||||||
if e.pressed:
|
if e.pressed:
|
||||||
selected = hovered
|
selected = meta_hovered
|
||||||
match type:
|
match type:
|
||||||
"d":
|
"d":
|
||||||
dir_popup.set_global_position(get_global_mouse_position())
|
dir_popup.set_global_position(get_global_mouse_position())
|
||||||
@ -163,27 +153,6 @@ func _input(e:InputEvent):
|
|||||||
file_popup.popup()
|
file_popup.popup()
|
||||||
get_tree().set_input_as_handled()
|
get_tree().set_input_as_handled()
|
||||||
|
|
||||||
func _meta_to_file(m:String):
|
|
||||||
var p = m.split(":", true, 1)
|
|
||||||
var type = p[0]
|
|
||||||
var index = int(p[1])
|
|
||||||
match type:
|
|
||||||
"d", "unrecycle":
|
|
||||||
return [type, dirs[index].file_path, dirs[index]]
|
|
||||||
"f":
|
|
||||||
return [type, files[index]]
|
|
||||||
|
|
||||||
func _meta_entered(m):
|
|
||||||
hovered = m
|
|
||||||
var f = _meta_to_file(m)
|
|
||||||
match f[0]:
|
|
||||||
"f", "d": hint_tooltip = f[1]
|
|
||||||
"unrecycle": hint_tooltip = "Unrecycle %s" % f[1]
|
|
||||||
|
|
||||||
func _meta_exited(_m):
|
|
||||||
hovered = ""
|
|
||||||
hint_tooltip = ""
|
|
||||||
|
|
||||||
func _file_opened(_file_path:String): _redraw()
|
func _file_opened(_file_path:String): _redraw()
|
||||||
func _file_closed(_file_path:String): _redraw()
|
func _file_closed(_file_path:String): _redraw()
|
||||||
func _file_selected(_file_path:String): _redraw()
|
func _file_selected(_file_path:String): _redraw()
|
||||||
@ -193,16 +162,9 @@ var lines:PoolStringArray = PoolStringArray()
|
|||||||
|
|
||||||
func _redraw():
|
func _redraw():
|
||||||
lines = PoolStringArray()
|
lines = PoolStringArray()
|
||||||
dirs.clear()
|
|
||||||
files.clear()
|
|
||||||
_draw_dir(editor.file_list[""], 0)
|
_draw_dir(editor.file_list[""], 0)
|
||||||
set_bbcode(lines.join("\n"))
|
set_bbcode(lines.join("\n"))
|
||||||
|
|
||||||
func clr(s:String, c:Color) -> String: return "[color=#%s]%s[/color]" % [c.to_html(), s]
|
|
||||||
func i(s:String) -> String: return "[i]%s[/i]" % s
|
|
||||||
func b(s:String) -> String: return "[b]%s[/b]" % s
|
|
||||||
func url(s:String, url:String) -> String: return "[url=%s]%s[/url]" % [url, s]
|
|
||||||
|
|
||||||
const FOLDER:String = "🗀" # not visible in godot
|
const FOLDER:String = "🗀" # not visible in godot
|
||||||
func _draw_dir(dir:Dictionary, deep:int):
|
func _draw_dir(dir:Dictionary, deep:int):
|
||||||
var is_tagging = editor.is_tagging()
|
var is_tagging = editor.is_tagging()
|
||||||
@ -210,14 +172,13 @@ func _draw_dir(dir:Dictionary, deep:int):
|
|||||||
|
|
||||||
var space = clr("┃ ".repeat(deep), Color.white.darkened(.8))
|
var space = clr("┃ ".repeat(deep), Color.white.darkened(.8))
|
||||||
var file:String = dir.file_path
|
var file:String = dir.file_path
|
||||||
var name:String = b(file.get_file())
|
|
||||||
var head:String = "▼" if dir.open else "▶"
|
var head:String = "▼" if dir.open else "▶"
|
||||||
var dir_index:int = len(dirs)
|
head = clr(space+FOLDER+head, Color.white.darkened(.5))
|
||||||
var link:String = url(space+clr(FOLDER+head, Color.white.darkened(.5))+" "+name, "d:%s" % dir_index)
|
head += " " + b(file.get_file())
|
||||||
|
var link:String = meta(head, ["d", dir], file)
|
||||||
if file.begins_with(editor.PATH_TRASH) and file.count("/") == 3:
|
if file.begins_with(editor.PATH_TRASH) and file.count("/") == 3:
|
||||||
link += " " + url(clr("⬅", Color.yellowgreen), "unrecycle:%s" % dir_index)
|
link += " " + meta(clr("⬅", Color.yellowgreen), ["unrecycle", dir], file)
|
||||||
lines.append(clr(link, Color.white.darkened(dimmest)))
|
lines.append(clr(link, Color.white.darkened(dimmest)))
|
||||||
dirs.append(dir)
|
|
||||||
|
|
||||||
var sel = editor.get_selected_tab()
|
var sel = editor.get_selected_tab()
|
||||||
sel = sel.file_path if sel else ""
|
sel = sel.file_path if sel else ""
|
||||||
@ -266,5 +227,4 @@ func _draw_dir(dir:Dictionary, deep:int):
|
|||||||
file = clr(file, color)
|
file = clr(file, color)
|
||||||
ext = clr("." + ext, Color.white.darkened(.65))
|
ext = clr("." + ext, Color.white.darkened(.65))
|
||||||
var line = space + head + file + ext
|
var line = space + head + file + ext
|
||||||
lines.append(url(line, "f:%s" % len(files)))
|
lines.append(meta(line, ["f", file_path], file_path))
|
||||||
files.append(file_path)
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
tool
|
tool
|
||||||
extends LineEdit
|
extends LineEdit
|
||||||
|
|
||||||
onready var editor:TextEditor = owner
|
onready var editor:TE_TextEditor = owner
|
||||||
var fr:FuncRef
|
var fr:FuncRef
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
@ -9,16 +9,20 @@ func _ready():
|
|||||||
_e = connect("text_entered", self, "_enter")
|
_e = connect("text_entered", self, "_enter")
|
||||||
_e = connect("focus_exited", self, "_lost_focus")
|
_e = connect("focus_exited", self, "_lost_focus")
|
||||||
|
|
||||||
add_font_override("font", TextEditor.FONT_R)
|
add_font_override("font", editor.FONT_R)
|
||||||
|
|
||||||
func _unhandled_key_input(e):
|
func _unhandled_key_input(e):
|
||||||
if e.scancode == KEY_ESCAPE and e.pressed:
|
if not editor.is_plugin_active():
|
||||||
|
return
|
||||||
|
|
||||||
|
if visible and e.scancode == KEY_ESCAPE and e.pressed:
|
||||||
fr = null
|
fr = null
|
||||||
hide()
|
hide()
|
||||||
get_tree().set_input_as_handled()
|
get_tree().set_input_as_handled()
|
||||||
|
|
||||||
func display(t:String, obj:Object, fname:String):
|
func display(t:String, obj:Object, fname:String):
|
||||||
text = t
|
text = t
|
||||||
|
select_all()
|
||||||
fr = funcref(obj, fname)
|
fr = funcref(obj, fname)
|
||||||
show()
|
show()
|
||||||
call_deferred("grab_focus")
|
call_deferred("grab_focus")
|
||||||
@ -28,5 +32,7 @@ func _lost_focus():
|
|||||||
hide()
|
hide()
|
||||||
|
|
||||||
func _enter(t:String):
|
func _enter(t:String):
|
||||||
fr.call_func(t)
|
if fr:
|
||||||
|
print("calling %s with %s" % [fr, t])
|
||||||
|
fr.call_func(t)
|
||||||
hide()
|
hide()
|
||||||
|
@ -1,20 +1,13 @@
|
|||||||
tool
|
tool
|
||||||
extends TE_RichTextLabel
|
extends "res://addons/text_editor/TE_RichTextLabel.gd"
|
||||||
|
|
||||||
onready var editor:TextEditor = owner
|
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
var _e
|
var _e
|
||||||
_e = editor.connect("file_selected", self, "_file_selected")
|
_e = editor.connect("file_selected", self, "_file_selected")
|
||||||
_e = editor.connect("file_saved", self, "_file_saved")
|
_e = editor.connect("file_saved", self, "_file_saved")
|
||||||
_e = connect("resized", self, "_resized")
|
|
||||||
|
|
||||||
func _resized():
|
#func _resized():
|
||||||
add_constant_override("table_hseparation", int(rect_size.x / 6.0))
|
# add_constant_override("table_hseparation", int(rect_size.x / 6.0))
|
||||||
|
|
||||||
func _unhandled_key_input(e):
|
|
||||||
if e.scancode == KEY_M and e.pressed:
|
|
||||||
visible = not visible
|
|
||||||
|
|
||||||
func _file_selected(_file_path:String):
|
func _file_selected(_file_path:String):
|
||||||
yield(get_tree(), "idle_frame")
|
yield(get_tree(), "idle_frame")
|
||||||
|
19
addons/text_editor/TE_MetaTabs.gd
Normal file
19
addons/text_editor/TE_MetaTabs.gd
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
tool
|
||||||
|
extends TabContainer
|
||||||
|
|
||||||
|
onready var editor:TE_TextEditor = owner
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
if not editor.is_plugin_active():
|
||||||
|
return
|
||||||
|
|
||||||
|
add_font_override("font", editor.FONT_R)
|
||||||
|
|
||||||
|
func _unhandled_key_input(e):
|
||||||
|
if not editor.is_plugin_active():
|
||||||
|
return
|
||||||
|
|
||||||
|
# Ctrl + M = meta tabs
|
||||||
|
if e.scancode == KEY_M and e.control and e.pressed:
|
||||||
|
visible = not visible
|
||||||
|
get_tree().set_input_as_handled()
|
@ -1,13 +1,88 @@
|
|||||||
extends RichTextLabel
|
extends RichTextLabel
|
||||||
class_name TE_RichTextLabel
|
|
||||||
|
|
||||||
|
onready var editor:TE_TextEditor = owner
|
||||||
|
|
||||||
|
var meta_items:Array = []
|
||||||
|
var meta_hovered:Array = []
|
||||||
|
|
||||||
|
class Table:
|
||||||
|
var table_id:String
|
||||||
|
var heading:Array = []
|
||||||
|
var columns:Array = []
|
||||||
|
var _sort_index:int
|
||||||
|
var _sort_reverse:bool
|
||||||
|
|
||||||
|
func _init(id:String):
|
||||||
|
table_id = id
|
||||||
|
|
||||||
|
func sort(index:int, reverse:bool):
|
||||||
|
_sort_index = index
|
||||||
|
_sort_reverse = reverse
|
||||||
|
columns.sort_custom(self, "_sort")
|
||||||
|
|
||||||
|
func output(rte:RichTextLabel):
|
||||||
|
rte.push_table(len(heading))
|
||||||
|
for i in len(heading):
|
||||||
|
rte.push_cell()
|
||||||
|
rte.push_bold()
|
||||||
|
rte.push_meta("table|%s|%s" % [table_id, i])
|
||||||
|
rte.add_text(heading[i])
|
||||||
|
rte.pop()
|
||||||
|
rte.pop()
|
||||||
|
rte.pop()
|
||||||
|
for i in len(columns):
|
||||||
|
rte.push_cell()
|
||||||
|
rte.add_text(str(columns[i]))
|
||||||
|
rte.pop()
|
||||||
|
rte.pop()
|
||||||
|
|
||||||
|
class RTE:
|
||||||
|
var rte
|
||||||
|
var s:String
|
||||||
|
|
||||||
|
func start(st:String):
|
||||||
|
s = st
|
||||||
|
return self
|
||||||
|
|
||||||
|
func clr(c:Color):
|
||||||
|
s = "[color=#%s]%s[/color]" % [c.to_html(), s]
|
||||||
|
return self
|
||||||
|
|
||||||
|
func meta(type:String, meta, args=null):
|
||||||
|
var index:int = len(rte.meta_items)
|
||||||
|
rte.meta_items.append(meta)
|
||||||
|
s = "[url=%s|%s]%s[/url]" % [type, index, s]
|
||||||
|
return self
|
||||||
|
|
||||||
|
func out():
|
||||||
|
rte.append_bbcode(s)
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
|
# hint
|
||||||
|
theme = Theme.new()
|
||||||
|
theme.set_font("font", "TooltipLabel", editor.FONT_R)
|
||||||
|
|
||||||
add_font_override("normal_font", owner.FONT_R)
|
add_font_override("normal_font", owner.FONT_R)
|
||||||
add_font_override("bold_font", owner.FONT_B)
|
add_font_override("bold_font", owner.FONT_B)
|
||||||
add_font_override("italics_font", owner.FONT_I)
|
add_font_override("italics_font", owner.FONT_I)
|
||||||
add_font_override("bold_italics_font", owner.FONT_BI)
|
add_font_override("bold_italics_font", owner.FONT_BI)
|
||||||
|
|
||||||
|
var _e
|
||||||
|
_e = connect("resized", self, "_resized")
|
||||||
|
_e = connect("meta_clicked", self, "_meta_clicked")
|
||||||
|
_e = connect("meta_hover_started", self, "_meta_hover_started")
|
||||||
|
_e = connect("meta_hover_ended", self, "_meta_hover_ended")
|
||||||
|
|
||||||
|
func _resized():
|
||||||
|
pass
|
||||||
|
|
||||||
|
func _clicked(_data):
|
||||||
|
pass
|
||||||
|
|
||||||
|
func clear():
|
||||||
|
.clear()
|
||||||
|
meta_items.clear()
|
||||||
|
|
||||||
func table(rows) -> String:
|
func table(rows) -> String:
|
||||||
var cells = ""
|
var cells = ""
|
||||||
var clr = Color.white.darkened(.5).to_html()
|
var clr = Color.white.darkened(.5).to_html()
|
||||||
@ -19,3 +94,33 @@ func table(rows) -> String:
|
|||||||
for item in rows[i]:
|
for item in rows[i]:
|
||||||
cells += "[cell][color=#%s]%s[/color][/cell]" % [clr, item]
|
cells += "[cell][color=#%s]%s[/color][/cell]" % [clr, item]
|
||||||
return "[center][table=%s]%s[/table][/center]" % [len(rows[0]), cells]
|
return "[center][table=%s]%s[/table][/center]" % [len(rows[0]), cells]
|
||||||
|
|
||||||
|
func b(t:String) -> String: return "[b]%s[/b]" % t
|
||||||
|
func i(t:String) -> String: return "[i]%s[/i]" % t
|
||||||
|
func clr(t:String, c:Color) -> String: return "[color=#%s]%s[/color]" % [c.to_html(), t]
|
||||||
|
func center(t:String): return "[center]%s[/center]" % t
|
||||||
|
|
||||||
|
func _meta_hover_started(meta):
|
||||||
|
var info = meta_items[int(meta)]
|
||||||
|
var hint = info[1]
|
||||||
|
meta_hovered = info[0]
|
||||||
|
if hint:
|
||||||
|
hint_tooltip = hint
|
||||||
|
|
||||||
|
func _meta_hover_ended(_meta):
|
||||||
|
meta_hovered = []
|
||||||
|
hint_tooltip = ""
|
||||||
|
|
||||||
|
func _meta_clicked(meta):
|
||||||
|
var info = meta_items[int(meta)]
|
||||||
|
if info[0]:
|
||||||
|
_clicked(info[0])
|
||||||
|
|
||||||
|
func add_meta(args:Array, hint:String) -> int:
|
||||||
|
var index:int = len(meta_items)
|
||||||
|
meta_items.append([args, hint])
|
||||||
|
return index
|
||||||
|
|
||||||
|
func meta(t:String, args:Array=[], hint:String="") -> String:
|
||||||
|
var index:int = add_meta(args, hint)
|
||||||
|
return "[url=%s]%s[/url]" % [index, t]
|
||||||
|
151
addons/text_editor/TE_ScriptInfo.gd
Normal file
151
addons/text_editor/TE_ScriptInfo.gd
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
tool
|
||||||
|
extends "res://addons/text_editor/TE_RichTextLabel.gd"
|
||||||
|
|
||||||
|
var chapter_info:Array = []
|
||||||
|
var sort_on:String = "words"
|
||||||
|
var sort_reverse:Dictionary = { id=false, words=false, unique=false }
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
var _e
|
||||||
|
_e = editor.connect("file_opened", self, "_update")
|
||||||
|
_e = editor.connect("file_saved", self, "_update")
|
||||||
|
|
||||||
|
func _update(f):
|
||||||
|
set_process(true)
|
||||||
|
|
||||||
|
func _process(_delta):
|
||||||
|
chapter_info.clear()
|
||||||
|
|
||||||
|
for path in editor.file_paths:
|
||||||
|
var file = path.get_file()
|
||||||
|
var ext = file.get_extension()
|
||||||
|
match ext:
|
||||||
|
"md": _process_md(path)
|
||||||
|
|
||||||
|
_sort()
|
||||||
|
_redraw()
|
||||||
|
|
||||||
|
set_process(false)
|
||||||
|
|
||||||
|
func _chapter(path:String, line:int, id:String):
|
||||||
|
chapter_info.append({ path=path, line=line, id=id, words=0, chars=0, unique=0 })
|
||||||
|
|
||||||
|
func _process_md(path:String):
|
||||||
|
var lines = TE_Util.load_text(path).split("\n")
|
||||||
|
_chapter(path, 0, "NOH")
|
||||||
|
var i = 0
|
||||||
|
while i < len(lines):
|
||||||
|
# skip head meta
|
||||||
|
if i == 0 and lines[i].begins_with("---"):
|
||||||
|
i += 1
|
||||||
|
while i < len(lines) and not lines[i].begins_with("---"):
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
# skip code blocks
|
||||||
|
elif lines[i].begins_with("~~~") or lines[i].begins_with("```"):
|
||||||
|
var head = lines[i].substr(0, 3)
|
||||||
|
i += 1
|
||||||
|
while i < len(lines) and not lines[i].begins_with(head):
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
# heading
|
||||||
|
elif lines[i].begins_with("#"):
|
||||||
|
var p = lines[i].split(" ", true, 1)
|
||||||
|
var id = lines[i].split(" ", true, 1)[1].strip_edges()
|
||||||
|
_chapter(path, i, id)
|
||||||
|
|
||||||
|
else:
|
||||||
|
var words = lines[i].split(" ", false)
|
||||||
|
var unique = []
|
||||||
|
for word in words:
|
||||||
|
var w = clean_word(word.to_lower())
|
||||||
|
if w and not w in unique:
|
||||||
|
unique.append(w)
|
||||||
|
|
||||||
|
chapter_info[-1].words += len(words)
|
||||||
|
chapter_info[-1].unique += len(unique)
|
||||||
|
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
func clean_word(w:String):
|
||||||
|
var out = ""
|
||||||
|
for c in w:
|
||||||
|
if c in "abcdefghijklmnopqrstuvwxyz":
|
||||||
|
out += c
|
||||||
|
return out
|
||||||
|
|
||||||
|
func _clicked(args):
|
||||||
|
match args[0]:
|
||||||
|
"sort_table":
|
||||||
|
var key = args[1]
|
||||||
|
if sort_on != key:
|
||||||
|
sort_on = key
|
||||||
|
else:
|
||||||
|
sort_reverse[key] = not sort_reverse[key]
|
||||||
|
|
||||||
|
_sort()
|
||||||
|
_redraw()
|
||||||
|
|
||||||
|
"goto":
|
||||||
|
print(args)
|
||||||
|
var tab = editor.open_file(args[1])
|
||||||
|
editor.select_file(args[1])
|
||||||
|
tab.goto_line(args[2])
|
||||||
|
|
||||||
|
func _sort():
|
||||||
|
if sort_reverse[sort_on]:
|
||||||
|
chapter_info.sort_custom(self, "_sort_chapters")
|
||||||
|
else:
|
||||||
|
chapter_info.sort_custom(self, "_sort_chapters_r")
|
||||||
|
|
||||||
|
func _sort_chapters(a, b): return a[sort_on] < b[sort_on]
|
||||||
|
func _sort_chapters_r(a, b): return a[sort_on] >= b[sort_on]
|
||||||
|
|
||||||
|
func _redraw():
|
||||||
|
clear()
|
||||||
|
|
||||||
|
var c1 = Color.white.darkened(.4)
|
||||||
|
var c2 = Color.white.darkened(.3)
|
||||||
|
|
||||||
|
push_align(RichTextLabel.ALIGN_CENTER)
|
||||||
|
push_table(3)
|
||||||
|
for id in ["id", "words", "unique"]:
|
||||||
|
push_cell()
|
||||||
|
push_bold()
|
||||||
|
push_meta(add_meta(["sort_table", id], "sort on %s" % id))
|
||||||
|
add_text(id)
|
||||||
|
if sort_on == id:
|
||||||
|
push_color(Color.white.darkened(.5))
|
||||||
|
add_text(" ⯅" if sort_reverse[id] else " ⯆")
|
||||||
|
pop()
|
||||||
|
pop()
|
||||||
|
pop()
|
||||||
|
pop()
|
||||||
|
|
||||||
|
for i in len(chapter_info):
|
||||||
|
var item = chapter_info[i]
|
||||||
|
|
||||||
|
if item.id == "NOH" and not item.words:
|
||||||
|
continue
|
||||||
|
|
||||||
|
var clr = c1 if i%2==0 else c2
|
||||||
|
|
||||||
|
# id
|
||||||
|
push_cell()
|
||||||
|
push_color(clr)
|
||||||
|
push_meta(add_meta(["goto", item.path, item.line], item.path))
|
||||||
|
add_text(item.id)
|
||||||
|
pop()
|
||||||
|
pop()
|
||||||
|
pop()
|
||||||
|
|
||||||
|
# word cound
|
||||||
|
for w in ["words", "unique"]:
|
||||||
|
push_cell()
|
||||||
|
push_color(clr)
|
||||||
|
add_text(TE_Util.commas(item[w]))
|
||||||
|
pop()
|
||||||
|
pop()
|
||||||
|
|
||||||
|
pop()
|
||||||
|
pop()
|
104
addons/text_editor/TE_Search.gd
Normal file
104
addons/text_editor/TE_Search.gd
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
tool
|
||||||
|
extends "res://addons/text_editor/TE_RichTextLabel.gd"
|
||||||
|
|
||||||
|
onready var line_edit:LineEdit = get_parent().get_node("le")
|
||||||
|
|
||||||
|
var console_urls:Array = []
|
||||||
|
var last_search:String = ""
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
var _e
|
||||||
|
_e = line_edit.connect("text_entered", self, "_text_entered")
|
||||||
|
|
||||||
|
line_edit.add_font_override("font", editor.FONT_R)
|
||||||
|
|
||||||
|
func _unhandled_key_input(e):
|
||||||
|
if not editor.is_plugin_active():
|
||||||
|
return
|
||||||
|
|
||||||
|
# Ctrl + F to search
|
||||||
|
if e.scancode == KEY_F and e.pressed and e.control:
|
||||||
|
line_edit.grab_focus()
|
||||||
|
line_edit.grab_click_focus()
|
||||||
|
get_parent().get_parent().show()
|
||||||
|
get_parent().get_parent().current_tab = get_index()
|
||||||
|
get_tree().set_input_as_handled()
|
||||||
|
|
||||||
|
func _clicked(args):
|
||||||
|
match args[0]:
|
||||||
|
"goto":
|
||||||
|
var tab = editor.open_file(args[1])
|
||||||
|
editor.select_file(args[1])
|
||||||
|
tab.goto_line(int(args[2]))
|
||||||
|
|
||||||
|
func _text_entered(search_for:String):
|
||||||
|
last_search = search_for
|
||||||
|
clear()
|
||||||
|
var found:Dictionary = _search(search_for)
|
||||||
|
var bbcode:PoolStringArray = PoolStringArray()
|
||||||
|
var fpaths = found.keys()
|
||||||
|
|
||||||
|
for k in len(fpaths):
|
||||||
|
if k != 0:
|
||||||
|
bbcode.append("")
|
||||||
|
|
||||||
|
var file_path:String = fpaths[k]
|
||||||
|
var l = clr("%s/%s " % [k+1, len(fpaths)], Color.orange) + clr(file_path.get_file(), Color.yellow)
|
||||||
|
l = meta(l, ["goto", file_path, 0], file_path)
|
||||||
|
bbcode.append(l)
|
||||||
|
|
||||||
|
for j in len(found[file_path]):
|
||||||
|
var result = found[file_path][j]
|
||||||
|
var got_lines = result[0]
|
||||||
|
var line_index = result[1]
|
||||||
|
var char_index = result[2]
|
||||||
|
|
||||||
|
if j != 0:
|
||||||
|
bbcode.append("\t" + clr("...", Color.gray))
|
||||||
|
|
||||||
|
for i in len(got_lines):
|
||||||
|
l = ""
|
||||||
|
|
||||||
|
if i == 2:
|
||||||
|
var line:String = got_lines[i]
|
||||||
|
var head:String = line.substr(0, char_index)
|
||||||
|
var midd:String = line.substr(char_index, len(search_for)+1)
|
||||||
|
var tail:String = line.substr(char_index+len(search_for)+1)
|
||||||
|
head = clr(head, Color.tomato.lightened(.5))
|
||||||
|
midd = clr(midd, Color.tomato.darkened(.25))
|
||||||
|
tail = clr(tail, Color.tomato.lightened(.5))
|
||||||
|
l = "\t" + clr(str(line_index-2+i+1) + ": ", Color.tomato.lightened(.5)) + (head+midd+tail)
|
||||||
|
|
||||||
|
elif line_index-2+i >= 0:
|
||||||
|
l = "\t" + clr(str(line_index-2+i+1) + ": ", Color.gray) + got_lines[i]
|
||||||
|
|
||||||
|
if l:
|
||||||
|
l = meta(l, ["goto", file_path, line_index])
|
||||||
|
bbcode.append(l)
|
||||||
|
|
||||||
|
set_bbcode(bbcode.join("\n"))
|
||||||
|
|
||||||
|
# get a list of files containging lines
|
||||||
|
func _search(search_for:String) -> Dictionary:
|
||||||
|
var found = {}
|
||||||
|
var search_for_l = search_for.to_lower() # lowercase. TODO: match case
|
||||||
|
for path in editor.file_paths:
|
||||||
|
var lines = TE_Util.load_text(path).split("\n")
|
||||||
|
for line_index in len(lines):
|
||||||
|
var line:String = lines[line_index].to_lower()
|
||||||
|
# find index where result is found
|
||||||
|
var char_index:int = line.find(search_for_l)
|
||||||
|
if char_index != -1:
|
||||||
|
if not path in found:
|
||||||
|
found[path] = []
|
||||||
|
var preview_lines = PoolStringArray()
|
||||||
|
var highlight_from:int = line_index
|
||||||
|
# show surrounding 5 lines.
|
||||||
|
for i in range(-2, 3):
|
||||||
|
if line_index+i >= 0 and line_index+i < len(lines):
|
||||||
|
preview_lines.append(lines[line_index+i])
|
||||||
|
else:
|
||||||
|
preview_lines.append("")
|
||||||
|
# lines, index in file, index in line
|
||||||
|
found[path].append([preview_lines, line_index, char_index])
|
||||||
|
return found
|
@ -1,12 +1,8 @@
|
|||||||
tool
|
tool
|
||||||
extends RichTextLabel
|
extends "res://addons/text_editor/TE_RichTextLabel.gd"
|
||||||
|
|
||||||
onready var editor:TextEditor = owner
|
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
var _e
|
var _e
|
||||||
_e = connect("meta_hover_started", self, "_hovered")
|
|
||||||
_e = connect("meta_clicked", self, "_clicked")
|
|
||||||
_e = editor.connect("symbols_updated", self, "_redraw")
|
_e = editor.connect("symbols_updated", self, "_redraw")
|
||||||
_e = editor.connect("tags_updated", self, "_redraw")
|
_e = editor.connect("tags_updated", self, "_redraw")
|
||||||
|
|
||||||
@ -17,21 +13,23 @@ func _ready():
|
|||||||
|
|
||||||
call_deferred("_redraw")
|
call_deferred("_redraw")
|
||||||
|
|
||||||
func _hovered(_id):
|
func _clicked(args:Array):
|
||||||
pass
|
var te:TextEdit = editor.get_selected_tab()
|
||||||
|
te.goto_line(args[1])
|
||||||
func _clicked(id):
|
|
||||||
var p = id.split(":", true, 1)
|
|
||||||
var i = int(p[1])
|
|
||||||
match p[0]:
|
|
||||||
"l":
|
|
||||||
var te:TextEdit = editor.get_selected_tab()
|
|
||||||
te.cursor_set_line(te.get_line_count()) # force scroll to bottom so selected line will be at top
|
|
||||||
te.cursor_set_line(i)
|
|
||||||
|
|
||||||
func _redraw():
|
func _redraw():
|
||||||
var tab = editor.get_selected_tab()
|
var tab = editor.get_selected_tab()
|
||||||
var symbols = {} if not tab else tab.symbols
|
var symbols = {} if not tab else tab.symbols
|
||||||
|
var spaces = PoolStringArray([
|
||||||
|
"- ",
|
||||||
|
" - ",
|
||||||
|
" - "
|
||||||
|
])
|
||||||
|
var colors = PoolColorArray([
|
||||||
|
Color.white,
|
||||||
|
Color.white.darkened(.25),
|
||||||
|
Color.white.darkened(.5)
|
||||||
|
])
|
||||||
|
|
||||||
# no symbols
|
# no symbols
|
||||||
if not symbols or len(symbols) == 1:
|
if not symbols or len(symbols) == 1:
|
||||||
@ -44,9 +42,17 @@ func _redraw():
|
|||||||
if line_index == -1:
|
if line_index == -1:
|
||||||
continue # special file chapter
|
continue # special file chapter
|
||||||
var symbol_info = symbols[line_index]
|
var symbol_info = symbols[line_index]
|
||||||
var space = "" if not symbol_info.deep else " ".repeat(symbol_info.deep)
|
var deep = symbol_info.deep
|
||||||
var tagged = editor.is_tagged_or_visible(symbol_info.tags)
|
var space = "" if not deep else clr("-".repeat(deep), Color.white.darkened(.75))
|
||||||
var clr = Color.white.darkened(0.0 if tagged else 0.75).to_html()
|
var cl = Color.deepskyblue if deep == 0 else Color.white
|
||||||
t.append(space + "[color=#%s][url=l:%s]%s[/url][/color]" % [clr, line_index, symbol_info.name])
|
|
||||||
|
if not editor.is_tagged_or_visible(symbol_info.tags):
|
||||||
|
cl = cl.darkened(.7)
|
||||||
|
|
||||||
|
elif deep >= 1:
|
||||||
|
cl = cl.darkened(.33 * (deep-1))
|
||||||
|
|
||||||
|
var tags = "" if not symbol_info.tags else PoolStringArray(symbol_info.tags).join(", ")
|
||||||
|
t.append(clr(meta(space + symbol_info.name, [symbol_info, line_index], tags), cl))
|
||||||
|
|
||||||
set_bbcode(t.join("\n"))
|
set_bbcode(t.join("\n"))
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
tool
|
tool
|
||||||
extends TabContainer
|
extends TabContainer
|
||||||
|
|
||||||
onready var editor:TextEditor = owner
|
onready var editor:TE_TextEditor = owner
|
||||||
|
|
||||||
var mouse_over:bool = false
|
var mouse_over:bool = false
|
||||||
|
|
||||||
|
@ -1,15 +1,8 @@
|
|||||||
tool
|
tool
|
||||||
extends RichTextLabel
|
extends "res://addons/text_editor/TE_RichTextLabel.gd"
|
||||||
|
|
||||||
onready var editor:TextEditor = owner
|
|
||||||
|
|
||||||
var tag_indices:Array = [] # safer to use int in [url=] than str.
|
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
var _e
|
var _e
|
||||||
_e = connect("meta_hover_started", self, "_hovered")
|
|
||||||
_e = connect("meta_hover_ended", self, "_unhover")
|
|
||||||
_e = connect("meta_clicked", self, "_clicked")
|
|
||||||
_e = editor.connect("symbols_updated", self, "_redraw")
|
_e = editor.connect("symbols_updated", self, "_redraw")
|
||||||
_e = editor.connect("tags_updated", self, "_redraw")
|
_e = editor.connect("tags_updated", self, "_redraw")
|
||||||
|
|
||||||
@ -23,17 +16,17 @@ func _ready():
|
|||||||
theme.set_font("font", "TooltipLabel", editor.FONT_R)
|
theme.set_font("font", "TooltipLabel", editor.FONT_R)
|
||||||
|
|
||||||
call_deferred("_redraw")
|
call_deferred("_redraw")
|
||||||
|
#
|
||||||
|
#func _hovered(index):
|
||||||
|
# var tag = tag_indices[int(index)]
|
||||||
|
# var count = editor.tag_counts[tag]
|
||||||
|
# hint_tooltip =
|
||||||
|
|
||||||
func _hovered(index):
|
#func _unhover(t):
|
||||||
var tag = tag_indices[int(index)]
|
# hint_tooltip = ""
|
||||||
var count = editor.tag_counts[tag]
|
|
||||||
hint_tooltip = "%s x%s" % [tag, count]
|
|
||||||
|
|
||||||
func _unhover(t):
|
func _clicked(args:Array):
|
||||||
hint_tooltip = ""
|
var tag = args[0]
|
||||||
|
|
||||||
func _clicked(id):
|
|
||||||
var tag = tag_indices[int(id)]
|
|
||||||
editor.enable_tag(tag, not editor.is_tag_enabled(tag))
|
editor.enable_tag(tag, not editor.is_tag_enabled(tag))
|
||||||
|
|
||||||
func sort_tags(tags:Dictionary):
|
func sort_tags(tags:Dictionary):
|
||||||
@ -70,26 +63,19 @@ func _redraw():
|
|||||||
var enabled = editor.is_tag_enabled(tag)
|
var enabled = editor.is_tag_enabled(tag)
|
||||||
|
|
||||||
var x = tag
|
var x = tag
|
||||||
# if count > 1:
|
|
||||||
# x = "[color=#%s][i]%s[/i][/color]%s" % [count_color1 if enabled else count_color2, count, tag]
|
|
||||||
# else:
|
|
||||||
# x = tag
|
|
||||||
|
|
||||||
var color = editor.color_text
|
var color = editor.color_text
|
||||||
var dim = 0.75
|
var dim = 0.75
|
||||||
|
|
||||||
if tag in tab_tags:
|
if tag in tab_tags:
|
||||||
color = editor.color_symbol
|
color = editor.color_tag
|
||||||
x = "[b]%s[/b]" % x
|
x = b(x)
|
||||||
dim = 0.6
|
dim = 0.6
|
||||||
|
|
||||||
if enabled:
|
if enabled:
|
||||||
x = x
|
x = x
|
||||||
else:
|
else:
|
||||||
x = "[color=#%s]%s[/color]" % [color.darkened(dim).to_html(), x]
|
x = clr(x, color.darkened(dim))
|
||||||
|
|
||||||
x = "[url=%s]%s[/url]" % [len(tag_indices), x]
|
t.append(meta(x, [tag], "%s x%s" % [tag, count] ))
|
||||||
t.append(x)
|
|
||||||
tag_indices.append(tag)
|
|
||||||
|
|
||||||
set_bbcode("[center]" + t.join(" "))
|
set_bbcode("[center]" + t.join(" "))
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
tool
|
tool
|
||||||
extends Control
|
extends Control
|
||||||
class_name TextEditor
|
class_name TE_TextEditor
|
||||||
|
|
||||||
const FONT:DynamicFont = preload("res://addons/text_editor/fonts/font.tres")
|
const FONT:DynamicFont = preload("res://addons/text_editor/fonts/font.tres")
|
||||||
|
|
||||||
@ -62,11 +62,12 @@ var show:Dictionary = {
|
|||||||
var color_text:Color = Color.white
|
var color_text:Color = Color.white
|
||||||
var color_comment:Color = Color.white.darkened(.6)
|
var color_comment:Color = Color.white.darkened(.6)
|
||||||
var color_symbol:Color = Color.deepskyblue
|
var color_symbol:Color = Color.deepskyblue
|
||||||
|
var color_tag:Color = Color.yellow
|
||||||
var color_var:Color = Color.orange
|
var color_var:Color = Color.orange
|
||||||
var color_varname:Color = Color.white.darkened(.25)
|
var color_varname:Color = Color.white.darkened(.25)
|
||||||
|
|
||||||
onready var test_button:Node = $c/c/c/test
|
onready var test_button:Node = $c/c/c/test
|
||||||
onready var tab_parent:TabContainer = $c/div1/div2/c/tab_container
|
onready var tab_parent:TabContainer = $c/div1/div2/c/c/tab_container
|
||||||
onready var tab_prefab:Node = $file_editor
|
onready var tab_prefab:Node = $file_editor
|
||||||
onready var popup:ConfirmationDialog = $popup
|
onready var popup:ConfirmationDialog = $popup
|
||||||
onready var popup_unsaved:ConfirmationDialog = $popup_unsaved
|
onready var popup_unsaved:ConfirmationDialog = $popup_unsaved
|
||||||
@ -74,6 +75,7 @@ onready var file_dialog:FileDialog = $file_dialog
|
|||||||
onready var line_edit:LineEdit = $c/div1/div2/c/line_edit
|
onready var line_edit:LineEdit = $c/div1/div2/c/line_edit
|
||||||
onready var menu_file:MenuButton = $c/c/c/file_button
|
onready var menu_file:MenuButton = $c/c/c/file_button
|
||||||
onready var menu_view:MenuButton = $c/c/c/view_button
|
onready var menu_view:MenuButton = $c/c/c/view_button
|
||||||
|
onready var console:RichTextLabel = $c/div1/div2/c/c/meta_tabs/console
|
||||||
var popup_file:PopupMenu
|
var popup_file:PopupMenu
|
||||||
var popup_view:PopupMenu
|
var popup_view:PopupMenu
|
||||||
var popup_view_dir:PopupMenu = PopupMenu.new()
|
var popup_view_dir:PopupMenu = PopupMenu.new()
|
||||||
@ -81,6 +83,9 @@ var popup_view_file:PopupMenu = PopupMenu.new()
|
|||||||
|
|
||||||
var current_directory:String = "res://"
|
var current_directory:String = "res://"
|
||||||
var file_list:Dictionary = {}
|
var file_list:Dictionary = {}
|
||||||
|
var dir_paths:Array = []
|
||||||
|
var file_paths:Array = []
|
||||||
|
|
||||||
var symbols:Dictionary = {}
|
var symbols:Dictionary = {}
|
||||||
var tags:Array = []
|
var tags:Array = []
|
||||||
var tags_enabled:Dictionary = {}
|
var tags_enabled:Dictionary = {}
|
||||||
@ -91,9 +96,15 @@ var opened:Array = []
|
|||||||
var closed:Array = []
|
var closed:Array = []
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
|
console.info("active: %s" % is_plugin_active())
|
||||||
|
|
||||||
if not is_plugin_active():
|
if not is_plugin_active():
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if OS.has_feature("standalone"):
|
||||||
|
current_directory = OS.get_executable_path().get_base_dir()
|
||||||
|
|
||||||
|
console.info("current dir: %s" % current_directory)
|
||||||
# not needed when editor plugin
|
# not needed when editor plugin
|
||||||
# get_tree().set_auto_accept_quit(false)
|
# get_tree().set_auto_accept_quit(false)
|
||||||
|
|
||||||
@ -177,9 +188,6 @@ func _ready():
|
|||||||
# tab control
|
# tab control
|
||||||
_e = tab_parent.connect("tab_changed", self, "_tab_changed")
|
_e = tab_parent.connect("tab_changed", self, "_tab_changed")
|
||||||
|
|
||||||
#
|
|
||||||
tab_parent.add_font_override("font", FONT_R)
|
|
||||||
|
|
||||||
load_state()
|
load_state()
|
||||||
update_checks()
|
update_checks()
|
||||||
set_directory()
|
set_directory()
|
||||||
@ -200,18 +208,14 @@ func update_checks():
|
|||||||
#
|
#
|
||||||
for i in len(MAIN_EXTENSIONS):
|
for i in len(MAIN_EXTENSIONS):
|
||||||
var ext = MAIN_EXTENSIONS[i]
|
var ext = MAIN_EXTENSIONS[i]
|
||||||
# popup_view_file.set_item_checked(i+2, exts_enabled)
|
|
||||||
#
|
#
|
||||||
for i in len(INTERNAL_EXTENSIONS):
|
for i in len(INTERNAL_EXTENSIONS):
|
||||||
var ext = INTERNAL_EXTENSIONS[i]
|
var ext = INTERNAL_EXTENSIONS[i]
|
||||||
var id = i+len(MAIN_EXTENSIONS)+3
|
var id = i+len(MAIN_EXTENSIONS)+3
|
||||||
# popup_view_file.set_item_checked(id, false)
|
|
||||||
# TODOOO
|
|
||||||
|
|
||||||
func save_state():
|
func save_state():
|
||||||
var state:Dictionary = {
|
var state:Dictionary = {
|
||||||
"save_version": "1",
|
"save_version": "1",
|
||||||
"current_directory": current_directory,
|
|
||||||
"font_size": FONT.size,
|
"font_size": FONT.size,
|
||||||
"tabs": {},
|
"tabs": {},
|
||||||
"selected": get_selected_file(),
|
"selected": get_selected_file(),
|
||||||
@ -244,8 +248,6 @@ func load_state():
|
|||||||
if file_path == state.selected:
|
if file_path == state.selected:
|
||||||
selected = tab
|
selected = tab
|
||||||
|
|
||||||
current_directory = state.get("current_directory", current_directory)
|
|
||||||
|
|
||||||
_load_property(state, "show", true)
|
_load_property(state, "show", true)
|
||||||
|
|
||||||
update_checks()
|
update_checks()
|
||||||
@ -260,6 +262,11 @@ func load_state():
|
|||||||
|
|
||||||
emit_signal("state_loaded")
|
emit_signal("state_loaded")
|
||||||
|
|
||||||
|
yield(get_tree(), "idle_frame")
|
||||||
|
if selected:
|
||||||
|
emit_signal("file_selected", selected.file_path)
|
||||||
|
|
||||||
|
|
||||||
func _load_property(state:Dictionary, property:String, merge:bool=false):
|
func _load_property(state:Dictionary, property:String, merge:bool=false):
|
||||||
if property in state and typeof(state[property]) == typeof(self[property]):
|
if property in state and typeof(state[property]) == typeof(self[property]):
|
||||||
if merge:
|
if merge:
|
||||||
@ -403,7 +410,7 @@ func is_tagged(file_path:String) -> bool:
|
|||||||
func is_tagging() -> bool:
|
func is_tagging() -> bool:
|
||||||
return len(tags) > 0
|
return len(tags) > 0
|
||||||
|
|
||||||
func popup_create_file(dir:String="res://"):
|
func popup_create_file(dir:String=current_directory):
|
||||||
file_dialog.mode = FileDialog.MODE_SAVE_FILE
|
file_dialog.mode = FileDialog.MODE_SAVE_FILE
|
||||||
file_dialog.current_dir = dir
|
file_dialog.current_dir = dir
|
||||||
file_dialog.window_title = "Create File"
|
file_dialog.window_title = "Create File"
|
||||||
@ -412,7 +419,7 @@ func popup_create_file(dir:String="res://"):
|
|||||||
file_dialog.set_meta("mode", "create_file")
|
file_dialog.set_meta("mode", "create_file")
|
||||||
file_dialog.show()
|
file_dialog.show()
|
||||||
|
|
||||||
func popup_create_dir(dir:String="res://"):
|
func popup_create_dir(dir:String=current_directory):
|
||||||
file_dialog.mode = FileDialog.MODE_OPEN_DIR
|
file_dialog.mode = FileDialog.MODE_OPEN_DIR
|
||||||
file_dialog.current_dir = dir
|
file_dialog.current_dir = dir
|
||||||
file_dialog.window_title = "Create Folder"
|
file_dialog.window_title = "Create Folder"
|
||||||
@ -429,11 +436,13 @@ func create_file(file_path:String):
|
|||||||
open_file(file_path)
|
open_file(file_path)
|
||||||
select_file(file_path)
|
select_file(file_path)
|
||||||
else:
|
else:
|
||||||
push_error("couldnt create %s" % file_path)
|
var err_msg = "couldnt create %s" % file_path
|
||||||
|
console.err(err_msg)
|
||||||
|
push_error(err_msg)
|
||||||
|
|
||||||
func create_dir(file_path:String):
|
func create_dir(file_path:String):
|
||||||
var d:Directory = Directory.new()
|
var d:Directory = Directory.new()
|
||||||
if file_path and file_path.begins_with("res://") and not d.file_exists(file_path):
|
if file_path and file_path.begins_with(current_directory) and not d.file_exists(file_path):
|
||||||
print("creating folder \"%s\"" % file_path)
|
print("creating folder \"%s\"" % file_path)
|
||||||
d.make_dir(file_path)
|
d.make_dir(file_path)
|
||||||
refresh_files()
|
refresh_files()
|
||||||
@ -509,11 +518,23 @@ func _open_file(file_path:String):
|
|||||||
tab.load_file(file_path)
|
tab.load_file(file_path)
|
||||||
return tab
|
return tab
|
||||||
|
|
||||||
|
func is_allowed_extension(file_path:String) -> bool:
|
||||||
|
var ext = get_extension(file_path)
|
||||||
|
return ext in MAIN_EXTENSIONS
|
||||||
|
|
||||||
func open_file(file_path:String, temporary:bool=false):
|
func open_file(file_path:String, temporary:bool=false):
|
||||||
var tab = get_tab(file_path)
|
var tab = get_tab(file_path)
|
||||||
if tab:
|
if tab:
|
||||||
return tab
|
return tab
|
||||||
|
|
||||||
|
elif not File.new().file_exists(file_path):
|
||||||
|
push_error("no file %s" % file_path)
|
||||||
|
return null
|
||||||
|
|
||||||
|
elif not is_allowed_extension(file_path):
|
||||||
|
push_error("can't open %s" % file_path)
|
||||||
|
return null
|
||||||
|
|
||||||
else:
|
else:
|
||||||
tab = _open_file(file_path)
|
tab = _open_file(file_path)
|
||||||
if temporary:
|
if temporary:
|
||||||
@ -596,6 +617,13 @@ func rename_file(old_path:String, new_path:String):
|
|||||||
push_error("couldn't rename %s to %s." % [old_path, new_path])
|
push_error("couldn't rename %s to %s." % [old_path, new_path])
|
||||||
|
|
||||||
func select_file(file_path:String):
|
func select_file(file_path:String):
|
||||||
|
if not File.new().file_exists(file_path):
|
||||||
|
push_error("no file %s" % file_path)
|
||||||
|
return
|
||||||
|
|
||||||
|
if not is_allowed_extension(file_path):
|
||||||
|
return
|
||||||
|
|
||||||
var temp = get_temporary_tab()
|
var temp = get_temporary_tab()
|
||||||
if temp:
|
if temp:
|
||||||
if temp.file_path == file_path:
|
if temp.file_path == file_path:
|
||||||
@ -611,8 +639,10 @@ func select_file(file_path:String):
|
|||||||
_selected_file_changed(file_path)
|
_selected_file_changed(file_path)
|
||||||
|
|
||||||
func set_directory(path:String=current_directory):
|
func set_directory(path:String=current_directory):
|
||||||
var gpath = ProjectSettings.globalize_path(path)
|
# var gpath = ProjectSettings.globalize_path(path)
|
||||||
var dname = gpath.get_file()
|
# var dname = gpath.get_file()
|
||||||
|
console.msg("Set " + path)
|
||||||
|
|
||||||
current_directory = path
|
current_directory = path
|
||||||
file_dialog.current_dir = path
|
file_dialog.current_dir = path
|
||||||
refresh_files()
|
refresh_files()
|
||||||
@ -640,12 +670,17 @@ func get_all_tabs() -> Array:
|
|||||||
func refresh_files():
|
func refresh_files():
|
||||||
var old_file_list = file_list.duplicate(true)
|
var old_file_list = file_list.duplicate(true)
|
||||||
file_list.clear()
|
file_list.clear()
|
||||||
|
dir_paths.clear()
|
||||||
|
file_paths.clear()
|
||||||
var dir = Directory.new()
|
var dir = Directory.new()
|
||||||
if dir.open(current_directory) == OK:
|
var err = dir.open(current_directory)
|
||||||
|
if err == OK:
|
||||||
_scan_dir("", current_directory, dir, file_list, old_file_list.get("", {}))
|
_scan_dir("", current_directory, dir, file_list, old_file_list.get("", {}))
|
||||||
emit_signal("updated_file_list")
|
emit_signal("updated_file_list")
|
||||||
else:
|
else:
|
||||||
push_error("error trying to load %s." % current_directory)
|
var err_msg = "error trying to load %s: %s" % [current_directory, err]
|
||||||
|
push_error(err_msg)
|
||||||
|
console.err(err_msg)
|
||||||
|
|
||||||
func show_dir(fname:String, base_dir:String) -> bool:
|
func show_dir(fname:String, base_dir:String) -> bool:
|
||||||
if not show.dir.gdignore and File.new().file_exists(base_dir.plus_file(".gdignore")):
|
if not show.dir.gdignore and File.new().file_exists(base_dir.plus_file(".gdignore")):
|
||||||
@ -686,6 +721,7 @@ func _scan_dir(id:String, path:String, dir:Directory, last_dir:Dictionary, old_l
|
|||||||
|
|
||||||
while fname:
|
while fname:
|
||||||
var file_path = dir.get_current_dir().plus_file(fname)
|
var file_path = dir.get_current_dir().plus_file(fname)
|
||||||
|
console.msg(file_path)
|
||||||
|
|
||||||
if dir.current_is_dir():
|
if dir.current_is_dir():
|
||||||
if show_dir(fname, file_path):
|
if show_dir(fname, file_path):
|
||||||
@ -704,8 +740,10 @@ func _scan_dir(id:String, path:String, dir:Directory, last_dir:Dictionary, old_l
|
|||||||
for p in a_dirs_and_files:
|
for p in a_dirs_and_files:
|
||||||
if a_dirs_and_files[p] is Dictionary:
|
if a_dirs_and_files[p] is Dictionary:
|
||||||
a_dirs.append(p)
|
a_dirs.append(p)
|
||||||
|
dir_paths.append(a_dirs_and_files[p].file_path)
|
||||||
else:
|
else:
|
||||||
a_files.append(a_dirs_and_files[p])
|
a_files.append(a_dirs_and_files[p])
|
||||||
|
file_paths.append(a_dirs_and_files[p])
|
||||||
|
|
||||||
sort_on_ext(a_dirs)
|
sort_on_ext(a_dirs)
|
||||||
sort_on_ext(a_files)
|
sort_on_ext(a_files)
|
||||||
@ -737,9 +775,12 @@ static func get_extension(file_path:String) -> String:
|
|||||||
return file.split(".", true, 1)[1]
|
return file.split(".", true, 1)[1]
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
static func get_extension_helper(file_path:String) -> TE_ExtensionHelper:
|
func get_extension_helper(file_path:String) -> TE_ExtensionHelper:
|
||||||
var ext:String = get_extension(file_path).replace(".", "_")
|
var ext:String = get_extension(file_path).replace(".", "_")
|
||||||
var ext_path:String = "res://addons/text_editor/ext/ext_%s.gd" % ext
|
var ext_path:String = "res://addons/text_editor/ext/ext_%s.gd" % ext
|
||||||
if File.new().file_exists(ext_path):
|
var script = load(ext_path)
|
||||||
return load(ext_path).new()
|
if script:
|
||||||
|
return script.new()
|
||||||
|
|
||||||
|
console.err("no helper %s" % ext_path)
|
||||||
return load("res://addons/text_editor/ext/TE_ExtensionHelper.gd").new()
|
return load("res://addons/text_editor/ext/TE_ExtensionHelper.gd").new()
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
[gd_scene load_steps=16 format=2]
|
[gd_scene load_steps=24 format=2]
|
||||||
|
|
||||||
|
[ext_resource path="res://addons/text_editor/TE_Console.gd" type="Script" id=1]
|
||||||
[ext_resource path="res://addons/text_editor/TE_TextEditor.gd" type="Script" id=2]
|
[ext_resource path="res://addons/text_editor/TE_TextEditor.gd" type="Script" id=2]
|
||||||
[ext_resource path="res://addons/text_editor/TE_FilesList.gd" type="Script" id=3]
|
[ext_resource path="res://addons/text_editor/TE_FilesList.gd" type="Script" id=3]
|
||||||
[ext_resource path="res://addons/text_editor/TE_FileEditor.gd" type="Script" id=4]
|
[ext_resource path="res://addons/text_editor/TE_FileEditor.gd" type="Script" id=4]
|
||||||
@ -13,6 +14,9 @@
|
|||||||
[ext_resource path="res://addons/text_editor/fonts/font_r.tres" type="DynamicFont" id=12]
|
[ext_resource path="res://addons/text_editor/fonts/font_r.tres" type="DynamicFont" id=12]
|
||||||
[ext_resource path="res://addons/text_editor/fonts/font_bi.tres" type="DynamicFont" id=13]
|
[ext_resource path="res://addons/text_editor/fonts/font_bi.tres" type="DynamicFont" id=13]
|
||||||
[ext_resource path="res://addons/text_editor/fonts/font.tres" type="DynamicFont" id=14]
|
[ext_resource path="res://addons/text_editor/fonts/font.tres" type="DynamicFont" id=14]
|
||||||
|
[ext_resource path="res://addons/text_editor/TE_Search.gd" type="Script" id=15]
|
||||||
|
[ext_resource path="res://addons/text_editor/TE_MetaTabs.gd" type="Script" id=16]
|
||||||
|
[ext_resource path="res://addons/text_editor/TE_ScriptInfo.gd" type="Script" id=17]
|
||||||
|
|
||||||
[sub_resource type="Theme" id=1]
|
[sub_resource type="Theme" id=1]
|
||||||
TooltipLabel/fonts/font = ExtResource( 12 )
|
TooltipLabel/fonts/font = ExtResource( 12 )
|
||||||
@ -20,6 +24,18 @@ TooltipLabel/fonts/font = ExtResource( 12 )
|
|||||||
[sub_resource type="Theme" id=2]
|
[sub_resource type="Theme" id=2]
|
||||||
TooltipLabel/fonts/font = ExtResource( 12 )
|
TooltipLabel/fonts/font = ExtResource( 12 )
|
||||||
|
|
||||||
|
[sub_resource type="Theme" id=3]
|
||||||
|
TooltipLabel/fonts/font = ExtResource( 12 )
|
||||||
|
|
||||||
|
[sub_resource type="Theme" id=4]
|
||||||
|
TooltipLabel/fonts/font = ExtResource( 12 )
|
||||||
|
|
||||||
|
[sub_resource type="Theme" id=5]
|
||||||
|
TooltipLabel/fonts/font = ExtResource( 12 )
|
||||||
|
|
||||||
|
[sub_resource type="Theme" id=6]
|
||||||
|
TooltipLabel/fonts/font = ExtResource( 12 )
|
||||||
|
|
||||||
[node name="text_editor" type="Control"]
|
[node name="text_editor" type="Control"]
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
@ -146,7 +162,7 @@ items = [ "Rename", null, 0, false, false, 0, 0, null, "", false, "", null, 0, f
|
|||||||
margin_right = 20.0
|
margin_right = 20.0
|
||||||
margin_bottom = 20.0
|
margin_bottom = 20.0
|
||||||
custom_fonts/font = ExtResource( 14 )
|
custom_fonts/font = ExtResource( 14 )
|
||||||
items = [ "New File", null, 0, false, false, 0, 0, null, "", false, "New Folder", null, 0, false, false, 1, 0, null, "", false ]
|
items = [ "New File", null, 0, false, false, 0, 0, null, "", false, "New Folder", null, 0, false, false, 1, 0, null, "", false, "", null, 0, false, false, -1, 0, null, "", true, "Remove", null, 0, false, false, 3, 0, null, "", false ]
|
||||||
|
|
||||||
[node name="div2" type="HSplitContainer" parent="c/div1"]
|
[node name="div2" type="HSplitContainer" parent="c/div1"]
|
||||||
margin_left = 218.0
|
margin_left = 218.0
|
||||||
@ -168,13 +184,20 @@ size_flags_vertical = 3
|
|||||||
[node name="line_edit" type="LineEdit" parent="c/div1/div2/c"]
|
[node name="line_edit" type="LineEdit" parent="c/div1/div2/c"]
|
||||||
visible = false
|
visible = false
|
||||||
margin_right = 614.0
|
margin_right = 614.0
|
||||||
margin_bottom = 24.0
|
margin_bottom = 32.0
|
||||||
custom_fonts/font = ExtResource( 12 )
|
custom_fonts/font = ExtResource( 12 )
|
||||||
script = ExtResource( 8 )
|
script = ExtResource( 8 )
|
||||||
|
|
||||||
[node name="tab_container" type="TabContainer" parent="c/div1/div2/c"]
|
[node name="c" type="VSplitContainer" parent="c/div1/div2/c"]
|
||||||
margin_right = 614.0
|
margin_right = 614.0
|
||||||
margin_bottom = 539.0
|
margin_bottom = 566.0
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 3
|
||||||
|
split_offset = -200
|
||||||
|
|
||||||
|
[node name="tab_container" type="TabContainer" parent="c/div1/div2/c/c"]
|
||||||
|
margin_right = 614.0
|
||||||
|
margin_bottom = 566.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
custom_fonts/font = ExtResource( 12 )
|
custom_fonts/font = ExtResource( 12 )
|
||||||
@ -185,18 +208,98 @@ __meta__ = {
|
|||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="meta" type="RichTextLabel" parent="c/div1/div2/c"]
|
[node name="meta_tabs" type="TabContainer" parent="c/div1/div2/c/c"]
|
||||||
margin_top = 543.0
|
visible = false
|
||||||
|
margin_top = 288.0
|
||||||
margin_right = 614.0
|
margin_right = 614.0
|
||||||
margin_bottom = 566.0
|
margin_bottom = 566.0
|
||||||
|
script = ExtResource( 16 )
|
||||||
|
|
||||||
|
[node name="console" type="RichTextLabel" parent="c/div1/div2/c/c/meta_tabs"]
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
margin_left = 4.0
|
||||||
|
margin_top = 32.0
|
||||||
|
margin_right = -4.0
|
||||||
|
margin_bottom = -4.0
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 3
|
||||||
|
bbcode_enabled = true
|
||||||
|
meta_underlined = false
|
||||||
|
script = ExtResource( 1 )
|
||||||
|
|
||||||
|
[node name="search" type="VBoxContainer" parent="c/div1/div2/c/c/meta_tabs"]
|
||||||
|
visible = false
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
margin_left = 4.0
|
||||||
|
margin_top = 32.0
|
||||||
|
margin_right = -4.0
|
||||||
|
margin_bottom = -4.0
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 3
|
||||||
|
|
||||||
|
[node name="le" type="LineEdit" parent="c/div1/div2/c/c/meta_tabs/search"]
|
||||||
|
margin_right = 58.0
|
||||||
|
margin_bottom = 24.0
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
custom_fonts/font = ExtResource( 12 )
|
||||||
|
|
||||||
|
[node name="rte" type="RichTextLabel" parent="c/div1/div2/c/c/meta_tabs/search"]
|
||||||
|
margin_top = 28.0
|
||||||
|
margin_right = 58.0
|
||||||
|
margin_bottom = 28.0
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 3
|
||||||
|
theme = SubResource( 2 )
|
||||||
|
custom_fonts/bold_italics_font = ExtResource( 13 )
|
||||||
|
custom_fonts/italics_font = ExtResource( 10 )
|
||||||
|
custom_fonts/bold_font = ExtResource( 11 )
|
||||||
|
custom_fonts/normal_font = ExtResource( 12 )
|
||||||
|
bbcode_enabled = true
|
||||||
|
meta_underlined = false
|
||||||
|
script = ExtResource( 15 )
|
||||||
|
|
||||||
|
[node name="meta" type="RichTextLabel" parent="c/div1/div2/c/c/meta_tabs"]
|
||||||
|
visible = false
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
margin_left = 4.0
|
||||||
|
margin_top = 32.0
|
||||||
|
margin_right = -4.0
|
||||||
|
margin_bottom = -4.0
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 3
|
||||||
|
theme = SubResource( 3 )
|
||||||
|
custom_constants/table_hseparation = 16
|
||||||
custom_fonts/bold_italics_font = ExtResource( 13 )
|
custom_fonts/bold_italics_font = ExtResource( 13 )
|
||||||
custom_fonts/italics_font = ExtResource( 10 )
|
custom_fonts/italics_font = ExtResource( 10 )
|
||||||
custom_fonts/bold_font = ExtResource( 11 )
|
custom_fonts/bold_font = ExtResource( 11 )
|
||||||
custom_fonts/normal_font = ExtResource( 12 )
|
custom_fonts/normal_font = ExtResource( 12 )
|
||||||
bbcode_enabled = true
|
bbcode_enabled = true
|
||||||
fit_content_height = true
|
|
||||||
script = ExtResource( 9 )
|
script = ExtResource( 9 )
|
||||||
|
|
||||||
|
[node name="sys" type="RichTextLabel" parent="c/div1/div2/c/c/meta_tabs"]
|
||||||
|
visible = false
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
margin_left = 4.0
|
||||||
|
margin_top = 32.0
|
||||||
|
margin_right = -4.0
|
||||||
|
margin_bottom = -4.0
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 3
|
||||||
|
theme = SubResource( 4 )
|
||||||
|
custom_constants/table_hseparation = 101
|
||||||
|
custom_fonts/bold_italics_font = ExtResource( 13 )
|
||||||
|
custom_fonts/italics_font = ExtResource( 10 )
|
||||||
|
custom_fonts/bold_font = ExtResource( 11 )
|
||||||
|
custom_fonts/normal_font = ExtResource( 12 )
|
||||||
|
bbcode_enabled = true
|
||||||
|
meta_underlined = false
|
||||||
|
text = "idwords ⯆unique"
|
||||||
|
script = ExtResource( 17 )
|
||||||
|
|
||||||
[node name="c2" type="PanelContainer" parent="c/div1/div2"]
|
[node name="c2" type="PanelContainer" parent="c/div1/div2"]
|
||||||
margin_left = 626.0
|
margin_left = 626.0
|
||||||
margin_right = 806.0
|
margin_right = 806.0
|
||||||
@ -221,6 +324,7 @@ size_flags_vertical = 3
|
|||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
|
theme = SubResource( 5 )
|
||||||
custom_fonts/bold_italics_font = ExtResource( 13 )
|
custom_fonts/bold_italics_font = ExtResource( 13 )
|
||||||
custom_fonts/italics_font = ExtResource( 10 )
|
custom_fonts/italics_font = ExtResource( 10 )
|
||||||
custom_fonts/bold_font = ExtResource( 11 )
|
custom_fonts/bold_font = ExtResource( 11 )
|
||||||
@ -246,7 +350,7 @@ anchor_right = 1.0
|
|||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
theme = SubResource( 2 )
|
theme = SubResource( 6 )
|
||||||
custom_fonts/bold_italics_font = ExtResource( 13 )
|
custom_fonts/bold_italics_font = ExtResource( 13 )
|
||||||
custom_fonts/italics_font = ExtResource( 10 )
|
custom_fonts/italics_font = ExtResource( 10 )
|
||||||
custom_fonts/bold_font = ExtResource( 11 )
|
custom_fonts/bold_font = ExtResource( 11 )
|
||||||
|
@ -4,12 +4,12 @@ class_name TE_ExtensionHelper
|
|||||||
|
|
||||||
var symbols:Dictionary = {}
|
var symbols:Dictionary = {}
|
||||||
|
|
||||||
func generate_meta(t:TextEdit, r:TE_RichTextLabel):
|
func generate_meta(t:TextEdit, r:RichTextLabel):
|
||||||
var chars = TE_Util.commas(len(t.text))
|
var chars = TE_Util.commas(len(t.text))
|
||||||
var words = TE_Util.commas(len(t.text.split(" ", false)))
|
var words = TE_Util.commas(len(t.text.split(" ", false)))
|
||||||
var lines = TE_Util.commas(len(TE_Util.split_many(t.text, ".?!\n", false)))
|
var lines = TE_Util.commas(len(TE_Util.split_many(t.text, ".?!\n", false)))
|
||||||
var bytes = TE_Util.file_size(t.file_path)
|
var bytes = TE_Util.file_size(t.file_path)
|
||||||
r.add_constant_override("table_hseparation", int(r.rect_size.x / 5.0))
|
# r.add_constant_override("table_hseparation", int(r.rect_size.x / 5.0))
|
||||||
r.set_bbcode(r.table([
|
r.set_bbcode(r.table([
|
||||||
["chars", "words", "lines", "bytes"],
|
["chars", "words", "lines", "bytes"],
|
||||||
[chars, words, lines, bytes]
|
[chars, words, lines, bytes]
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
tool
|
tool
|
||||||
extends TE_ExtensionHelper
|
extends TE_ExtensionHelper
|
||||||
|
|
||||||
func apply_colors(e:TextEditor, t:TextEdit):
|
func apply_colors(e:TE_TextEditor, t:TextEdit):
|
||||||
.apply_colors(e, t)
|
.apply_colors(e, t)
|
||||||
# symbols
|
# symbols
|
||||||
t.add_color_region("[", "]", e.color_symbol, false)
|
t.add_color_region("[", "]", e.color_symbol, false)
|
||||||
|
@ -34,7 +34,7 @@ func get_symbols(t:String):
|
|||||||
|
|
||||||
return out
|
return out
|
||||||
|
|
||||||
func apply_colors(e:TextEditor, t:TextEdit):
|
func apply_colors(e:TE_TextEditor, t:TextEdit):
|
||||||
.apply_colors(e, t)
|
.apply_colors(e, t)
|
||||||
|
|
||||||
# vars
|
# vars
|
||||||
|
@ -4,7 +4,7 @@ extends TE_ExtensionHelper
|
|||||||
func toggle_comment(t:TextEdit, head:String="<!-- ", tail:String=" -->"):
|
func toggle_comment(t:TextEdit, head:String="<!-- ", tail:String=" -->"):
|
||||||
return .toggle_comment(t, head, tail)
|
return .toggle_comment(t, head, tail)
|
||||||
|
|
||||||
func apply_colors(e:TextEditor, t:TextEdit):
|
func apply_colors(e:TE_TextEditor, t:TextEdit):
|
||||||
.apply_colors(e, t)
|
.apply_colors(e, t)
|
||||||
|
|
||||||
t.add_keyword_color("true", e.color_var)
|
t.add_keyword_color("true", e.color_var)
|
||||||
@ -32,15 +32,9 @@ func apply_colors(e:TextEditor, t:TextEdit):
|
|||||||
t.add_color_region("%s *" % h, "*", tint1, true)
|
t.add_color_region("%s *" % h, "*", tint1, true)
|
||||||
t.add_color_region("%s \"" % h, "\"", tint2, true)
|
t.add_color_region("%s \"" % h, "\"", tint2, true)
|
||||||
t.add_color_region("%s " % h, "*", head, true)
|
t.add_color_region("%s " % h, "*", head, true)
|
||||||
# t.add_color_region("# \"", "\"", TE_Util.hue_shift(head, .33), true)
|
|
||||||
# t.add_color_region("# ", "", head, true)
|
|
||||||
# t.add_color_region("## ", "", head, true)
|
|
||||||
# t.add_color_region("### ", "", head, true)
|
|
||||||
# t.add_color_region("#### ", "", head, true)
|
|
||||||
# t.add_color_region("##### ", "", head, true)
|
|
||||||
# t.add_color_region("###### ", "", head, true)
|
|
||||||
|
|
||||||
# url links
|
# url links
|
||||||
|
# t.add_color_region("[]", ")", e.color_var.lightened(.5))
|
||||||
t.add_color_region("![", ")", e.color_var.lightened(.5))
|
t.add_color_region("![", ")", e.color_var.lightened(.5))
|
||||||
|
|
||||||
# lists
|
# lists
|
||||||
|
@ -43,7 +43,7 @@ func toggle_comment(t:TextEdit, head:String="", tail:String=""):
|
|||||||
|
|
||||||
return [old, new]
|
return [old, new]
|
||||||
|
|
||||||
func apply_colors(e:TextEditor, t:TextEdit):
|
func apply_colors(e:TE_TextEditor, t:TextEdit):
|
||||||
.apply_colors(e, t)
|
.apply_colors(e, t)
|
||||||
|
|
||||||
# strings
|
# strings
|
||||||
|
@ -3,5 +3,5 @@
|
|||||||
name="TextEditor"
|
name="TextEditor"
|
||||||
description="A text editor for Godot."
|
description="A text editor for Godot."
|
||||||
author="teebar"
|
author="teebar"
|
||||||
version="1.2"
|
version="1.4"
|
||||||
script="plugin.gd"
|
script="plugin.gd"
|
||||||
|
Loading…
Reference in New Issue
Block a user