This commit is contained in:
teebarjunk 2021-11-27 05:35:18 -05:00
parent 40beef4690
commit dfe30486d2
15 changed files with 501 additions and 142 deletions

View File

@ -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
- Tag Viewer now shows all tags regardless of whether the file is open or not.
- File View can show symbols. Toggle with `ctrl` click.

View File

@ -1,5 +1,5 @@
# Text Editor
Version `1.9`
Version `1.10`
![](README/readme_preview.png)
@ -9,7 +9,7 @@ Version `1.9`
- Multi file tab system.
- File browser filtering.
- Highlighting for common formats (`md` `json` `ini`...)
- Tag system.
- Tag [System](#mini-features-tags).
- File Management:
- Creation.
- Renaming.
@ -18,13 +18,7 @@ Version `1.9`
- Search files.
- Image previews.
- Auto save/load settings.
- Many little *Ease of Life* functions:
- Comment toggling for:
- `.md`: `<!-- -->`
- `.json`: `/* */`
- `.ini`: `; `
- `.cfg`: `; `
- `.yaml`: `# `
- Many little *Ease of Life* [features](#mini-features).
# Controls
- `ctrl + N` New file.
@ -89,5 +83,68 @@ This will then highlight *Files* and *Symbols* that have that tag.
- [ ] Color themes.
# 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.

View File

@ -1,6 +1,9 @@
tool
extends "res://addons/text_editor/TE_RichTextLabel.gd"
func _ready():
clear()
func msg(msg):
append_bbcode(str(msg))
newline()

View File

@ -83,29 +83,36 @@ var color_tag:Color = Color.yellow
var color_var:Color = Color.orange
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 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_unsaved:ConfirmationDialog = $popup_unsaved
onready var file_dialog:FileDialog = $file_dialog
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 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 file_list:Dictionary = {}
var dir_paths:Array = []
@ -149,7 +156,7 @@ func _ready():
btn.connect("pressed", popup_unsaved, "hide")
TE_Util.dig(popup_unsaved, self, "_apply_fonts")
# menu
# menu: file
menu_file.add_font_override("font", FONT_R)
popup_file = menu_file.get_popup()
popup_file.clear()
@ -159,7 +166,7 @@ func _ready():
popup_file.add_item("Open last closed", 300)
_e = popup_file.connect("index_pressed", self, "_menu_file")
# view
# menu: view
menu_view.add_font_override("font", FONT_R)
popup_view = menu_view.get_popup()
popup_view.clear()
@ -209,6 +216,15 @@ func _ready():
popup_view.add_submenu_item("Files", "Files")
_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
_e = file_dialog.connect("file_selected", self, "_file_dialog_file")
file_dialog.add_font_override("title_font", FONT_R)
@ -232,10 +248,25 @@ func _ready():
file_data.clear()
_scanning = true
_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))
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):
progress_bar.visible = true
progress_bar.value = 0
@ -537,12 +568,34 @@ func _apply_fonts(n:Node):
if n.has_font("font"):
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):
var text = popup_file.get_item_text(index)
match text:
"New File": popup_create_file() # "New File"
"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):
var text = popup_view_dir.get_item_text(index)
match text:
@ -675,6 +728,7 @@ func create_file(file_path:String, text:String=""):
if f.open(file_path, File.WRITE) == OK:
f.store_string(text)
f.close()
update_file_data(file_path)
refresh_files()
if file_dialog.has_meta("callback"):
@ -1025,15 +1079,15 @@ func _can_show_file(fname:String) -> bool:
func get_dir_info(path:String) -> Dictionary:
return TE_Util.dig_for(file_list, "file_path", path)
var all_file_paths:Array = []
func get_all_file_paths():
all_file_paths.clear()
TE_Util.dig(file_list, self, "_get_all_file_paths")
return all_file_paths
func _get_all_file_paths(d:Dictionary):
if "files" in d:
all_file_paths.append_array(d.files)
#var all_file_paths:Array = []
#func get_all_file_paths():
# all_file_paths.clear()
# TE_Util.dig(file_list, self, "_get_all_file_paths")
# return all_file_paths
#
#func _get_all_file_paths(d:Dictionary):
# if "files" in d:
# all_file_paths.append_array(d.files)
func get_file_tint_name(fpath:String) -> String:
var bdir = fpath.get_base_dir()

