This commit is contained in:
teebarjunk 2021-10-22 23:51:34 -04:00
parent c8ce103df4
commit 96c064c2b9
12 changed files with 209 additions and 39 deletions

View File

@ -1,3 +1,17 @@
# 1.6
- Added `Uppercase` `Lowercase` and `Capitalize` option to popup menu for selected text.
- `ctrl + click` in symbol view selects entire "chapter" and sub "chapters". `ctrl + shift + click` selects only one "chapter".
- `ctrl + click` in editor will auto scroll symbol view.
- Folders can be tinted.
- `word_wrap` state is saved/loaded.
- Fixed error that occured when folder containing binary was moved.
- Markdown can have a `progress` field in meta data which can be sorted in `sys`.
- Markdown meta info taken into account for `sys`
- Markdown meta info colourized.
- Markdown code color based on variable color.
- JSON comments like YAML: `"#": "comment"`
- JSON color tweaks.
# 1.5
- Added `Ctrl + N` to immediately create new file without defining path.
- New unsaved file will have contents remembered.

View File

@ -1,5 +1,5 @@
# Text Editor
Version `1.5`
Version `1.6`
![](README/readme_preview.png)
@ -35,6 +35,11 @@ Version `1.5`
- `ctrl + up` `ctrl + down` Move selected lines
- `ctrl + /` Toggle line comments
- `ctrl + M` Toggle file meta info
- `ctrl + F` Search for text in all files
## Symbol View
- `ctrl + click` Select entire block + children.
- `ctrl + shift + click` Select block without children.
# Symbols and Tags
To make it easier to find stuff there is a *Symbol* viewer.

View File

