mirror of
https://github.com/Relintai/Godot-TextEditor.git
synced 2025-01-26 16:59:19 +01:00
1.10
This commit is contained in:
parent
40beef4690
commit
dfe30486d2
12
CHANGES.md
12
CHANGES.md
@ -1,3 +1,15 @@
|
|||||||
|
# 1.10
|
||||||
|
- Added cursor panel at bottom of Text Editor.
|
||||||
|
- Word counter.
|
||||||
|
- Symbol path.
|
||||||
|
- Added `insert` menu, for inserting Date.
|
||||||
|
- `ctrl + shift + u` and `ctrl + shift + l` will toggle uppercase and lowercase.
|
||||||
|
- `ctrl + shift + o` and `ctrl + shift + p` will toggle capitalize and variablize.
|
||||||
|
- Fixed `ctrl + f` not bringing up search pannel.
|
||||||
|
- Fixed error when creating new file.
|
||||||
|
- Removed Text Editor hints.
|
||||||
|
- Color tweaks.
|
||||||
|
|
||||||
# 1.9
|
# 1.9
|
||||||
- Tag Viewer now shows all tags regardless of whether the file is open or not.
|
- Tag Viewer now shows all tags regardless of whether the file is open or not.
|
||||||
- File View can show symbols. Toggle with `ctrl` click.
|
- File View can show symbols. Toggle with `ctrl` click.
|
||||||
|
79
README.md
79
README.md
@ -1,5 +1,5 @@
|
|||||||
# Text Editor
|
# Text Editor
|
||||||
Version `1.9`
|
Version `1.10`
|
||||||
|
|
||||||
![](README/readme_preview.png)
|
![](README/readme_preview.png)
|
||||||
|
|
||||||
@ -9,7 +9,7 @@ Version `1.9`
|
|||||||
- Multi file tab system.
|
- Multi file tab system.
|
||||||
- File browser filtering.
|
- File browser filtering.
|
||||||
- Highlighting for common formats (`md` `json` `ini`...)
|
- Highlighting for common formats (`md` `json` `ini`...)
|
||||||
- Tag system.
|
- Tag [System](#mini-features-tags).
|
||||||
- File Management:
|
- File Management:
|
||||||
- Creation.
|
- Creation.
|
||||||
- Renaming.
|
- Renaming.
|
||||||
@ -18,13 +18,7 @@ Version `1.9`
|
|||||||
- Search files.
|
- Search files.
|
||||||
- Image previews.
|
- Image previews.
|
||||||
- Auto save/load settings.
|
- Auto save/load settings.
|
||||||
- Many little *Ease of Life* functions:
|
- Many little *Ease of Life* [features](#mini-features).
|
||||||
- Comment toggling for:
|
|
||||||
- `.md`: `<!-- -->`
|
|
||||||
- `.json`: `/* */`
|
|
||||||
- `.ini`: `; `
|
|
||||||
- `.cfg`: `; `
|
|
||||||
- `.yaml`: `# `
|
|
||||||
|
|
||||||
# Controls
|
# Controls
|
||||||
- `ctrl + N` New file.
|
- `ctrl + N` New file.
|
||||||
@ -89,5 +83,68 @@ This will then highlight *Files* and *Symbols* that have that tag.
|
|||||||
- [ ] Color themes.
|
- [ ] Color themes.
|
||||||
|
|
||||||
# Mini features
|
# Mini features
|
||||||
- Clicking in file will scroll symbol view to the nearest symbol, and display it's name in the tool tip hint.
|
|
||||||
- `ctrl` click in File View to toggle it's symbol list.
|
## File List
|
||||||
|
### Colorize Folder
|
||||||
|
You can colorize files in a folder for easier identification. Right click a folder and select a color.
|
||||||
|
The `tab colors` toggle at the top will toggle tabs colorized by folder.
|
||||||
|
|
||||||
|
### Content Preview
|
||||||
|
You can preview the contents of a file by `ctrl + click`ing it.
|
||||||
|
|
||||||
|
The list is clickable, so you can go straight to a section of the file.
|
||||||
|
|
||||||
|
When using the filter, contents will be scanned.
|
||||||
|
|
||||||
|
## Content List (Symbols)
|
||||||
|
### Selecting Sections
|
||||||
|
`ctrl + click`ing on a symbol will select all lines contained in it, and it's childrens.
|
||||||
|
|
||||||
|
`ctrl + shift + click` a symbol will only select it's lines, not it's childrens.
|
||||||
|
|
||||||
|
## File Editor
|
||||||
|
### Follow Link
|
||||||
|
You can follow Markdown links by `ctrl + click`ing on them.
|
||||||
|
|
||||||
|
## Tags
|
||||||
|
The tag list displays all tags throughout the files.
|
||||||
|
|
||||||
|
To add a tag to a file, include a comment, with a hashtag:
|
||||||
|
- `.md`: `<!-- #tag1 #tag2 -->`
|
||||||
|
- `.json`: `{ "#": "#tag1 #tag2 }`
|
||||||
|
- `.ini` `.cfg`: `; #tag1 #tag2`
|
||||||
|
- `.yaml`: `# #tag1 #tag2`
|
||||||
|
|
||||||
|
`click` a tag to select it.
|
||||||
|
|
||||||
|
All files in the File List and symbols in the Symbol List containing the tag, will be highlighted.
|
||||||
|
|
||||||
|
`ctrl + click` to select multiple tags at once.
|
||||||
|
|
||||||
|
## Meta Panel
|
||||||
|
Toggle the meta panel with `ctrl + M`.
|
||||||
|
|
||||||
|
### Meta
|
||||||
|
The meta tab updates whenever you make a save.
|
||||||
|
|
||||||
|
It lists some information on the contents of your file.
|
||||||
|
|
||||||
|
Currently it mostly only works for Markdown.
|
||||||
|
|
||||||
|
### Search
|
||||||
|
todo
|
||||||
|
|
||||||
|
### System
|
||||||
|
Hitting refrsh will list all files in a table with sortable columns.
|
||||||
|
|
||||||
|
Select a column to sort on:
|
||||||
|
- Chapter count.
|
||||||
|
- Word count.
|
||||||
|
- Unique words.
|
||||||
|
- Progress.
|
||||||
|
- Time since modified.
|
||||||
|
|
||||||
|
### Image
|
||||||
|
In Markdown files (`.md`) you can `ctrl + click` an image to preview it.
|
||||||
|
|
||||||
|
Images look like: `![](image_url.png)` in Markdown.
|
@ -1,6 +1,9 @@
|
|||||||
tool
|
tool
|
||||||
extends "res://addons/text_editor/TE_RichTextLabel.gd"
|
extends "res://addons/text_editor/TE_RichTextLabel.gd"
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
clear()
|
||||||
|
|
||||||
func msg(msg):
|
func msg(msg):
|
||||||
append_bbcode(str(msg))
|
append_bbcode(str(msg))
|
||||||
newline()
|
newline()
|
||||||
|
@ -83,29 +83,36 @@ var color_tag:Color = Color.yellow
|
|||||||
var color_var:Color = Color.orange
|
var color_var:Color = Color.orange
|
||||||
var color_varname:Color = color_text.darkened(.25)
|
var color_varname:Color = color_text.darkened(.25)
|
||||||
|
|
||||||
|
export var p_tab_parent:NodePath
|
||||||
|
export var p_tab_prefab:NodePath
|
||||||
|
export var p_console:NodePath
|
||||||
|
export var p_progress_bar:NodePath
|
||||||
|
|
||||||
|
onready var tab_parent:TabContainer = get_node(p_tab_parent)
|
||||||
|
onready var tab_prefab:Node = get_node(p_tab_prefab)
|
||||||
|
onready var console:RichTextLabel = get_node(p_console)
|
||||||
|
onready var progress_bar:ProgressBar = get_node(p_progress_bar)
|
||||||
|
|
||||||
|
export var p_menu_file:NodePath
|
||||||
|
export var p_menu_view:NodePath
|
||||||
|
export var p_menu_insert:NodePath
|
||||||
|
onready var menu_file:MenuButton = get_node(p_menu_file)
|
||||||
|
onready var menu_view:MenuButton = get_node(p_menu_view)
|
||||||
|
onready var menu_insert:MenuButton = get_node(p_menu_insert)
|
||||||
|
var popup_file:PopupMenu
|
||||||
|
var popup_view:PopupMenu
|
||||||
|
var popup_insert:PopupMenu
|
||||||
|
var popup_view_dir:PopupMenu = PopupMenu.new()
|
||||||
|
var popup_view_file:PopupMenu = PopupMenu.new()
|
||||||
|
|
||||||
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/c/tab_container
|
|
||||||
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
|
||||||
onready var file_dialog:FileDialog = $file_dialog
|
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_view:MenuButton = $c/c/c/view_button
|
|
||||||
onready var word_wrap:CheckBox = $c/c/c/word_wrap
|
onready var word_wrap:CheckBox = $c/c/c/word_wrap
|
||||||
onready var tab_colors:CheckBox = $c/c/c/tab_colors
|
onready var tab_colors:CheckBox = $c/c/c/tab_colors
|
||||||
|
|
||||||
export var p_console:NodePath
|
|
||||||
onready var console:RichTextLabel = get_node(p_console)
|
|
||||||
|
|
||||||
export var p_progress_bar:NodePath
|
|
||||||
onready var progress_bar:ProgressBar = get_node(p_progress_bar)
|
|
||||||
|
|
||||||
var popup_file:PopupMenu
|
|
||||||
var popup_view:PopupMenu
|
|
||||||
var popup_view_dir:PopupMenu = PopupMenu.new()
|
|
||||||
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 dir_paths:Array = []
|
||||||
@ -149,7 +156,7 @@ func _ready():
|
|||||||
btn.connect("pressed", popup_unsaved, "hide")
|
btn.connect("pressed", popup_unsaved, "hide")
|
||||||
TE_Util.dig(popup_unsaved, self, "_apply_fonts")
|
TE_Util.dig(popup_unsaved, self, "_apply_fonts")
|
||||||
|
|
||||||
# menu
|
# menu: file
|
||||||
menu_file.add_font_override("font", FONT_R)
|
menu_file.add_font_override("font", FONT_R)
|
||||||
popup_file = menu_file.get_popup()
|
popup_file = menu_file.get_popup()
|
||||||
popup_file.clear()
|
popup_file.clear()
|
||||||
@ -159,7 +166,7 @@ func _ready():
|
|||||||
popup_file.add_item("Open last closed", 300)
|
popup_file.add_item("Open last closed", 300)
|
||||||
_e = popup_file.connect("index_pressed", self, "_menu_file")
|
_e = popup_file.connect("index_pressed", self, "_menu_file")
|
||||||
|
|
||||||
# view
|
# menu: view
|
||||||
menu_view.add_font_override("font", FONT_R)
|
menu_view.add_font_override("font", FONT_R)
|
||||||
popup_view = menu_view.get_popup()
|
popup_view = menu_view.get_popup()
|
||||||
popup_view.clear()
|
popup_view.clear()
|
||||||
@ -209,6 +216,15 @@ func _ready():
|
|||||||
popup_view.add_submenu_item("Files", "Files")
|
popup_view.add_submenu_item("Files", "Files")
|
||||||
_e = popup_view_file.connect("index_pressed", self, "_menu_view_file")
|
_e = popup_view_file.connect("index_pressed", self, "_menu_view_file")
|
||||||
|
|
||||||
|
# menu: insert
|
||||||
|
menu_insert.add_font_override("font", FONT_R)
|
||||||
|
popup_insert = menu_insert.get_popup()
|
||||||
|
popup_insert.clear()
|
||||||
|
popup_insert.add_font_override("font", FONT_R)
|
||||||
|
popup_insert.add_item("Date")
|
||||||
|
popup_insert.add_item("Words Typed")
|
||||||
|
_e = popup_insert.connect("index_pressed", self, "_menu_insert")
|
||||||
|
|
||||||
# file dialog
|
# file dialog
|
||||||
_e = file_dialog.connect("file_selected", self, "_file_dialog_file")
|
_e = file_dialog.connect("file_selected", self, "_file_dialog_file")
|
||||||
file_dialog.add_font_override("title_font", FONT_R)
|
file_dialog.add_font_override("title_font", FONT_R)
|
||||||
@ -232,10 +248,25 @@ func _ready():
|
|||||||
file_data.clear()
|
file_data.clear()
|
||||||
_scanning = true
|
_scanning = true
|
||||||
_start_load_at = OS.get_system_time_secs()
|
_start_load_at = OS.get_system_time_secs()
|
||||||
_files_to_load = get_all_file_paths().duplicate()
|
_files_to_load = file_paths.duplicate()#get_all_file_paths().duplicate()
|
||||||
start_progress(len(_files_to_load))
|
start_progress(len(_files_to_load))
|
||||||
set_process(true)
|
set_process(true)
|
||||||
|
|
||||||
|
func override_fonts(node:Node):
|
||||||
|
if node is RichTextLabel:
|
||||||
|
var r:RichTextLabel = node
|
||||||
|
r.add_font_override("normal_font", FONT_R)
|
||||||
|
r.add_font_override("bold_font", FONT_B)
|
||||||
|
r.add_font_override("italics_font", FONT_I)
|
||||||
|
r.add_font_override("bold_italics_font", FONT_BI)
|
||||||
|
|
||||||
|
func get_symbol_color(deep:int=0, off:float=0.0) -> Color:
|
||||||
|
var t = clamp(deep / 6.0, 0.0, 1.0)
|
||||||
|
var s = pow(lerp(1.0, 0.33, t), 6.0)
|
||||||
|
var v = lerp(1.0, 0.33, t)
|
||||||
|
var c = color_symbol
|
||||||
|
return c.from_hsv(wrapf(c.h + off, 0.0, 1.0), c.s * s, c.v * v, c.a)
|
||||||
|
|
||||||
func start_progress(maxx:int):
|
func start_progress(maxx:int):
|
||||||
progress_bar.visible = true
|
progress_bar.visible = true
|
||||||
progress_bar.value = 0
|
progress_bar.value = 0
|
||||||
@ -537,12 +568,34 @@ func _apply_fonts(n:Node):
|
|||||||
if n.has_font("font"):
|
if n.has_font("font"):
|
||||||
n.add_font_override("font", FONT_R)
|
n.add_font_override("font", FONT_R)
|
||||||
|
|
||||||
|
func insert_date():
|
||||||
|
var d = OS.get_date()
|
||||||
|
var m = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"][d.month-1]
|
||||||
|
insert("%s %s, %s" % [m, d.day, d.year])
|
||||||
|
|
||||||
|
func insert(text:String):
|
||||||
|
var t:TextEdit = get_selected_tab()
|
||||||
|
if t:
|
||||||
|
var l = t.cursor_get_line()
|
||||||
|
var c = t.cursor_get_column()
|
||||||
|
t.insert_text_at_cursor(text)
|
||||||
|
t.select(l, c, l, c+len(text))
|
||||||
|
yield(get_tree(), "idle_frame")
|
||||||
|
t.grab_focus()
|
||||||
|
t.grab_click_focus()
|
||||||
|
|
||||||
func _menu_file(index:int):
|
func _menu_file(index:int):
|
||||||
var text = popup_file.get_item_text(index)
|
var text = popup_file.get_item_text(index)
|
||||||
match text:
|
match text:
|
||||||
"New File": popup_create_file() # "New File"
|
"New File": popup_create_file() # "New File"
|
||||||
"Open last closed": open_last_file() # "Open last closed"
|
"Open last closed": open_last_file() # "Open last closed"
|
||||||
|
|
||||||
|
func _menu_insert(index:int):
|
||||||
|
var text = popup_insert.get_item_text(index)
|
||||||
|
match text:
|
||||||
|
"Date": insert_date()
|
||||||
|
"Words Typed": insert("WORDS TYPED")
|
||||||
|
|
||||||
func _menu_view_dir(index:int):
|
func _menu_view_dir(index:int):
|
||||||
var text = popup_view_dir.get_item_text(index)
|
var text = popup_view_dir.get_item_text(index)
|
||||||
match text:
|
match text:
|
||||||
@ -675,6 +728,7 @@ func create_file(file_path:String, text:String=""):
|
|||||||
if f.open(file_path, File.WRITE) == OK:
|
if f.open(file_path, File.WRITE) == OK:
|
||||||
f.store_string(text)
|
f.store_string(text)
|
||||||
f.close()
|
f.close()
|
||||||
|
update_file_data(file_path)
|
||||||
refresh_files()
|
refresh_files()
|
||||||
|
|
||||||
if file_dialog.has_meta("callback"):
|
if file_dialog.has_meta("callback"):
|
||||||
@ -1025,15 +1079,15 @@ func _can_show_file(fname:String) -> bool:
|
|||||||
func get_dir_info(path:String) -> Dictionary:
|
func get_dir_info(path:String) -> Dictionary:
|
||||||
return TE_Util.dig_for(file_list, "file_path", path)
|
return TE_Util.dig_for(file_list, "file_path", path)
|
||||||
|
|
||||||
var all_file_paths:Array = []
|
#var all_file_paths:Array = []
|
||||||
func get_all_file_paths():
|
#func get_all_file_paths():
|
||||||
all_file_paths.clear()
|
# all_file_paths.clear()
|
||||||
TE_Util.dig(file_list, self, "_get_all_file_paths")
|
# TE_Util.dig(file_list, self, "_get_all_file_paths")
|
||||||
return all_file_paths
|
# return all_file_paths
|
||||||
|
#
|
||||||
func _get_all_file_paths(d:Dictionary):
|
#func _get_all_file_paths(d:Dictionary):
|
||||||
if "files" in d:
|
# if "files" in d:
|
||||||
all_file_paths.append_array(d.files)
|
# all_file_paths.append_array(d.files)
|
||||||
|
|
||||||
func get_file_tint_name(fpath:String) -> String:
|
func get_file_tint_name(fpath:String) -> String:
|
||||||
var bdir = fpath.get_base_dir()
|
var bdir = fpath.get_base_dir()
|
||||||
|
@ -126,7 +126,7 @@ func selection_lowercase():
|
|||||||
|
|
||||||
func selection_variable():
|
func selection_variable():
|
||||||
_remember_selection()
|
_remember_selection()
|
||||||
insert_text_at_cursor(get_selection_text().to_lower().replace(" ", "_"))
|
insert_text_at_cursor(TE_Util.to_var(get_selection_text()))
|
||||||
_remake_selection()
|
_remake_selection()
|
||||||
|
|
||||||
func selection_capitalize():
|
func selection_capitalize():
|
||||||
@ -134,6 +134,8 @@ func selection_capitalize():
|
|||||||
insert_text_at_cursor(get_selection_text().capitalize())
|
insert_text_at_cursor(get_selection_text().capitalize())
|
||||||
_remake_selection()
|
_remake_selection()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func _node(n):
|
func _node(n):
|
||||||
var _e
|
var _e
|
||||||
if n is HScrollBar:
|
if n is HScrollBar:
|
||||||
@ -188,20 +190,27 @@ func _update_selected_line():
|
|||||||
var l = cursor_get_line()
|
var l = cursor_get_line()
|
||||||
editor.select_symbol_line(0)
|
editor.select_symbol_line(0)
|
||||||
|
|
||||||
var depth = PoolStringArray()
|
for i in len(symbols):
|
||||||
|
var sindex = clamp(i, 0, len(symbols))
|
||||||
|
var symbol = symbols.values()[sindex]
|
||||||
|
if i == len(symbols)-1 or symbols.keys()[i+1] > l:
|
||||||
|
editor.select_symbol_line(sindex)
|
||||||
|
break
|
||||||
|
|
||||||
|
func get_line_symbols(line:int) -> PoolStringArray:
|
||||||
|
var depth:PoolStringArray = PoolStringArray()
|
||||||
for i in len(symbols):
|
for i in len(symbols):
|
||||||
var sindex = clamp(i, 0, len(symbols))
|
var sindex = clamp(i, 0, len(symbols))
|
||||||
var symbol = symbols.values()[sindex]
|
var symbol = symbols.values()[sindex]
|
||||||
while len(depth) <= symbol.deep:
|
while len(depth) <= symbol.deep:
|
||||||
depth.append("")
|
depth.append("")
|
||||||
|
|
||||||
depth[symbol.deep] = " ".repeat(symbol.deep) + symbol.name
|
depth[symbol.deep] = symbol.name
|
||||||
|
|
||||||
if i == len(symbols)-1 or symbols.keys()[i+1] > l:
|
if i == len(symbols)-1 or symbols.keys()[i+1] > line:
|
||||||
editor.select_symbol_line(sindex)
|
|
||||||
depth.resize(symbol.deep+1)
|
depth.resize(symbol.deep+1)
|
||||||
hint_tooltip = "[%s]\n%s" % [editor.get_localized_path(file_path), depth.join("\n")]
|
|
||||||
break
|
break
|
||||||
|
return depth
|
||||||
|
|
||||||
func _input(e):
|
func _input(e):
|
||||||
if not editor.is_plugin_active():
|
if not editor.is_plugin_active():
|
||||||
@ -272,10 +281,29 @@ func _input(e):
|
|||||||
select(f+1, 0, t+1, len(get_line(t+1)))
|
select(f+1, 0, t+1, len(get_line(t+1)))
|
||||||
cursor_set_line(cursor_get_line()+1, false)
|
cursor_set_line(cursor_get_line()+1, false)
|
||||||
|
|
||||||
if e.scancode == KEY_U: selection_uppercase()
|
if e.scancode == KEY_U:
|
||||||
if e.scancode == KEY_L: selection_lowercase()
|
if get_selection_text() == get_selection_text().to_upper():
|
||||||
if e.scancode == KEY_O: selection_capitalize()
|
selection_lowercase()
|
||||||
if e.scancode == KEY_P: selection_variable()
|
else:
|
||||||
|
selection_uppercase()
|
||||||
|
|
||||||
|
if e.scancode == KEY_L:
|
||||||
|
if get_selection_text() == get_selection_text().to_lower():
|
||||||
|
selection_uppercase()
|
||||||
|
else:
|
||||||
|
selection_lowercase()
|
||||||
|
|
||||||
|
if e.scancode == KEY_O:
|
||||||
|
if get_selection_text() == get_selection_text().capitalize():
|
||||||
|
selection_variable()
|
||||||
|
else:
|
||||||
|
selection_capitalize()
|
||||||
|
|
||||||
|
if e.scancode == KEY_P:
|
||||||
|
if get_selection_text() == TE_Util.to_var(get_selection_text()):
|
||||||
|
selection_capitalize()
|
||||||
|
else:
|
||||||
|
selection_variable()
|
||||||
|
|
||||||
func _unhandled_key_input(e):
|
func _unhandled_key_input(e):
|
||||||
if not visible:
|
if not visible:
|
||||||
@ -328,9 +356,10 @@ func goto_symbol(index:int):
|
|||||||
if syms and index >= 0 and index < len(syms):
|
if syms and index >= 0 and index < len(syms):
|
||||||
goto_line(syms[index])
|
goto_line(syms[index])
|
||||||
|
|
||||||
func goto_line(line:int):
|
func goto_line(line:int, bottom:bool=true):
|
||||||
# force scroll to bottom so selected line will be at top
|
# force scroll to bottom so selected line will be at top
|
||||||
cursor_set_line(get_line_count())
|
if bottom:
|
||||||
|
cursor_set_line(get_line_count())
|
||||||
cursor_set_line(line)
|
cursor_set_line(line)
|
||||||
_update_selected_line()
|
_update_selected_line()
|
||||||
|
|
||||||
@ -467,7 +496,6 @@ func update_name():
|
|||||||
editor.tab_parent.set_tab_icon(get_index(), null)
|
editor.tab_parent.set_tab_icon(get_index(), null)
|
||||||
|
|
||||||
editor.tab_parent.set_tab_title(get_index(), n)
|
editor.tab_parent.set_tab_title(get_index(), n)
|
||||||
editor.tab_parent.get_tab_control(get_index()).hint_tooltip = file_path
|
|
||||||
|
|
||||||
func update_heading():
|
func update_heading():
|
||||||
if Engine.editor_hint:
|
if Engine.editor_hint:
|
||||||
|
101
addons/text_editor/TE_FileInfoLabel.gd
Normal file
101
addons/text_editor/TE_FileInfoLabel.gd
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
tool
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
const DIM:Color = Color.webgray
|
||||||
|
const CLR:Color = Color.white
|
||||||
|
|
||||||
|
onready var editor:TE_Editor = owner
|
||||||
|
var tab:TextEdit = null
|
||||||
|
var typed:String = ""
|
||||||
|
var word_count:int = 0
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
var _e
|
||||||
|
yield(get_tree(), "idle_frame")
|
||||||
|
_e = editor.tab_parent.connect("tab_changed", self, "_tab_changed")
|
||||||
|
|
||||||
|
editor.override_fonts($l)
|
||||||
|
editor.override_fonts($m)
|
||||||
|
editor.override_fonts($r)
|
||||||
|
|
||||||
|
func _tab_changed(index:int):
|
||||||
|
if tab and is_instance_valid(tab) and not tab.is_queued_for_deletion():
|
||||||
|
tab.disconnect("cursor_changed", self, "_cursor_changed")
|
||||||
|
tab = null
|
||||||
|
|
||||||
|
var new_tab = editor.tab_parent.get_child(index)
|
||||||
|
if tab == new_tab:
|
||||||
|
return
|
||||||
|
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
|
||||||
|
|
||||||
|
func _input(event):
|
||||||
|
if event is InputEventKey and event.pressed and tab and is_instance_valid(tab) and tab.has_focus():
|
||||||
|
if not event.scancode == KEY_BACKSPACE:
|
||||||
|
if char(event.scancode) in " .?!-":
|
||||||
|
word_count += 1
|
||||||
|
typed = ""
|
||||||
|
else:
|
||||||
|
typed += char(event.scancode)
|
||||||
|
_cursor_changed()
|
||||||
|
|
||||||
|
func _cursor_changed():
|
||||||
|
var l_lines:PoolStringArray = PoolStringArray()
|
||||||
|
var m_lines:PoolStringArray = PoolStringArray()
|
||||||
|
var r_lines:PoolStringArray = PoolStringArray()
|
||||||
|
var l:RichTextLabel
|
||||||
|
|
||||||
|
if tab.is_selection_active():
|
||||||
|
var seltext:String = tab.get_selection_text()
|
||||||
|
var words = {}
|
||||||
|
var word_count:int = TE_Util.count_words(seltext, words, null, false)
|
||||||
|
m_lines.append(kv("chars", len(seltext)))
|
||||||
|
m_lines.append(kv("words", word_count))
|
||||||
|
|
||||||
|
var l1 = tab.get_selection_from_line() + 1
|
||||||
|
var l2 = tab.get_selection_to_line() + 1
|
||||||
|
var c1 = tab.get_selection_from_column()
|
||||||
|
var c2 = tab.get_selection_to_column()
|
||||||
|
|
||||||
|
if l1 == l2:
|
||||||
|
l_lines.append(kv("line", l1))
|
||||||
|
l_lines.append(kv("char", "%s - %s" % [c1, c2]))
|
||||||
|
|
||||||
|
else:
|
||||||
|
l_lines.append(clr("line: ", DIM) + clr(str(l1), CLR) + clr(":", DIM) + clr(str(c1), CLR))
|
||||||
|
l_lines.append(clr("->", Color.webgray))
|
||||||
|
l_lines.append(clr("line: ", DIM) + clr(str(l2), CLR) + clr(":", DIM) + clr(str(c2), CLR))
|
||||||
|
|
||||||
|
m_lines.append(kv("lines", abs(l2 - l1) + 1))
|
||||||
|
|
||||||
|
else:
|
||||||
|
l_lines.append(kv("line", tab.cursor_get_line() + 1))
|
||||||
|
l_lines.append(kv("char", tab.cursor_get_column()))
|
||||||
|
|
||||||
|
var depth = tab.get_line_symbols(tab.cursor_get_line())
|
||||||
|
for i in len(depth):
|
||||||
|
depth[i] = b(depth[i])
|
||||||
|
r_lines.append(depth.join(clr("/", DIM)))
|
||||||
|
|
||||||
|
m_lines.append(kv("typed", word_count))
|
||||||
|
|
||||||
|
$l.set_bbcode(l_lines.join(" "))
|
||||||
|
$m.set_bbcode("[center]" + m_lines.join(" "))
|
||||||
|
$r.set_bbcode("[right]" +r_lines.join(" "))
|
||||||
|
|
||||||
|
func kv(k:String, v) -> String:
|
||||||
|
var clr2 = Color.white
|
||||||
|
if v is int:
|
||||||
|
v = TE_Util.commas(v)
|
||||||
|
return clr(k + ": ", DIM) + clr(str(v), clr2)
|
||||||
|
|
||||||
|
func b(t:String) -> String: return "[b]%s[/b]" % t
|
||||||
|
func i(t:String) -> String: return "[i]%s[/i]" % t
|
||||||
|
func u(t:String) -> String: return "[u]%s[/u]" % t
|
||||||
|
func clr(t:String, c:Color) -> String: return "[color=#%s]%s[/color]" % [c.to_html(), t]
|
@ -319,7 +319,7 @@ func _draw_dir(dir:Dictionary, deep:int):
|
|||||||
var sname = sdata.name
|
var sname = sdata.name
|
||||||
if filter and not filter in sname.to_lower():
|
if filter and not filter in sname.to_lower():
|
||||||
continue
|
continue
|
||||||
var s = " ".repeat(sdata.deep) + clr(" %s) " % [j], dull) + clr(sname, dull_tint)
|
var s = clr("|%s %s) " % [" ".repeat(sdata.deep), j], dull) + clr(sname, dull_tint)
|
||||||
var h = hint_path + " #" + sname
|
var h = hint_path + " #" + sname
|
||||||
symbol_lines.append(meta(space + s, ["fs", file_path, j], h))
|
symbol_lines.append(meta(space + s, ["fs", file_path, j], h))
|
||||||
|
|
||||||
|
@ -13,12 +13,26 @@ func _unhandled_key_input(e):
|
|||||||
if not editor.is_plugin_active():
|
if not editor.is_plugin_active():
|
||||||
return
|
return
|
||||||
|
|
||||||
# Ctrl + M = meta tabs
|
if e.control and e.pressed:
|
||||||
if e.scancode == KEY_M and e.control and e.pressed:
|
match e.scancode:
|
||||||
get_parent().visible = not get_parent().visible
|
# show this menu
|
||||||
get_tree().set_input_as_handled()
|
KEY_M:
|
||||||
|
set_visible(not get_parent().visible)
|
||||||
|
get_tree().set_input_as_handled()
|
||||||
|
|
||||||
|
# find menu
|
||||||
|
KEY_F:
|
||||||
|
set_visible(true)
|
||||||
|
select_tab($search)
|
||||||
|
$search/rte.select()
|
||||||
|
|
||||||
|
func set_visible(v:bool):
|
||||||
|
get_parent().visible = v
|
||||||
|
|
||||||
|
func select_tab(tab:Node):
|
||||||
|
current_tab = tab.get_index()
|
||||||
|
|
||||||
func show_image(file_path:String):
|
func show_image(file_path:String):
|
||||||
get_parent().visible = true
|
get_parent().visible = true
|
||||||
current_tab = $image.get_index()
|
select_tab($image)
|
||||||
$image/image.texture = TE_Util.load_image(file_path)
|
$image/image.texture = TE_Util.load_image(file_path)
|
||||||
|
@ -17,20 +17,10 @@ func _ready():
|
|||||||
all_toggle.add_font_override("font", editor.FONT_R)
|
all_toggle.add_font_override("font", editor.FONT_R)
|
||||||
case_toggle.add_font_override("font", editor.FONT_R)
|
case_toggle.add_font_override("font", editor.FONT_R)
|
||||||
|
|
||||||
func _unhandled_key_input(e):
|
func select():
|
||||||
if not editor.is_plugin_active():
|
line_edit.grab_focus()
|
||||||
return
|
line_edit.grab_click_focus()
|
||||||
|
line_edit.select_all()
|
||||||
# Ctrl + F to search
|
|
||||||
if e.scancode == KEY_F and e.pressed and e.control:
|
|
||||||
line_edit.grab_focus()
|
|
||||||
line_edit.grab_click_focus()
|
|
||||||
line_edit.select_all()
|
|
||||||
# show meta tab
|
|
||||||
get_parent().get_parent().show()
|
|
||||||
# make search tab current meta tab
|
|
||||||
get_parent().get_parent().current_tab = get_parent().get_index()
|
|
||||||
get_tree().set_input_as_handled()
|
|
||||||
|
|
||||||
func _clicked(args):
|
func _clicked(args):
|
||||||
match args[0]:
|
match args[0]:
|
||||||
@ -39,12 +29,16 @@ func _clicked(args):
|
|||||||
editor.select_file(args[1])
|
editor.select_file(args[1])
|
||||||
yield(get_tree(), "idle_frame")
|
yield(get_tree(), "idle_frame")
|
||||||
# goto line
|
# goto line
|
||||||
var line = int(args[2])
|
var hfrom = int(args[2])
|
||||||
tab.goto_line(line)
|
var line = int(args[3])
|
||||||
|
tab.goto_line(hfrom)
|
||||||
|
tab.goto_line(line, false)
|
||||||
# select area
|
# select area
|
||||||
var from = int(args[3])
|
var from = int(args[4])
|
||||||
var lenn = int(args[4])
|
var lenn = int(args[5])
|
||||||
tab.select(line, from, line, from + lenn)
|
tab.select(line, from, line, from + lenn)
|
||||||
|
tab.cursor_set_line(line)
|
||||||
|
tab.cursor_set_column(from)
|
||||||
|
|
||||||
func _text_entered(search_for:String):
|
func _text_entered(search_for:String):
|
||||||
last_search = search_for
|
last_search = search_for
|
||||||
@ -62,33 +56,37 @@ func _text_entered(search_for:String):
|
|||||||
l = meta(l, ["goto", file_path, 0, 0, 0], file_path)
|
l = meta(l, ["goto", file_path, 0, 0, 0], file_path)
|
||||||
bbcode.append(l)
|
bbcode.append(l)
|
||||||
|
|
||||||
for j in len(found[file_path]):
|
var all_found = found[file_path]
|
||||||
|
for j in len(all_found):
|
||||||
var result = found[file_path][j]
|
var result = found[file_path][j]
|
||||||
var got_lines = result[0]
|
var got_lines = result[0]
|
||||||
var line_index = result[1]
|
var highlight_from = result[1]
|
||||||
var char_index = result[2]
|
var line_index = result[2]
|
||||||
|
var char_index = result[3]
|
||||||
|
|
||||||
if j != 0:
|
bbcode.append(clr(" %s/%s" % [j+1, len(all_found)], Color.orange))
|
||||||
bbcode.append("\t" + clr("...", Color.gray))
|
|
||||||
|
|
||||||
for i in len(got_lines):
|
for i in len(got_lines):
|
||||||
l = ""
|
l = ""
|
||||||
|
var highlight = got_lines[i][0]
|
||||||
|
var lindex = got_lines[i][1]
|
||||||
|
var ltext = got_lines[i][2]
|
||||||
|
|
||||||
if i == 2:
|
if highlight:
|
||||||
var line:String = got_lines[i]
|
var line:String = ltext
|
||||||
var head:String = line.substr(0, char_index)
|
var head:String = line.substr(0, char_index)
|
||||||
var midd:String = line.substr(char_index, len(search_for))
|
var midd:String = line.substr(char_index, len(search_for))
|
||||||
var tail:String = line.substr(char_index+len(search_for))
|
var tail:String = line.substr(char_index+len(search_for))
|
||||||
head = clr(head, Color.deepskyblue.lightened(.5))
|
head = clr(head, Color.white.darkened(.25))
|
||||||
midd = clr(midd, Color.deepskyblue.darkened(.25))
|
midd = b(clr(midd, Color.white))
|
||||||
tail = clr(tail, Color.deepskyblue.lightened(.5))
|
tail = clr(tail, Color.white.darkened(.25))
|
||||||
l = "\t" + clr(str(line_index-2+i+1) + ": ", Color.deepskyblue.lightened(.5)) + (head+midd+tail)
|
l = "\t" + clr(str(lindex) + ": ", Color.white.darkened(.25)) + (head+midd+tail)
|
||||||
|
|
||||||
elif line_index-2+i >= 0:
|
else:
|
||||||
l = "\t" + clr(str(line_index-2+i+1) + ": ", Color.gray) + got_lines[i]
|
l = "\t" + clr(str(lindex) + ": ", Color.white.darkened(.65)) + clr(ltext, Color.white.darkened(.5))
|
||||||
|
|
||||||
if l:
|
if l:
|
||||||
l = meta(l, ["goto", file_path, line_index, char_index, len(search_for)])
|
l = meta(l, ["goto", file_path, highlight_from, line_index, char_index, len(search_for)])
|
||||||
bbcode.append(l)
|
bbcode.append(l)
|
||||||
|
|
||||||
set_bbcode(bbcode.join("\n"))
|
set_bbcode(bbcode.join("\n"))
|
||||||
@ -120,7 +118,7 @@ func _search(search_for:String) -> Dictionary:
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
paths = [sel]
|
paths = [sel]
|
||||||
|
|
||||||
for path in paths:
|
for path in paths:
|
||||||
var lines = TE_Util.load_text(path).split("\n")
|
var lines = TE_Util.load_text(path).split("\n")
|
||||||
for line_index in len(lines):
|
for line_index in len(lines):
|
||||||
@ -136,17 +134,25 @@ func _search(search_for:String) -> Dictionary:
|
|||||||
if not path in out:
|
if not path in out:
|
||||||
out[path] = []
|
out[path] = []
|
||||||
|
|
||||||
var preview_lines = PoolStringArray()
|
var preview_lines = [[true, line_index, lines[line_index]]]
|
||||||
var highlight_from:int = line_index
|
var highlight_from:int = line_index
|
||||||
|
|
||||||
# show surrounding 5 lines.
|
# previous few lines before a blank
|
||||||
for i in range(-2, 3):
|
for i in range(1, 3):
|
||||||
if line_index+i >= 0 and line_index+i < len(lines):
|
if line_index-i >= 0:
|
||||||
preview_lines.append(lines[line_index+i])
|
if not lines[line_index-i].strip_edges():
|
||||||
else:
|
break
|
||||||
preview_lines.append("")
|
highlight_from = line_index-i
|
||||||
|
preview_lines.push_front([false, line_index-i, lines[line_index-i]])
|
||||||
|
|
||||||
|
# next few lines before a blank
|
||||||
|
for i in range(1, 3):
|
||||||
|
if line_index+i < len(lines):
|
||||||
|
if not lines[line_index+i].strip_edges():
|
||||||
|
break
|
||||||
|
preview_lines.push_back([false, line_index+i, lines[line_index+i]])
|
||||||
|
|
||||||
# lines, index in file, index in line
|
# lines, index in file, index in line
|
||||||
out[path].append([preview_lines, line_index, char_index])
|
out[path].append([preview_lines, highlight_from, line_index, char_index])
|
||||||
|
|
||||||
return out
|
return out
|
||||||
|
@ -120,19 +120,18 @@ func _redraw():
|
|||||||
if filter and not filter in symbol_info.name.to_lower():
|
if filter and not filter in symbol_info.name.to_lower():
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if deep == 0:
|
if symbol_info.name.begins_with("*") and symbol_info.name.ends_with("*"):
|
||||||
cl = editor.color_symbol
|
cl = editor.get_symbol_color(deep, -.33)
|
||||||
if symbol_info.name.begins_with("*") and symbol_info.name.ends_with("*"):
|
|
||||||
cl = TE_Util.hue_shift(cl, -.33)
|
elif symbol_info.name.begins_with('"') and symbol_info.name.ends_with('"'):
|
||||||
elif symbol_info.name.begins_with('"') and symbol_info.name.ends_with('"'):
|
cl = editor.get_symbol_color(deep, .33)
|
||||||
cl = TE_Util.hue_shift(cl, .33)
|
|
||||||
|
else:
|
||||||
|
cl = editor.get_symbol_color(deep)
|
||||||
|
|
||||||
if not editor.is_tagged_or_visible(symbol_info.tags):
|
if not editor.is_tagged_or_visible(symbol_info.tags):
|
||||||
cl = cl.darkened(.7)
|
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(", ")
|
var tags = "" if not symbol_info.tags else PoolStringArray(symbol_info.tags).join(", ")
|
||||||
var text = clr(meta(space + symbol_info.name, [symbol_info, line_index], tags), cl)
|
var text = clr(meta(space + symbol_info.name, [symbol_info, line_index], tags), cl)
|
||||||
if i == selected_line:
|
if i == selected_line:
|
||||||
|
@ -31,13 +31,13 @@ class Sorter:
|
|||||||
static func sort_keys(d:Dictionary, reverse:bool=false): return Sorter.new(d).on_keys(reverse)
|
static func sort_keys(d:Dictionary, reverse:bool=false): return Sorter.new(d).on_keys(reverse)
|
||||||
static func sort_vals(d:Dictionary, reverse:bool=false): return Sorter.new(d).on_vals(reverse)
|
static func sort_vals(d:Dictionary, reverse:bool=false): return Sorter.new(d).on_vals(reverse)
|
||||||
|
|
||||||
static func count_words(text:String, counter:Dictionary, skip_words=null):
|
static func count_words(text:String, counter:Dictionary, skip_words=null, stop_words:bool=true):
|
||||||
var word_count:int = 0
|
var word_count:int = 0
|
||||||
for sentence in text.split("."):
|
for sentence in text.split("."):
|
||||||
for word in sentence.split(" "):
|
for word in sentence.split(" "):
|
||||||
word = _sanitize_word(word)
|
word = _sanitize_word(word)
|
||||||
if not word: continue
|
if not word: continue
|
||||||
if word in TE_StopWords.STOP_WORDS: continue
|
if stop_words and word in TE_StopWords.STOP_WORDS: continue
|
||||||
if skip_words and word in skip_words: continue
|
if skip_words and word in skip_words: continue
|
||||||
|
|
||||||
word_count += 1
|
word_count += 1
|
||||||
@ -69,6 +69,9 @@ static func _sanitize_word(word:String):
|
|||||||
|
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
static func to_var(s:String) -> String:
|
||||||
|
return s.to_lower().replace(" ", "_")
|
||||||
|
|
||||||
static func load_text(path:String) -> String:
|
static func load_text(path:String) -> String:
|
||||||
var f:File = File.new()
|
var f:File = File.new()
|
||||||
if f.file_exists(path):
|
if f.file_exists(path):
|
||||||
@ -197,6 +200,9 @@ static func file_size(path:String) -> String:
|
|||||||
static func hue_shift(c:Color, h:float) -> Color:
|
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)
|
return c.from_hsv(wrapf(c.h + h, 0.0, 1.0), c.s, c.v, c.a)
|
||||||
|
|
||||||
|
#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)
|
||||||
|
|
||||||
#static func sort(d, reverse:bool=false):
|
#static func sort(d, reverse:bool=false):
|
||||||
# return Dict.new(d).sort(reverse)
|
# return Dict.new(d).sort(reverse)
|
||||||
#
|
#
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
[gd_scene load_steps=26 format=2]
|
[gd_scene load_steps=29 format=2]
|
||||||
|
|
||||||
[ext_resource path="res://addons/text_editor/TE_Console.gd" type="Script" id=1]
|
[ext_resource path="res://addons/text_editor/TE_Console.gd" type="Script" id=1]
|
||||||
[ext_resource path="res://addons/text_editor/TE_Editor.gd" type="Script" id=2]
|
[ext_resource path="res://addons/text_editor/TE_Editor.gd" type="Script" id=2]
|
||||||
@ -17,6 +17,9 @@
|
|||||||
[ext_resource path="res://addons/text_editor/TE_Search.gd" type="Script" id=15]
|
[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_MetaTabs.gd" type="Script" id=16]
|
||||||
[ext_resource path="res://addons/text_editor/TE_ScriptInfo.gd" type="Script" id=17]
|
[ext_resource path="res://addons/text_editor/TE_ScriptInfo.gd" type="Script" id=17]
|
||||||
|
[ext_resource path="res://addons/text_editor/TE_FileInfoLabel.gd" type="Script" id=18]
|
||||||
|
[ext_resource path="res://addons/text_editor/TE_RichTextLabel.gd" type="Script" id=19]
|
||||||
|
[ext_resource path="res://addons/text_editor/te_empty_style.tres" type="StyleBox" id=20]
|
||||||
|
|
||||||
[sub_resource type="Theme" id=8]
|
[sub_resource type="Theme" id=8]
|
||||||
|
|
||||||
@ -50,8 +53,13 @@ script = ExtResource( 2 )
|
|||||||
__meta__ = {
|
__meta__ = {
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
p_tab_parent = NodePath("c/div1/div2/c/c/c2/tab_container")
|
||||||
|
p_tab_prefab = NodePath("file_editor")
|
||||||
p_console = NodePath("c/div1/div2/c/c/c/meta_tabs/console")
|
p_console = NodePath("c/div1/div2/c/c/c/meta_tabs/console")
|
||||||
p_progress_bar = NodePath("c/c/c/progress")
|
p_progress_bar = NodePath("c/c/c/progress")
|
||||||
|
p_menu_file = NodePath("c/c/c/file")
|
||||||
|
p_menu_view = NodePath("c/c/c/view")
|
||||||
|
p_menu_insert = NodePath("c/c/c/insert")
|
||||||
|
|
||||||
[node name="file_editor" type="TextEdit" parent="."]
|
[node name="file_editor" type="TextEdit" parent="."]
|
||||||
visible = false
|
visible = false
|
||||||
@ -97,7 +105,7 @@ margin_right = 12.0
|
|||||||
margin_bottom = 24.0
|
margin_bottom = 24.0
|
||||||
text = "⟳"
|
text = "⟳"
|
||||||
|
|
||||||
[node name="file_button" type="MenuButton" parent="c/c/c"]
|
[node name="file" type="MenuButton" parent="c/c/c"]
|
||||||
margin_left = 16.0
|
margin_left = 16.0
|
||||||
margin_right = 48.0
|
margin_right = 48.0
|
||||||
margin_bottom = 24.0
|
margin_bottom = 24.0
|
||||||
@ -107,7 +115,7 @@ __meta__ = {
|
|||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="view_button" type="MenuButton" parent="c/c/c"]
|
[node name="view" type="MenuButton" parent="c/c/c"]
|
||||||
margin_left = 52.0
|
margin_left = 52.0
|
||||||
margin_right = 93.0
|
margin_right = 93.0
|
||||||
margin_bottom = 24.0
|
margin_bottom = 24.0
|
||||||
@ -118,21 +126,32 @@ __meta__ = {
|
|||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="word_wrap" type="CheckBox" parent="c/c/c"]
|
[node name="insert" type="MenuButton" parent="c/c/c"]
|
||||||
margin_left = 97.0
|
margin_left = 97.0
|
||||||
margin_right = 155.0
|
margin_right = 146.0
|
||||||
|
margin_bottom = 24.0
|
||||||
|
focus_mode = 2
|
||||||
|
text = "insert"
|
||||||
|
items = [ "New File", null, 0, false, false, 0, 0, null, "", false, "Extensions", null, 0, false, false, 1, 0, null, "Extensions", false, "New File", null, 0, false, false, 2, 0, null, "", false, "Extensions", null, 0, false, false, 3, 0, null, "Extensions", false ]
|
||||||
|
__meta__ = {
|
||||||
|
"_edit_use_anchors_": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[node name="word_wrap" type="CheckBox" parent="c/c/c"]
|
||||||
|
margin_left = 150.0
|
||||||
|
margin_right = 208.0
|
||||||
margin_bottom = 24.0
|
margin_bottom = 24.0
|
||||||
text = "wrap"
|
text = "wrap"
|
||||||
|
|
||||||
[node name="tab_colors" type="CheckBox" parent="c/c/c"]
|
[node name="tab_colors" type="CheckBox" parent="c/c/c"]
|
||||||
margin_left = 159.0
|
margin_left = 212.0
|
||||||
margin_right = 250.0
|
margin_right = 303.0
|
||||||
margin_bottom = 24.0
|
margin_bottom = 24.0
|
||||||
text = "tab colors"
|
text = "tab colors"
|
||||||
|
|
||||||
[node name="space" type="Control" parent="c/c/c"]
|
[node name="space" type="Control" parent="c/c/c"]
|
||||||
margin_left = 254.0
|
margin_left = 307.0
|
||||||
margin_right = 978.0
|
margin_right = 971.0
|
||||||
margin_bottom = 24.0
|
margin_bottom = 24.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
@ -147,12 +166,12 @@ size_flags_vertical = 3
|
|||||||
|
|
||||||
[node name="version" type="Label" parent="c/c/c"]
|
[node name="version" type="Label" parent="c/c/c"]
|
||||||
modulate = Color( 1, 1, 1, 0.521569 )
|
modulate = Color( 1, 1, 1, 0.521569 )
|
||||||
margin_left = 982.0
|
margin_left = 975.0
|
||||||
margin_top = 3.0
|
margin_top = 3.0
|
||||||
margin_right = 1010.0
|
margin_right = 1010.0
|
||||||
margin_bottom = 20.0
|
margin_bottom = 20.0
|
||||||
custom_fonts/font = ExtResource( 12 )
|
custom_fonts/font = ExtResource( 12 )
|
||||||
text = "v1.9"
|
text = "v1.10"
|
||||||
align = 2
|
align = 2
|
||||||
|
|
||||||
[node name="div1" type="HSplitContainer" parent="c"]
|
[node name="div1" type="HSplitContainer" parent="c"]
|
||||||
@ -192,6 +211,7 @@ margin_right = 192.0
|
|||||||
margin_bottom = 27.0
|
margin_bottom = 27.0
|
||||||
custom_fonts/font = ExtResource( 12 )
|
custom_fonts/font = ExtResource( 12 )
|
||||||
clear_button_enabled = true
|
clear_button_enabled = true
|
||||||
|
placeholder_text = "Filter"
|
||||||
|
|
||||||
[node name="list_files" type="RichTextLabel" parent="c/div1/c2/c/c"]
|
[node name="list_files" type="RichTextLabel" parent="c/div1/c2/c/c"]
|
||||||
margin_top = 31.0
|
margin_top = 31.0
|
||||||
@ -253,10 +273,17 @@ margin_right = 614.0
|
|||||||
margin_bottom = 562.0
|
margin_bottom = 562.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
|
split_offset = 100
|
||||||
|
|
||||||
[node name="tab_container" type="TabContainer" parent="c/div1/div2/c/c"]
|
[node name="c2" type="VBoxContainer" parent="c/div1/div2/c/c"]
|
||||||
margin_right = 614.0
|
margin_right = 614.0
|
||||||
margin_bottom = 275.0
|
margin_bottom = 375.0
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 3
|
||||||
|
|
||||||
|
[node name="tab_container" type="TabContainer" parent="c/div1/div2/c/c/c2"]
|
||||||
|
margin_right = 614.0
|
||||||
|
margin_bottom = 353.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
custom_constants/top_margin = 0
|
custom_constants/top_margin = 0
|
||||||
@ -269,8 +296,62 @@ __meta__ = {
|
|||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[node name="c" type="HBoxContainer" parent="c/div1/div2/c/c/c2"]
|
||||||
|
margin_top = 357.0
|
||||||
|
margin_right = 614.0
|
||||||
|
margin_bottom = 375.0
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
script = ExtResource( 18 )
|
||||||
|
|
||||||
|
[node name="l" type="RichTextLabel" parent="c/div1/div2/c/c/c2/c"]
|
||||||
|
margin_right = 202.0
|
||||||
|
margin_bottom = 18.0
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 3
|
||||||
|
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 )
|
||||||
|
custom_styles/focus = ExtResource( 20 )
|
||||||
|
custom_styles/normal = ExtResource( 20 )
|
||||||
|
bbcode_enabled = true
|
||||||
|
fit_content_height = true
|
||||||
|
script = ExtResource( 19 )
|
||||||
|
|
||||||
|
[node name="m" type="RichTextLabel" parent="c/div1/div2/c/c/c2/c"]
|
||||||
|
margin_left = 206.0
|
||||||
|
margin_right = 408.0
|
||||||
|
margin_bottom = 18.0
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 3
|
||||||
|
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 )
|
||||||
|
custom_styles/focus = ExtResource( 20 )
|
||||||
|
custom_styles/normal = ExtResource( 20 )
|
||||||
|
bbcode_enabled = true
|
||||||
|
fit_content_height = true
|
||||||
|
script = ExtResource( 19 )
|
||||||
|
|
||||||
|
[node name="r" type="RichTextLabel" parent="c/div1/div2/c/c/c2/c"]
|
||||||
|
margin_left = 412.0
|
||||||
|
margin_right = 614.0
|
||||||
|
margin_bottom = 18.0
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 3
|
||||||
|
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 )
|
||||||
|
custom_styles/focus = ExtResource( 20 )
|
||||||
|
custom_styles/normal = ExtResource( 20 )
|
||||||
|
bbcode_enabled = true
|
||||||
|
fit_content_height = true
|
||||||
|
script = ExtResource( 19 )
|
||||||
|
|
||||||
[node name="c" type="Control" parent="c/div1/div2/c/c"]
|
[node name="c" type="Control" parent="c/div1/div2/c/c"]
|
||||||
margin_top = 287.0
|
margin_top = 387.0
|
||||||
margin_right = 614.0
|
margin_right = 614.0
|
||||||
margin_bottom = 562.0
|
margin_bottom = 562.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
@ -287,7 +368,6 @@ __meta__ = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[node name="console" type="RichTextLabel" parent="c/div1/div2/c/c/c/meta_tabs"]
|
[node name="console" type="RichTextLabel" parent="c/div1/div2/c/c/c/meta_tabs"]
|
||||||
visible = false
|
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
margin_left = 4.0
|
margin_left = 4.0
|
||||||
@ -304,11 +384,6 @@ custom_fonts/normal_font = ExtResource( 12 )
|
|||||||
bbcode_enabled = true
|
bbcode_enabled = true
|
||||||
meta_underlined = false
|
meta_underlined = false
|
||||||
text = "active: False
|
text = "active: False
|
||||||
active: False
|
|
||||||
active: False
|
|
||||||
active: False
|
|
||||||
active: False
|
|
||||||
active: False
|
|
||||||
"
|
"
|
||||||
script = ExtResource( 1 )
|
script = ExtResource( 1 )
|
||||||
|
|
||||||
@ -357,7 +432,6 @@ margin_left = 413.0
|
|||||||
margin_right = 504.0
|
margin_right = 504.0
|
||||||
margin_bottom = 27.0
|
margin_bottom = 27.0
|
||||||
custom_fonts/font = ExtResource( 12 )
|
custom_fonts/font = ExtResource( 12 )
|
||||||
pressed = true
|
|
||||||
text = "all files"
|
text = "all files"
|
||||||
|
|
||||||
[node name="case" type="CheckBox" parent="c/div1/div2/c/c/c/meta_tabs/search/c"]
|
[node name="case" type="CheckBox" parent="c/div1/div2/c/c/c/meta_tabs/search/c"]
|
||||||
@ -370,7 +444,7 @@ text = "match case"
|
|||||||
[node name="rte" type="RichTextLabel" parent="c/div1/div2/c/c/c/meta_tabs/search"]
|
[node name="rte" type="RichTextLabel" parent="c/div1/div2/c/c/c/meta_tabs/search"]
|
||||||
margin_top = 31.0
|
margin_top = 31.0
|
||||||
margin_right = 606.0
|
margin_right = 606.0
|
||||||
margin_bottom = 231.0
|
margin_bottom = 139.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
theme = SubResource( 12 )
|
theme = SubResource( 12 )
|
||||||
@ -401,7 +475,7 @@ text = "⟳"
|
|||||||
[node name="sys" type="RichTextLabel" parent="c/div1/div2/c/c/c/meta_tabs/sys"]
|
[node name="sys" type="RichTextLabel" parent="c/div1/div2/c/c/c/meta_tabs/sys"]
|
||||||
margin_top = 27.0
|
margin_top = 27.0
|
||||||
margin_right = 606.0
|
margin_right = 606.0
|
||||||
margin_bottom = 227.0
|
margin_bottom = 239.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
theme = SubResource( 13 )
|
theme = SubResource( 13 )
|
||||||
@ -416,6 +490,7 @@ text = "idwords ⯆unique"
|
|||||||
script = ExtResource( 17 )
|
script = ExtResource( 17 )
|
||||||
|
|
||||||
[node name="image" type="VBoxContainer" parent="c/div1/div2/c/c/c/meta_tabs"]
|
[node name="image" type="VBoxContainer" parent="c/div1/div2/c/c/c/meta_tabs"]
|
||||||
|
visible = false
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
margin_left = 4.0
|
margin_left = 4.0
|
||||||
@ -466,6 +541,7 @@ margin_right = 166.0
|
|||||||
margin_bottom = 27.0
|
margin_bottom = 27.0
|
||||||
custom_fonts/font = ExtResource( 12 )
|
custom_fonts/font = ExtResource( 12 )
|
||||||
clear_button_enabled = true
|
clear_button_enabled = true
|
||||||
|
placeholder_text = "Filter"
|
||||||
|
|
||||||
[node name="list_symbols" type="RichTextLabel" parent="c/div1/div2/c2/c/c/c"]
|
[node name="list_symbols" type="RichTextLabel" parent="c/div1/div2/c2/c/c/c"]
|
||||||
margin_top = 31.0
|
margin_top = 31.0
|
||||||
|
@ -128,9 +128,10 @@ func apply_colors(e:TE_Editor, t:TextEdit):
|
|||||||
var quote:Color = lerp(e.color_text, e.color_symbol, .5)
|
var quote:Color = lerp(e.color_text, e.color_symbol, .5)
|
||||||
|
|
||||||
t.add_color_override("function_color", e.color_text)
|
t.add_color_override("function_color", e.color_text)
|
||||||
|
t.add_color_override("number_color", e.color_text)
|
||||||
|
|
||||||
t.add_keyword_color("true", e.color_var)
|
# t.add_keyword_color("true", e.color_var)
|
||||||
t.add_keyword_color("false", e.color_var)
|
# t.add_keyword_color("false", e.color_var)
|
||||||
|
|
||||||
# bold italic
|
# bold italic
|
||||||
t.add_color_region("***", "***", Color.tomato.darkened(.3), false)
|
t.add_color_region("***", "***", Color.tomato.darkened(.3), false)
|
||||||
@ -148,6 +149,8 @@ func apply_colors(e:TE_Editor, t:TextEdit):
|
|||||||
# non official markdown:
|
# non official markdown:
|
||||||
# formatted
|
# formatted
|
||||||
t.add_color_region("{", "}", lerp(e.color_text, e.color_var, .5).darkened(.25), false)
|
t.add_color_region("{", "}", lerp(e.color_text, e.color_var, .5).darkened(.25), false)
|
||||||
|
# t.add_color_region("[", "]", lerp(e.color_text, e.color_var, .5).darkened(.25), false)
|
||||||
|
# t.add_color_region("(", ")", lerp(e.color_text, e.color_var, .5).darkened(.25), false)
|
||||||
if false:
|
if false:
|
||||||
# quote
|
# quote
|
||||||
t.add_color_region('"', '"', quote, false)
|
t.add_color_region('"', '"', quote, false)
|
||||||
@ -158,14 +161,11 @@ func apply_colors(e:TE_Editor, t:TextEdit):
|
|||||||
t.add_color_region("![", ")", e.color_var.lightened(.5))
|
t.add_color_region("![", ")", e.color_var.lightened(.5))
|
||||||
|
|
||||||
# headings
|
# headings
|
||||||
var head = e.color_symbol
|
for i in range(1, 7):
|
||||||
var tint1 = TE_Util.hue_shift(head, -.33)
|
|
||||||
var tint2 = TE_Util.hue_shift(head, .33)
|
|
||||||
for i in range(1, 6):
|
|
||||||
var h = "#".repeat(i)
|
var h = "#".repeat(i)
|
||||||
t.add_color_region("%s *" % h, "*", tint1, true)
|
t.add_color_region("%s *" % h, "*", e.get_symbol_color(i-1, -.33), true)
|
||||||
t.add_color_region("%s \"" % h, "\"", tint2, true)
|
t.add_color_region("%s \"" % h, "\"", e.get_symbol_color(i-1, .33), true)
|
||||||
t.add_color_region("%s " % h, "*", head, true)
|
t.add_color_region("%s " % h, "*", e.get_symbol_color(i-1), true)
|
||||||
|
|
||||||
# lists
|
# lists
|
||||||
t.add_color_region("- [x", "]", Color.yellowgreen, false)
|
t.add_color_region("- [x", "]", Color.yellowgreen, false)
|
||||||
|
@ -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.9"
|
version="1.10"
|
||||||
script="plugin.gd"
|
script="plugin.gd"
|
||||||
|
3
addons/text_editor/te_empty_style.tres
Normal file
3
addons/text_editor/te_empty_style.tres
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[gd_resource type="StyleBoxEmpty" format=2]
|
||||||
|
|
||||||
|
[resource]
|
Loading…
Reference in New Issue
Block a user