View File

@ -126,7 +126,7 @@ func selection_lowercase():
func selection_variable():
_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()
func selection_capitalize():
@ -134,6 +134,8 @@ func selection_capitalize():
insert_text_at_cursor(get_selection_text().capitalize())
_remake_selection()
func _node(n):
var _e
if n is HScrollBar:
@ -188,20 +190,27 @@ func _update_selected_line():
var l = cursor_get_line()
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):
var sindex = clamp(i, 0, len(symbols))
var symbol = symbols.values()[sindex]
while len(depth) <= symbol.deep:
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:
editor.select_symbol_line(sindex)
if i == len(symbols)-1 or symbols.keys()[i+1] > line:
depth.resize(symbol.deep+1)
hint_tooltip = "[%s]\n%s" % [editor.get_localized_path(file_path), depth.join("\n")]
break
return depth
func _input(e):
if not editor.is_plugin_active():
@ -272,10 +281,29 @@ func _input(e):
select(f+1, 0, t+1, len(get_line(t+1)))
cursor_set_line(cursor_get_line()+1, false)
if e.scancode == KEY_U: selection_uppercase()
if e.scancode == KEY_L: selection_lowercase()
if e.scancode == KEY_O: selection_capitalize()
if e.scancode == KEY_P: selection_variable()
if e.scancode == KEY_U:
if get_selection_text() == get_selection_text().to_upper():
selection_lowercase()
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):
if not visible:
@ -328,9 +356,10 @@ func goto_symbol(index:int):
if syms and index >= 0 and index < len(syms):
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
cursor_set_line(get_line_count())
if bottom:
cursor_set_line(get_line_count())
cursor_set_line(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_title(get_index(), n)
editor.tab_parent.get_tab_control(get_index()).hint_tooltip = file_path
func update_heading():
if Engine.editor_hint:

View 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]

View File

@ -319,7 +319,7 @@ func _draw_dir(dir:Dictionary, deep:int):
var sname = sdata.name
if filter and not filter in sname.to_lower():
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
symbol_lines.append(meta(space + s, ["fs", file_path, j], h))

View File

@ -13,12 +13,26 @@ 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:
get_parent().visible = not get_parent().visible
get_tree().set_input_as_handled()
if e.control and e.pressed:
match e.scancode:
# show this menu
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):
get_parent().visible = true
current_tab = $image.get_index()
select_tab($image)
$image/image.texture = TE_Util.load_image(file_path)

View File