@ -40,6 +40,8 @@ signal save_files()
signal state_saved()
signal state_loaded()
signal selected_symbol_line(symbol_index)
var plugin = null
var plugin_hint:bool = false
@ -64,7 +66,7 @@ var color_comment:Color = Color.white.darkened(.6)
var color_symbol:Color = Color.deepskyblue
var color_tag:Color = Color.yellow
var color_var:Color = Color.orange
var color_varname:Color = Color.white.darkened(.25)
var color_varname:Color = color_text.darkened(.25)
onready var test_button:Node = $c/c/c/test
onready var tab_parent:TabContainer = $c/div1/div2/c/c/tab_container
@ -198,9 +200,15 @@ func _ready():
set_directory()
func _toggle_word_wrap():
tab_prefab.set_wrap_enabled(word_wrap.pressed)
set_word_wrap(word_wrap.pressed)
func set_word_wrap(ww:bool):
tab_prefab.set_wrap_enabled(ww)
for tab in get_all_tabs():
tab.set_wrap_enabled(word_wrap.pressed)
tab.set_wrap_enabled(ww)
func select_symbol_line(line:int):
emit_signal("selected_symbol_line", line)
func update_checks():
# Directories
@ -223,13 +231,21 @@ func update_checks():
var ext = INTERNAL_EXTENSIONS[i]
var id = i+len(MAIN_EXTENSIONS)+3
func get_localized_path(file_path:String):
assert(file_path.begins_with(current_directory))
return file_path.substr(len(current_directory))
func get_globalized_path(file_path:String):
return current_directory.plus_file(file_path)
func save_state():
var state:Dictionary = {
"save_version": "1",
"font_size": FONT.size,
"font_size_ui": FONT_R.size,
"tabs": {},
"selected": get_selected_file(),
"selected": get_localized_path(get_selected_file()),
"word_wrap": word_wrap.pressed,
"show": show,
"tags": tags,
"tag_counts": tag_counts,
@ -247,20 +263,32 @@ func save_state():
state["window_size"] = [ws.x, ws.y]
for tab in get_all_tabs():
state.tabs[tab.file_path] = tab.get_state()
state.tabs[get_localized_path(tab.file_path)] = tab.get_state()
TE_Util.save_json(PATH_STATE, state)
emit_signal("state_saved")
func _fix_tint(d:Dictionary):
if "tint" in d:
var c = d.tint.split_floats(",")
d.tint = Color(c[0], c[1], c[2], c[3])
func load_state():
var state:Dictionary = TE_Util.load_json(PATH_STATE)
if not state:
return
# word wrap
var ww = state.get("word_wrap", word_wrap)
word_wrap.pressed = ww
set_word_wrap(ww)
var selected
for file_path in state.tabs:
var st = state.tabs[file_path]
file_path = get_globalized_path(file_path)
var tab = _open_file(file_path)
tab.set_state(state.tabs[file_path])
tab.set_state(st)
if file_path == state.selected:
selected = tab
@ -274,6 +302,8 @@ func load_state():
for f in [FONT_R, FONT_B, FONT_I, FONT_BI]:
f.size = font_size_ui
TE_Util.dig(state.file_list, self, "_fix_tint")
_load_property(state, "file_list")
_load_property(state, "tag_counts")
_load_property(state, "tags_enabled")
@ -557,6 +587,9 @@ func get_temporary_tab() -> TextEdit:
return child
return null
func load_file(file_path:String) -> String:
return TE_Util.load_text(file_path)
func save_file(file_path:String, text:String):
var f:File = File.new()
var _err = f.open(file_path, File.WRITE)
@ -702,7 +735,9 @@ func rename_file(old_path:String, new_path:String):
return
if File.new().file_exists(new_path):
push_error("can't rename %s to %s. file already exists." % [old_path, new_path])
var err_msg = "can't rename %s to %s. file already exists." % [old_path, new_path]
push_error(err_msg)
console.err(err_msg)
return
var selected = get_selected_file()
@ -713,7 +748,9 @@ func rename_file(old_path:String, new_path:String):
emit_signal("file_renamed", old_path, new_path)
else:
push_error("couldn't rename %s to %s." % [old_path, new_path])
var err_msg = "couldn't rename %s to %s." % [old_path, new_path]
push_error(err_msg)
console.err(err_msg)
func select_file(file_path:String):
if not File.new().file_exists(file_path):
@ -809,7 +846,9 @@ func _scan_dir(id:String, path:String, dir:Directory, last_dir:Dictionary, old_l
files=a_files,
dirs=a_dirs,
show=true,
open=old_last_dir.get("open", true) }
open=old_last_dir.get("open", true),
tint=old_last_dir.get("tint", Color.white)
}
last_dir[id] = info
var fname = dir.get_next()

View File

@ -9,6 +9,7 @@ var helper:TE_ExtensionHelper
var temporary:bool = false setget set_temporary
var modified:bool = false
var file_path:String = ""
var mouse_inside:bool = false
var symbols:Dictionary = {}
var tags:Dictionary = {}
@ -37,13 +38,23 @@ func _ready():
_e = connect("text_changed", self, "text_changed")
_e = connect("focus_entered", self, "set", ["in_focus", true])
_e = connect("focus_exited", self, "set", ["in_focus", false])
_e = connect("mouse_entered", self, "set", ["mouse_inside", true])
_e = connect("mouse_exited", self, "set", ["mouse_inside", false])
if get_parent() is TabContainer:
get_parent().connect("tab_changed", self, "_tab_changed")
get_parent().connect("tab_selected", self, "_tab_changed")
add_font_override("font", editor.FONT)
get_menu().add_font_override("font", editor.FONT)
var popup = get_menu()
popup.add_font_override("font", editor.FONT)
popup.add_separator()
popup.add_item("Uppercase")
popup.add_item("Lowercase")
popup.add_item("Capitalize")
popup.add_item("Variable")
_e = popup.connect("index_pressed", self, "_popup_menu")
# hint
theme = Theme.new()
@ -51,6 +62,25 @@ func _ready():
TE_Util.dig(self, self, "_node")
func _popup_menu(index:int):
match get_menu().get_item_text(index):
"Uppercase": selection_uppercase()
"Lowercase": selection_lowercase()
"Capitalize": selection_capitalize()
"Variable": selection_variable()
func selection_uppercase():
insert_text_at_cursor(get_selection_text().to_upper())
func selection_lowercase():
insert_text_at_cursor(get_selection_text().to_lower())
func selection_variable():
insert_text_at_cursor(get_selection_text().to_lower().replace(" ", "_"))
func selection_capitalize():
insert_text_at_cursor(get_selection_text().capitalize())
func _node(n):
var _e
if n is HScrollBar:
@ -105,11 +135,23 @@ func _input(e):
if not editor.is_plugin_active():
return
if not visible or not in_focus:
if not visible or not in_focus or not mouse_inside:
return
if e is InputEventMouseButton and not e.pressed and e.control:
var line:String = get_line(cursor_get_line())
# if selecting a symbol, show it in symbol viewer
if cursor_get_line() in symbols:
editor.select_symbol_line(symbols.keys().find(cursor_get_line())-1)
else:
var l = cursor_get_line()
editor.select_symbol_line(0)
for i in len(symbols):
if symbols.keys()[i] > l:
editor.select_symbol_line(max(0, i-2))
break
var ca = line.find("(")
var cb = line.find_last(")")
if ca != -1 and cb != -1:
@ -209,7 +251,6 @@ func _file_selected(p:String):
func goto_line(line:int):
prints("goto ", line)
# force scroll to bottom so selected line will be at top
cursor_set_line(get_line_count())
cursor_set_line(line)
@ -285,7 +326,7 @@ func _popup(msg):
func load_file(path:String):
file_path = path
if path != "":
text = TE_Util.load_text(path)
text = editor.load_file(path)
update_colors()
update_name()
@ -328,8 +369,8 @@ func update_name():
if temporary: n = "?" + n
if modified: n = "*" + n
if len(n) > 9:
n = n.substr(0, 6) + "..."
if len(n) > 12:
n = n.substr(0, 9) + "..."
editor.tab_parent.set_tab_title(get_index(), n)
editor.tab_parent.get_tab_control(get_index()).hint_tooltip = file_path

View File

@ -35,6 +35,12 @@ func _ready():
dir_popup.add_item("New File")
dir_popup.add_separator()
dir_popup.add_item("Remove")
dir_popup.add_separator()
dir_popup.add_item("Tint Yellow")
dir_popup.add_item("Tint Red")
dir_popup.add_item("Tint Blue")
dir_popup.add_item("Tint Green")
dir_popup.add_item("Reset Tint")
_e = dir_popup.connect("index_pressed", self, "_dir_popup")
dir_popup.add_font_override("font", editor.FONT)
@ -52,6 +58,21 @@ func _dir_popup(index:int):
match dir_popup.get_item_text(index):
"New File": editor.popup_create_file(file)
"Remove": editor.recycle(file)
"Tint Yellow":
selected[1].tint = Color.gold
_redraw()
"Tint Red":
selected[1].tint = Color.tomato
_redraw()
"Tint Blue":
selected[1].tint = Color.deepskyblue
_redraw()
"Tint Green":
selected[1].tint = Color.chartreuse
_redraw()
"Reset Tint":
selected[1].tint = Color.white
_redraw()
func _file_popup(index:int):
var type = selected[0]
@ -115,7 +136,7 @@ func _input(e:InputEvent):
if type == "d":
var dir:String = file.file_path
var old_path:String = drag_file
var old_path:String = drag_file.file_path
var new_path:String = dir.plus_file(old_path.get_file())
editor.rename_file(old_path, new_path)
@ -176,7 +197,7 @@ func _draw_dir(dir:Dictionary, deep:int):
var link:String = meta(head, ["d", dir], file)
if file.begins_with(editor.PATH_TRASH) and file.count("/") == 3:
link += " " + meta(clr("", Color.yellowgreen), ["unrecycle", dir], file)
lines.append(clr(link, Color.white.darkened(dimmest)))
lines.append(clr(link, dir.tint.darkened(dimmest)))
var sel = editor.get_selected_tab()
sel = sel.file_path if sel else ""
@ -199,7 +220,7 @@ func _draw_dir(dir:Dictionary, deep:int):
var is_selected = file_path == sel
var is_opened = editor.is_opened(file_path)
var color = Color.white
var color = dir.tint
head = "┣╸" if i != last else "┗╸"
if "readme" in file.to_lower():