@ -17,20 +17,10 @@ func _ready():
all_toggle.add_font_override("font", editor.FONT_R)
case_toggle.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()
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 select():
line_edit.grab_focus()
line_edit.grab_click_focus()
line_edit.select_all()
func _clicked(args):
match args[0]:
@ -39,12 +29,16 @@ func _clicked(args):
editor.select_file(args[1])
yield(get_tree(), "idle_frame")
# goto line
var line = int(args[2])
tab.goto_line(line)
var hfrom = int(args[2])
var line = int(args[3])
tab.goto_line(hfrom)
tab.goto_line(line, false)
# select area
var from = int(args[3])
var lenn = int(args[4])
var from = int(args[4])
var lenn = int(args[5])
tab.select(line, from, line, from + lenn)
tab.cursor_set_line(line)
tab.cursor_set_column(from)
func _text_entered(search_for:String):
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)
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 got_lines = result[0]
var line_index = result[1]
var char_index = result[2]
var highlight_from = result[1]
var line_index = result[2]
var char_index = result[3]
if j != 0:
bbcode.append("\t" + clr("...", Color.gray))
bbcode.append(clr(" %s/%s" % [j+1, len(all_found)], Color.orange))
for i in len(got_lines):
l = ""
var highlight = got_lines[i][0]
var lindex = got_lines[i][1]
var ltext = got_lines[i][2]
if i == 2:
var line:String = got_lines[i]
if highlight:
var line:String = ltext
var head:String = line.substr(0, char_index)
var midd:String = line.substr(char_index, len(search_for))
var tail:String = line.substr(char_index+len(search_for))
head = clr(head, Color.deepskyblue.lightened(.5))
midd = clr(midd, Color.deepskyblue.darkened(.25))
tail = clr(tail, Color.deepskyblue.lightened(.5))
l = "\t" + clr(str(line_index-2+i+1) + ": ", Color.deepskyblue.lightened(.5)) + (head+midd+tail)
head = clr(head, Color.white.darkened(.25))
midd = b(clr(midd, Color.white))
tail = clr(tail, Color.white.darkened(.25))
l = "\t" + clr(str(lindex) + ": ", Color.white.darkened(.25)) + (head+midd+tail)
elif line_index-2+i >= 0:
l = "\t" + clr(str(line_index-2+i+1) + ": ", Color.gray) + got_lines[i]
else:
l = "\t" + clr(str(lindex) + ": ", Color.white.darkened(.65)) + clr(ltext, Color.white.darkened(.5))
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)
set_bbcode(bbcode.join("\n"))
@ -120,7 +118,7 @@ func _search(search_for:String) -> Dictionary:
else:
paths = [sel]
for path in paths:
var lines = TE_Util.load_text(path).split("\n")
for line_index in len(lines):
@ -136,17 +134,25 @@ func _search(search_for:String) -> Dictionary:
if not path in out:
out[path] = []
var preview_lines = PoolStringArray()
var preview_lines = [[true, line_index, lines[line_index]]]
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("")
# previous few lines before a blank
for i in range(1, 3):
if line_index-i >= 0:
if not lines[line_index-i].strip_edges():
break
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
out[path].append([preview_lines, line_index, char_index])
out[path].append([preview_lines, highlight_from, line_index, char_index])
return out

View File

@ -120,19 +120,18 @@ func _redraw():
if filter and not filter in symbol_info.name.to_lower():
continue
if deep == 0:
cl = editor.color_symbol
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('"'):
cl = TE_Util.hue_shift(cl, .33)
if symbol_info.name.begins_with("*") and symbol_info.name.ends_with("*"):
cl = editor.get_symbol_color(deep, -.33)
elif symbol_info.name.begins_with('"') and symbol_info.name.ends_with('"'):
cl = editor.get_symbol_color(deep, .33)
else:
cl = editor.get_symbol_color(deep)
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(", ")
var text = clr(meta(space + symbol_info.name, [symbol_info, line_index], tags), cl)
if i == selected_line:

View File

@ -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_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
for sentence in text.split("."):
for word in sentence.split(" "):
word = _sanitize_word(word)
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
word_count += 1
@ -69,6 +69,9 @@ static func _sanitize_word(word:String):
return out
static func to_var(s:String) -> String:
return s.to_lower().replace(" ", "_")
static func load_text(path:String) -> String:
var f:File = File.new()
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:
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):
# return Dict.new(d).sort(reverse)
#

View File