View File

@ -33,6 +33,5 @@ func _lost_focus():
func _enter(t:String):
if fr:
print("calling %s with %s" % [fr, t])
fr.call_func(t)
hide()

View File

@ -3,7 +3,7 @@ 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, chaps=false }
var sort_reverse:Dictionary = { id=false, words=false, chaps=false, "%":false }
func _ready():
var btn = get_parent().get_node("update")
@ -32,13 +32,13 @@ func _update():
func _chapter(path:String, line:int, id:String):
if not id:
id = "???"
chapter_info.append({ path=path, line=line, id=id, words=0, chaps=0 })
chapter_info.append({ path=path, line=line, id=id, words=0, chaps=0, "%":0.0 })
func _process_md(path:String):
var lines = TE_Util.load_text(path).split("\n")
var is_entire_file:bool = false
_chapter(path, 0, "NOH")
_chapter(path, 0, "(Noname)")
var i = 0
while i < len(lines):
# skip head meta
@ -46,6 +46,14 @@ func _process_md(path:String):
is_entire_file = true
i += 1
while i < len(lines) and not lines[i].begins_with("---"):
if lines[i].begins_with("name: "):
chapter_info[-1].id = lines[i].split("name: ", true, 1)[1]
elif lines[i].begins_with("progress: "):
chapter_info[-1]["%"] = float(lines[i].split("progress: ", true, 1)[1].replace("%", ""))
elif lines[i].begins_with("prog: "):
chapter_info[-1]["%"] = float(lines[i].split("prog: ", true, 1)[1].replace("%", ""))
i += 1
# skip code blocks
@ -106,7 +114,7 @@ func _redraw():
var c1 = Color.white.darkened(.4)
var c2 = Color.white.darkened(.3)
var cols = ["id", "words", "chaps"]
var cols = ["id", "words", "chaps", "%"]
push_align(RichTextLabel.ALIGN_CENTER)
push_table(len(cols))
for id in cols:
@ -146,6 +154,13 @@ func _redraw():
add_text(TE_Util.commas(item[x]))
pop()
pop()
# percent
push_cell()
push_color(clr)
add_text(str(int(item["%"])))
pop()
pop()
pop()
pop()

View File

@ -8,6 +8,7 @@ func _ready():
_e = editor.connect("symbols_updated", self, "_redraw")
_e = editor.connect("tags_updated", self, "_redraw")
_e = editor.connect("file_selected", self, "_file_selected")
_e = editor.connect("selected_symbol_line", self, "_selected_symbol_line")
_e = get_v_scroll().connect("value_changed", self, "_scrolling")
add_font_override("normal_font", editor.FONT_R)
@ -17,6 +18,10 @@ func _ready():
call_deferred("_redraw")
func _selected_symbol_line(line:int):
# scroll_to_line(get_line_count()-1)
scroll_to_line(line)
func _file_selected(file_path:String):
yield(get_tree(), "idle_frame")
get_v_scroll().value = hscrolls.get(file_path, 0)
@ -26,7 +31,33 @@ func _scrolling(v):
func _clicked(args:Array):
var te:TextEdit = editor.get_selected_tab()
te.goto_line(args[1])
# select entire symbol block?
if Input.is_key_pressed(KEY_CONTROL):
var tab = editor.get_selected_tab()
var symbols = {} if not tab else tab.symbols
var line_index:int = args[1]
var symbol_index:int = symbols.keys().find(line_index)
var next_line:int
# select sub symbol blocks?
if not Input.is_key_pressed(KEY_SHIFT):
var deep = symbols[line_index].deep
while symbol_index < len(symbols)-1 and symbols.values()[symbol_index+1].deep > deep:
symbol_index += 1
if symbol_index == len(symbols)-1:
next_line = tab.get_line_count()-1
else:
next_line = symbols.keys()[symbol_index+1]-1
tab.select(line_index, 0, next_line, len(tab.get_line(next_line)))
te.goto_line(line_index)
else:
te.goto_line(args[1])
func _redraw():
var tab = editor.get_selected_tab()

View File

@ -171,7 +171,7 @@ items = [ "Rename", null, 0, false, false, 0, 0, null, "", false, "", null, 0, f
margin_right = 20.0
margin_bottom = 20.0
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, "", null, 0, false, false, -1, 0, null, "", true, "Remove", null, 0, false, false, 3, 0, null, "", false ]
items = [ "New File", null, 0, false, false, 0, 0, null, "", false, "", null, 0, false, false, -1, 0, null, "", true, "Remove", null, 0, false, false, 2, 0, null, "", false ]
[node name="div2" type="HSplitContainer" parent="c/div1"]
margin_left = 218.0
@ -241,6 +241,7 @@ custom_fonts/normal_font = ExtResource( 12 )
bbcode_enabled = true
meta_underlined = false
text = "active: False
active: False
"
script = ExtResource( 1 )

View File

@ -17,19 +17,18 @@ func get_symbols(t:String):
var deep = max(0, len(lines[i]) - len(lines[i].strip_edges(true, false)) - 1)
last = add_symbol(i, deep, key)
# tags
# elif "/* #" in lines[i]:
# for tag in lines[i].split("/* #", true, 1)[1].split("*/", true, 1)[0].split("#"):
# tag = tag.strip_edges()
# if tag:
# last.tags.append(tag)
elif '"#": "' in lines[i]:
for tag in lines[i].split('"#": "', true, 1)[1].split('"', true, 1)[0].split("#"):
tag = tag.strip_edges()
if tag:
last.tags.append(tag)
elif '"tags": "' in lines[i]:
for tag in lines[i].split('"tags": "', true, 1)[1].split('"', true, 1)[0].split("#"):
tag = tag.strip_edges()
if tag:
last.tags.append(tag)
i += 1
return out
@ -38,12 +37,12 @@ func apply_colors(e:TE_Editor, t:TextEdit):
.apply_colors(e, t)
# vars
t.add_color_region(' "', '"', e.color_var)
t.add_color_region(' "', '"', e.color_varname)
t.add_color_region('"', '"', e.color_varname)
t.add_keyword_color("true", e.color_var)
t.add_keyword_color("false", e.color_var)
t.add_keyword_color("null", e.color_var)
# comments
t.add_color_region("/*", "*/", e.color_comment)
t.add_color_region("//", "", e.color_comment, true)
# t.add_color_region("/*", "*/", e.color_comment)
t.add_color_region('\t"#"', ",", e.color_comment, false)

View File

@ -42,9 +42,10 @@ func apply_colors(e:TE_Editor, t:TextEdit):
t.add_color_region("- [", " ]", e.color_text.darkened(.6), false)
# code blocks
var code:Color = lerp(e.color_text.darkened(.5), Color.yellowgreen, .5)
var code:Color = TE_Util.hue_shift(e.color_var, .33)#.darkened(.25)
t.add_color_region("```", "```", code, false)
t.add_color_region("~~~", "~~~", code, false)
t.add_color_region("---", "---", code, false)
# strikeout
t.add_color_region("~~", "~~", Color.tomato, false)
@ -75,8 +76,12 @@ func get_symbols(t:String) -> Dictionary:
tag = tag.strip_edges()
if tag:
last.tags.append(tag)
# elif "name: " in lines[i]:
# last.name = lines[i].split("name: ", true, 1)[1]
i += 1
i += 1
# i += 1
# symbols
elif lines[i].begins_with("#"):

View File

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