@ -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_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_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_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]
@ -50,8 +53,13 @@ script = ExtResource( 2 )
__meta__ = {
"_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_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="."]
visible = false
@ -97,7 +105,7 @@ margin_right = 12.0
margin_bottom = 24.0
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_right = 48.0
margin_bottom = 24.0
@ -107,7 +115,7 @@ __meta__ = {
"_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_right = 93.0
margin_bottom = 24.0
@ -118,21 +126,32 @@ __meta__ = {
"_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_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
text = "wrap"
[node name="tab_colors" type="CheckBox" parent="c/c/c"]
margin_left = 159.0
margin_right = 250.0
margin_left = 212.0
margin_right = 303.0
margin_bottom = 24.0
text = "tab colors"
[node name="space" type="Control" parent="c/c/c"]
margin_left = 254.0
margin_right = 978.0
margin_left = 307.0
margin_right = 971.0
margin_bottom = 24.0
size_flags_horizontal = 3
size_flags_vertical = 3
@ -147,12 +166,12 @@ size_flags_vertical = 3
[node name="version" type="Label" parent="c/c/c"]
modulate = Color( 1, 1, 1, 0.521569 )
margin_left = 982.0
margin_left = 975.0
margin_top = 3.0
margin_right = 1010.0
margin_bottom = 20.0
custom_fonts/font = ExtResource( 12 )
text = "v1.9"
text = "v1.10"
align = 2
[node name="div1" type="HSplitContainer" parent="c"]
@ -192,6 +211,7 @@ margin_right = 192.0
margin_bottom = 27.0
custom_fonts/font = ExtResource( 12 )
clear_button_enabled = true
placeholder_text = "Filter"
[node name="list_files" type="RichTextLabel" parent="c/div1/c2/c/c"]
margin_top = 31.0
@ -253,10 +273,17 @@ margin_right = 614.0
margin_bottom = 562.0
size_flags_horizontal = 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_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_vertical = 3
custom_constants/top_margin = 0
@ -269,8 +296,62 @@ __meta__ = {
"_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"]
margin_top = 287.0
margin_top = 387.0
margin_right = 614.0
margin_bottom = 562.0
size_flags_horizontal = 3
@ -287,7 +368,6 @@ __meta__ = {
}
[node name="console" type="RichTextLabel" parent="c/div1/div2/c/c/c/meta_tabs"]
visible = false
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 4.0
@ -304,11 +384,6 @@ custom_fonts/normal_font = ExtResource( 12 )
bbcode_enabled = true
meta_underlined = false
text = "active: False
active: False
active: False
active: False
active: False
active: False
"
script = ExtResource( 1 )
@ -357,7 +432,6 @@ margin_left = 413.0
margin_right = 504.0
margin_bottom = 27.0
custom_fonts/font = ExtResource( 12 )
pressed = true
text = "all files"
[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"]
margin_top = 31.0
margin_right = 606.0
margin_bottom = 231.0
margin_bottom = 139.0
size_flags_horizontal = 3
size_flags_vertical = 3
theme = SubResource( 12 )
@ -401,7 +475,7 @@ text = "⟳"
[node name="sys" type="RichTextLabel" parent="c/div1/div2/c/c/c/meta_tabs/sys"]
margin_top = 27.0
margin_right = 606.0
margin_bottom = 227.0
margin_bottom = 239.0
size_flags_horizontal = 3
size_flags_vertical = 3
theme = SubResource( 13 )
@ -416,6 +490,7 @@ text = "idwords ⯆unique"
script = ExtResource( 17 )
[node name="image" type="VBoxContainer" parent="c/div1/div2/c/c/c/meta_tabs"]
visible = false
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 4.0
@ -466,6 +541,7 @@ margin_right = 166.0
margin_bottom = 27.0
custom_fonts/font = ExtResource( 12 )
clear_button_enabled = true
placeholder_text = "Filter"
[node name="list_symbols" type="RichTextLabel" parent="c/div1/div2/c2/c/c/c"]
margin_top = 31.0

View File

@ -128,9 +128,10 @@ func apply_colors(e:TE_Editor, t:TextEdit):
var quote:Color = lerp(e.color_text, e.color_symbol, .5)
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("false", e.color_var)
# t.add_keyword_color("true", e.color_var)
# t.add_keyword_color("false", e.color_var)
# bold italic
t.add_color_region("***", "***", Color.tomato.darkened(.3), false)
@ -148,6 +149,8 @@ func apply_colors(e:TE_Editor, t:TextEdit):
# non official markdown:
# 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)
if false:
# quote
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))
# headings
var head = e.color_symbol
var tint1 = TE_Util.hue_shift(head, -.33)
var tint2 = TE_Util.hue_shift(head, .33)
for i in range(1, 6):
for i in range(1, 7):
var h = "#".repeat(i)
t.add_color_region("%s *" % h, "*", tint1, true)
t.add_color_region("%s \"" % h, "\"", tint2, true)
t.add_color_region("%s " % h, "*", head, true)
t.add_color_region("%s *" % h, "*", e.get_symbol_color(i-1, -.33), true)
t.add_color_region("%s \"" % h, "\"", e.get_symbol_color(i-1, .33), true)
t.add_color_region("%s " % h, "*", e.get_symbol_color(i-1), true)
# lists
t.add_color_region("- [x", "]", Color.yellowgreen, false)

View File

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

View File

@ -0,0 +1,3 @@
[gd_resource type="StyleBoxEmpty" format=2]
[resource]