Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
25d4f161cf | ||
|
4225903a92 | ||
|
dfe30486d2 | ||
|
40beef4690 | ||
|
498fb79e89 | ||
|
baeeb0a808 | ||
|
06e8d176c4 | ||
|
4f09def7ef | ||
|
96c064c2b9 | ||
|
c8ce103df4 | ||
|
5bcd5a47b0 | ||
|
f2ae9db115 |
1
.gitignore
vendored
@ -16,3 +16,4 @@ test_files/
|
|||||||
.trash/
|
.trash/
|
||||||
.trash.json
|
.trash.json
|
||||||
.text_editor_state.json
|
.text_editor_state.json
|
||||||
|
word_skip_list.txt
|
||||||
|
116
CHANGES.md
@ -1,3 +1,119 @@
|
|||||||
|
# 1.12
|
||||||
|
- Changed icon.
|
||||||
|
- Added tabs popup menu:
|
||||||
|
- Options for closing many tabs.
|
||||||
|
- Options for selecting tabs.
|
||||||
|
- Console is hidden on start.
|
||||||
|
- Fixed `yaml` tabs not working.
|
||||||
|
- Fixed `tab` + `shift + tab`ing when multiple lines are selected.
|
||||||
|
|
||||||
|
# 1.11
|
||||||
|
- Toggled `Low Processor Mode` to keep cpu/gpu usage down.
|
||||||
|
- Simplified *File List* filter display.
|
||||||
|
- *File List* filter now scans closed folders as well.
|
||||||
|
- Folder icon in *File List* changes when open/closed.
|
||||||
|
- *File Editor* now saves states of:
|
||||||
|
- Cursor position.
|
||||||
|
- Selection.
|
||||||
|
- Scroll position.
|
||||||
|
- Enabled hiding in *File Editor*.
|
||||||
|
- *Tag List* tags are sorted.
|
||||||
|
- Added `.rpy` *Renpy* file support.
|
||||||
|
- Added tab/spaces toggle.
|
||||||
|
- Fixed files with `.` in their name not showing up.
|
||||||
|
- Fixed error caused by clicking *File List* symbol for unopened file.
|
||||||
|
|
||||||
|
# 1.10
|
||||||
|
- Added cursor panel at bottom of Text Editor.
|
||||||
|
- Word counter.
|
||||||
|
- 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.
|
||||||
|
- File View filter will scan symbols as well.
|
||||||
|
- File List dims characters `0123456789-_`.
|
||||||
|
- Image Preview on `ctrl + click` in Markdown: `` will display `"res://icon.png"`
|
||||||
|
- Tab title ignores leading numbers: "001_character" = "character"
|
||||||
|
- Directories are highlighted if they have a file with a selected tag.
|
||||||
|
- Holding `ctrl` while selecting a tag allows multiple to be selected.
|
||||||
|
- Added tab icon based on folder color.
|
||||||
|
- Fixed Markdown symbol generator including `#` inside code.
|
||||||
|
- Fixed meta container resizing.
|
||||||
|
|
||||||
|
# 1.8
|
||||||
|
- Added filter to symbols list.
|
||||||
|
- Added filter to file list.
|
||||||
|
- Added `.md` highlighting for `{}`. (Not official Markdown.)
|
||||||
|
- Fixed unsaved files asking for a save path if no text entered.
|
||||||
|
- Fixed file wiping if hitting undo after loading a file.
|
||||||
|
- Fixed *no word_skip_list.txt* error.
|
||||||
|
- Folders colorized in file list.
|
||||||
|
- Display version at top right.
|
||||||
|
|
||||||
|
# 1.7
|
||||||
|
- Added option to view `Extensionless` files.
|
||||||
|
- Added Symbol path heirarchy to hint popup so you know where you are in big files:
|
||||||
|

|
||||||
|
- `ctrl + shift +`
|
||||||
|
- `U` Make selection uppercase.
|
||||||
|
- `L` Make selection lowercase.
|
||||||
|
- `O` Make selection capitalized.
|
||||||
|
- `P` Make selection variable: `My text -> my_text`
|
||||||
|
- Select file shorctut:
|
||||||
|
- `ctrl + shift + 0-9` Remember file.
|
||||||
|
- `ctrl + 0-9` Swap to file.
|
||||||
|
- Selected Symbol is now highlighted.
|
||||||
|
- Improved meta data for `.md` files.
|
||||||
|
- `search` will autoselect term when clicked.
|
||||||
|
- `search` `all` toggle added to allow only searching in the selected file.
|
||||||
|
- `search` `case` toggle added to allow searching based on upper/lower case.
|
||||||
|
- `sys` panel shows unique word list.
|
||||||
|
- `sys` panel shows time since modified.
|
||||||
|
- Can create a `word_skip_list.txt` in main folder for ignoring certain words from showing in `sys` word list.
|
||||||
|
- File List panel hint paths are localized.
|
||||||
|
- Removed `.md` function color.
|
||||||
|
- Fixed `trash` not working in exported binaries.
|
||||||
|
- Fixed dragging files into directory bug.
|
||||||
|
- Fixed temporary files not closing properly.
|
||||||
|
- Fixed close non existing tab bug.
|
||||||
|
- Fixed symbol list not redrawing after file closed.
|
||||||
|
- Fixed symbol list not redrawing after file type changed.
|
||||||
|
- Fixed focus not being grabbed when tab selected.
|
||||||
|
|
||||||
|
# 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.
|
||||||
|
- Added `Ctrl + Shift + Mouse wheel` to change ui font size.
|
||||||
|
- Added word wrap toggle.
|
||||||
|
- Fixed sorting error in `sys`.
|
||||||
|
- Fixed font size save/load.
|
||||||
|
- `sys` shows chapter count.
|
||||||
|
- Preserves symbol view scroll value when tabbing.
|
||||||
|
- Can access full filesystem.
|
||||||
|
- Fixed "New File" dialog not gaining focus.
|
||||||
|
|
||||||
# 1.4
|
# 1.4
|
||||||
- Added `sys` info tab.
|
- Added `sys` info tab.
|
||||||
- Added `console` info tab. (wip)
|
- Added `console` info tab. (wip)
|
||||||
|
145
README.md
@ -1,48 +1,62 @@
|
|||||||
# Text Editor
|
# Text Editor
|
||||||
Version `1.4`
|
Version `1.12`
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
***Warning: Use at your own risk. Backup your files before testing.***
|
***Warning: Use at your own risk. Backup your files before testing.***
|
||||||
|
|
||||||
# Features
|
# Features
|
||||||
- Tabs with scroll
|
- Multi file tab system.
|
||||||
- File filtering
|
- File browser filtering.
|
||||||
- Highlighting for common file formats (`md` `json`...)
|
- Highlighting for common formats (`md` `json` `ini`...)
|
||||||
- Tag filtering system
|
- Tag [System](#mini-features-tags).
|
||||||
- File Management:
|
- File Management:
|
||||||
- Creation
|
- Creation.
|
||||||
- Renaming
|
- Renaming.
|
||||||
- Recycling
|
- Recycling.
|
||||||
- Auto save/load settings
|
- Moving.
|
||||||
- Many little *Ease of life* functions:
|
- Search files.
|
||||||
- Folder open/close
|
- Image previews.
|
||||||
- Comment toggling for:
|
- Auto save/load settings.
|
||||||
- `.md`: `<!-- -->`
|
- Many little *Ease of Life* [features](#mini-features).
|
||||||
- `.json`: `/* */`
|
|
||||||
- `.ini`: `; `
|
|
||||||
- `.cfg`: `; `
|
|
||||||
- `.yaml`: `# `
|
|
||||||
|
|
||||||
# Controls
|
# Controls
|
||||||
- `ctrl + W` Close file
|
- `ctrl + N` New file.
|
||||||
- `ctrl + shift + W` Open last closed file
|
- `ctrl + W` Close file.
|
||||||
- `ctrl + tab` Select next open file
|
- `ctrl + shift + W` Open last closed file .
|
||||||
- `ctrl + shift + tab` Select last open file
|
- `ctrl + tab` Select next open file.
|
||||||
- `ctrl + mouse wheel` Adjust font size
|
- `ctrl + shift + tab` Select last open file.
|
||||||
- `ctrl + up` `ctrl + down` Move selected lines
|
- `ctrl + mouse wheel` Adjust font size.
|
||||||
- `ctrl + /` Toggle line comments
|
- `ctrl + shift + mouse wheel` Adjust ui font size.
|
||||||
- `ctrl + M` Toggle file meta info
|
- `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.
|
||||||
|
- `ctrl + shift + 0-9` Create hotkey for selected file.
|
||||||
|
- `ctrl + 0-9` Load hotkeyed file.
|
||||||
|
|
||||||
|
## Symbol View
|
||||||
|
- `ctrl + click` Select entire block + children.
|
||||||
|
- `ctrl + shift + click` Select block without children.
|
||||||
|
|
||||||
|
## Editor View
|
||||||
|
- `ctrl + click` anywhere: Scroll to nearest symbol in symbol view.
|
||||||
|
- `ctrl + click` inside brackets: Goto local file.
|
||||||
|
- `ctrl + shift +`
|
||||||
|
- `U` Make selection uppercase.
|
||||||
|
- `L` Make selection lowercase.
|
||||||
|
- `O` Make selection capitalized.
|
||||||
|
- `P` Make selection variable: `My text -> my_text`
|
||||||
|
|
||||||
# Symbols and Tags
|
# Symbols and Tags
|
||||||
To make it easier to find stuff there is a *Symbol* viewer.
|
*Symbols* are like *Table of Contents* for a file.
|
||||||
|
|
||||||
- `Markdown` uses headings `# Heading`
|
- `Markdown` uses headings `# Heading`
|
||||||
- `JSON` uses Dictionaries `"object": {`
|
- `JSON` uses Dictionaries `"object": {`
|
||||||
- `YAML` uses Dictionaries `object: `
|
- `YAML` uses Dictionaries `object: `
|
||||||
- `ini` `cfg` use headings `[heading]`
|
- `ini` `cfg` use headings `[heading]`
|
||||||
|
|
||||||
Symbols can have tags. Tags are added with comments.
|
Symbols can have *Tags*. Tags are added with comments.
|
||||||
|
|
||||||
- `Markdown` uses `<!-- #tag1 #tag2 -->`
|
- `Markdown` uses `<!-- #tag1 #tag2 -->`
|
||||||
- `JSON` uses `"#": "#tag1 #tag2"`
|
- `JSON` uses `"#": "#tag1 #tag2"`
|
||||||
@ -59,10 +73,81 @@ This will then highlight *Files* and *Symbols* that have that tag.
|
|||||||
# Todo
|
# Todo
|
||||||
- [x] `1.1` Preserve folders open/close state.
|
- [x] `1.1` Preserve folders open/close state.
|
||||||
- [x] `1.3` Search all files.
|
- [x] `1.3` Search all files.
|
||||||
- [ ] Search file.
|
- [x] `1.7` Search file.
|
||||||
- [ ] Find and replace.
|
- [ ] Find and replace.
|
||||||
- [ ] Improve meta data based on format.
|
- [x] `1.7` Improve meta data based on format.
|
||||||
- [x] `1.2` Recycle folders.
|
- [x] `1.2` Recycle folders.
|
||||||
- [x] `1.2` Unrecylce. (Toggle `view/directories/.trash` and press green arrow.
|
- [x] `1.2` Unrecylce. (Toggle `view/directories/.trash` and press green arrow.)
|
||||||
- [ ] JSON formatting.
|
- [ ] JSON formatting.
|
||||||
- [ ] JSON error testing.
|
- [ ] JSON error testing.
|
||||||
|
- [ ] Color themes.
|
||||||
|
|
||||||
|
# Mini features
|
||||||
|
|
||||||
|
## 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: `` in Markdown.
|
||||||
|
|
||||||
|
# Icon credit
|
||||||
|
<a href="https://www.flaticon.com/free-icons/files-and-folders" title="files and folders icons">Files and folders icons created by Uniconlabs - Flaticon</a>
|
BIN
README/changes_hint_toc.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
README/icon.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 121 KiB After Width: | Height: | Size: 97 KiB |
@ -1,5 +1,9 @@
|
|||||||
|
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()
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
tool
|
tool
|
||||||
extends RichTextLabel
|
extends RichTextLabel
|
||||||
|
|
||||||
var editor:TE_TextEditor
|
var editor:TE_Editor
|
||||||
var click_pos:Vector2
|
var click_pos:Vector2
|
||||||
|
|
||||||
func _init(text):
|
func _init(text):
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
tool
|
tool
|
||||||
extends TextEdit
|
extends TextEdit
|
||||||
|
|
||||||
var editor:TE_TextEditor
|
var editor:TE_Editor
|
||||||
var _hscroll:HScrollBar
|
var _hscroll:HScrollBar
|
||||||
var _vscroll:VScrollBar
|
var _vscroll:VScrollBar
|
||||||
|
|
||||||
@ -9,6 +9,7 @@ var helper:TE_ExtensionHelper
|
|||||||
var temporary:bool = false setget set_temporary
|
var temporary:bool = false setget set_temporary
|
||||||
var modified:bool = false
|
var modified:bool = false
|
||||||
var file_path:String = ""
|
var file_path:String = ""
|
||||||
|
var mouse_inside:bool = false
|
||||||
|
|
||||||
var symbols:Dictionary = {}
|
var symbols:Dictionary = {}
|
||||||
var tags:Dictionary = {}
|
var tags:Dictionary = {}
|
||||||
@ -17,30 +18,130 @@ var last_shift:bool
|
|||||||
var last_selected:bool
|
var last_selected:bool
|
||||||
var last_selection:Array = [0, 0, 0, 0]
|
var last_selection:Array = [0, 0, 0, 0]
|
||||||
|
|
||||||
|
var color:String = ""
|
||||||
|
|
||||||
var hscroll:int = 0
|
var hscroll:int = 0
|
||||||
var vscroll:int = 0
|
var vscroll:int = 0
|
||||||
var in_focus:bool = false
|
var in_focus:bool = false
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
|
# prefab?
|
||||||
|
if name == "file_editor":
|
||||||
|
set_process(false)
|
||||||
|
set_process_input(false)
|
||||||
|
return
|
||||||
|
|
||||||
var _e
|
var _e
|
||||||
if not editor:
|
if not editor:
|
||||||
editor = owner
|
editor = owner
|
||||||
_e = editor.connect("save_files", self, "save_file")
|
_e = editor.connect("save_files", self, "save_file")
|
||||||
_e = editor.connect("file_selected", self, "_file_selected")
|
_e = editor.connect("file_selected", self, "_file_selected")
|
||||||
_e = editor.connect("file_renamed", self, "_file_renamed")
|
_e = editor.connect("file_renamed", self, "_file_renamed")
|
||||||
|
_e = editor.connect("dir_tint_changed", self, "_dir_tint_changed")
|
||||||
_e = connect("text_changed", self, "text_changed")
|
_e = connect("text_changed", self, "text_changed")
|
||||||
_e = connect("focus_entered", self, "set", ["in_focus", true])
|
_e = connect("focus_entered", self, "_focus_entered")
|
||||||
_e = connect("focus_exited", self, "set", ["in_focus", false])
|
_e = connect("focus_exited", self, "_focus_exited")
|
||||||
|
_e = connect("mouse_entered", self, "set", ["mouse_inside", true])
|
||||||
|
_e = connect("mouse_exited", self, "set", ["mouse_inside", false])
|
||||||
|
# _e = connect("cursor_changed", self, "_cursor_changed")
|
||||||
|
|
||||||
if get_parent() is TabContainer:
|
# if get_parent() is TabContainer:
|
||||||
get_parent().connect("tab_changed", self, "_tab_changed")
|
# get_parent().connect("tab_changed", self, "_tab_changed")
|
||||||
get_parent().connect("tab_selected", self, "_tab_changed")
|
# get_parent().connect("tab_selected", self, "_tab_changed")
|
||||||
|
|
||||||
add_font_override("font", editor.FONT)
|
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", 1000)
|
||||||
|
# var sc = ShortCut.new()
|
||||||
|
# sc.shortcut = InputEventKey.new()
|
||||||
|
# sc.shortcut.shift = true
|
||||||
|
# sc.shortcut.control = true
|
||||||
|
# sc.shortcut.scancode = KEY_U
|
||||||
|
# popup.add_item_shortcut(sc, 1000)
|
||||||
|
popup.add_item("Lowercase")
|
||||||
|
popup.add_item("Capitalize")
|
||||||
|
popup.add_item("Variable")
|
||||||
|
|
||||||
|
# popup.add_shortcut()
|
||||||
|
_e = popup.connect("index_pressed", self, "_popup_menu")
|
||||||
|
|
||||||
|
# hint
|
||||||
|
theme = Theme.new()
|
||||||
|
theme.set_font("font", "TooltipLabel", editor.FONT_R)
|
||||||
|
# var sb = StyleBoxFlat.new()
|
||||||
|
# sb.bg_color.a = .75
|
||||||
|
# theme.set_color("font_color", "TooltipLabel", Color(0,0,0,.5))
|
||||||
|
# theme.set_stylebox("panel", "TooltipPanel", sb)
|
||||||
|
# print(theme.get_color_list("TooltipLabel"))
|
||||||
|
# print(theme.get_color_types())
|
||||||
|
|
||||||
TE_Util.dig(self, self, "_node")
|
TE_Util.dig(self, self, "_node")
|
||||||
|
|
||||||
|
func set_visible(v):
|
||||||
|
prints(file_path, v)
|
||||||
|
.set_visible(v)
|
||||||
|
|
||||||
|
func _focus_entered():
|
||||||
|
if not in_focus:
|
||||||
|
in_focus = true
|
||||||
|
|
||||||
|
func _focus_exited():
|
||||||
|
if in_focus:
|
||||||
|
in_focus = false
|
||||||
|
|
||||||
|
func set_cursor_state(s:Array):
|
||||||
|
cursor_set_line(s[0], s[1])
|
||||||
|
if len(s) > 2:
|
||||||
|
select(s[2], s[3], s[4], s[5])
|
||||||
|
|
||||||
|
func get_cursor_state() -> Array:
|
||||||
|
if is_selection_active():
|
||||||
|
return [
|
||||||
|
cursor_get_line(),
|
||||||
|
cursor_get_column(),
|
||||||
|
get_selection_from_line(),
|
||||||
|
get_selection_from_column(),
|
||||||
|
get_selection_to_line(),
|
||||||
|
get_selection_to_column()]
|
||||||
|
else:
|
||||||
|
return [
|
||||||
|
cursor_get_line(),
|
||||||
|
cursor_get_column()]
|
||||||
|
|
||||||
|
func _dir_tint_changed(dir:String):
|
||||||
|
if file_path.get_base_dir() == dir:
|
||||||
|
update_name()
|
||||||
|
|
||||||
|
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():
|
||||||
|
var s = get_cursor_state()
|
||||||
|
insert_text_at_cursor(get_selection_text().to_upper())
|
||||||
|
set_cursor_state(s)
|
||||||
|
|
||||||
|
func selection_lowercase():
|
||||||
|
var s = get_cursor_state()
|
||||||
|
insert_text_at_cursor(get_selection_text().to_lower())
|
||||||
|
set_cursor_state(s)
|
||||||
|
|
||||||
|
func selection_variable():
|
||||||
|
var s = get_cursor_state()
|
||||||
|
insert_text_at_cursor(TE_Util.to_var(get_selection_text()))
|
||||||
|
set_cursor_state(s)
|
||||||
|
|
||||||
|
func selection_capitalize():
|
||||||
|
var s = get_cursor_state()
|
||||||
|
insert_text_at_cursor(get_selection_text().capitalize())
|
||||||
|
set_cursor_state(s)
|
||||||
|
|
||||||
func _node(n):
|
func _node(n):
|
||||||
var _e
|
var _e
|
||||||
if n is HScrollBar:
|
if n is HScrollBar:
|
||||||
@ -56,43 +157,96 @@ func _scroll_h(h:HScrollBar):
|
|||||||
func _scroll_v(v:VScrollBar):
|
func _scroll_v(v:VScrollBar):
|
||||||
vscroll = v.value
|
vscroll = v.value
|
||||||
|
|
||||||
func _tab_changed(index:int):
|
|
||||||
var myindex = get_index()
|
|
||||||
if index == myindex and visible:
|
|
||||||
grab_focus()
|
|
||||||
grab_click_focus()
|
|
||||||
yield(get_tree(), "idle_frame")
|
|
||||||
set_h_scroll(hscroll)
|
|
||||||
set_v_scroll(vscroll)
|
|
||||||
|
|
||||||
func get_state() -> Dictionary:
|
func get_state() -> Dictionary:
|
||||||
return {
|
var state = {
|
||||||
hscroll=scroll_horizontal,
|
hscroll=scroll_horizontal,
|
||||||
vscroll=scroll_vertical
|
vscroll=scroll_vertical,
|
||||||
|
cursor=get_cursor_state()
|
||||||
}
|
}
|
||||||
|
# unsaved
|
||||||
|
if file_path == "":
|
||||||
|
state.text = text
|
||||||
|
return state
|
||||||
|
|
||||||
func set_state(state:Dictionary):
|
func set_state(state:Dictionary):
|
||||||
yield(get_tree(), "idle_frame")
|
yield(get_tree(), "idle_frame")
|
||||||
|
|
||||||
|
if "hscroll" in state:
|
||||||
hscroll = state.hscroll
|
hscroll = state.hscroll
|
||||||
vscroll = state.vscroll
|
vscroll = state.vscroll
|
||||||
set_h_scroll(state.hscroll)
|
set_h_scroll(state.hscroll)
|
||||||
set_v_scroll(state.vscroll)
|
set_v_scroll(state.vscroll)
|
||||||
|
|
||||||
func _file_renamed(old_path:String, new_path:String):
|
if "text" in state:
|
||||||
if old_path == file_path:
|
if state.text.strip_edges():
|
||||||
file_path = new_path
|
text = state.text
|
||||||
update_name()
|
else:
|
||||||
update_colors()
|
editor._close_file(file_path)
|
||||||
|
|
||||||
|
if "cursor" in state:
|
||||||
|
set_cursor_state(state.cursor)
|
||||||
|
|
||||||
|
func _update_selected_line():
|
||||||
|
var l = cursor_get_line()
|
||||||
|
editor.select_symbol_line(0)
|
||||||
|
|
||||||
|
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] = symbol.name
|
||||||
|
|
||||||
|
if i == len(symbols)-1 or symbols.keys()[i+1] > line:
|
||||||
|
depth.resize(symbol.deep+1)
|
||||||
|
break
|
||||||
|
return depth
|
||||||
|
|
||||||
func _input(e):
|
func _input(e):
|
||||||
if not editor.is_plugin_active():
|
if not editor.is_plugin_active():
|
||||||
return
|
return
|
||||||
|
|
||||||
if not visible or not in_focus:
|
# custom tab system
|
||||||
|
if visible and in_focus and e is InputEventKey and e.pressed and e.scancode == KEY_TAB:
|
||||||
|
if is_selection_active():
|
||||||
|
var a = get_selection_from_line()
|
||||||
|
var b = get_selection_to_line()
|
||||||
|
var lines = get_selection_text().split("\n")
|
||||||
|
if e.shift:
|
||||||
|
for i in len(lines):
|
||||||
|
lines[i] = lines[i].trim_prefix(helper.get_tab())
|
||||||
|
else:
|
||||||
|
for i in len(lines):
|
||||||
|
lines[i] = helper.get_tab() + lines[i]
|
||||||
|
insert_text_at_cursor(lines.join("\n"))
|
||||||
|
select(a, 0, b, len(get_line(b)))
|
||||||
|
|
||||||
|
else:
|
||||||
|
insert_text_at_cursor(helper.get_tab())
|
||||||
|
|
||||||
|
get_tree().set_input_as_handled()
|
||||||
|
|
||||||
|
if not visible or not in_focus or not mouse_inside:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# show current position in heirarchy as editor hint
|
||||||
|
if e is InputEventMouseButton and not e.pressed:
|
||||||
|
_update_selected_line()
|
||||||
|
|
||||||
if e is InputEventMouseButton and not e.pressed and e.control:
|
if e is InputEventMouseButton and not e.pressed and e.control:
|
||||||
var line:String = get_line(cursor_get_line())
|
var line:String = get_line(cursor_get_line())
|
||||||
|
|
||||||
|
# click link
|
||||||
var ca = line.find("(")
|
var ca = line.find("(")
|
||||||
var cb = line.find_last(")")
|
var cb = line.find_last(")")
|
||||||
if ca != -1 and cb != -1:
|
if ca != -1 and cb != -1:
|
||||||
@ -105,29 +259,6 @@ func _input(e):
|
|||||||
var link = file_path.get_base_dir().plus_file(file)
|
var link = file_path.get_base_dir().plus_file(file)
|
||||||
editor.open_file(link)
|
editor.open_file(link)
|
||||||
editor.select_file(link)
|
editor.select_file(link)
|
||||||
# print(link)
|
|
||||||
|
|
||||||
if e is InputEventKey and e.pressed and e.control:
|
|
||||||
# tab to next
|
|
||||||
if e.scancode == KEY_TAB:
|
|
||||||
get_tree().set_input_as_handled()
|
|
||||||
if e.shift:
|
|
||||||
get_parent().prev()
|
|
||||||
else:
|
|
||||||
get_parent().next()
|
|
||||||
|
|
||||||
# save files
|
|
||||||
elif e.scancode == KEY_S:
|
|
||||||
get_tree().set_input_as_handled()
|
|
||||||
editor.save_files()
|
|
||||||
|
|
||||||
# close file
|
|
||||||
elif e.scancode == KEY_W:
|
|
||||||
get_tree().set_input_as_handled()
|
|
||||||
if e.shift:
|
|
||||||
editor.open_last_file()
|
|
||||||
else:
|
|
||||||
close()
|
|
||||||
|
|
||||||
# remember last selection
|
# remember last selection
|
||||||
if e is InputEventKey and e.pressed:
|
if e is InputEventKey and e.pressed:
|
||||||
@ -170,6 +301,30 @@ 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:
|
||||||
|
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):
|
func _unhandled_key_input(e):
|
||||||
if not visible:
|
if not visible:
|
||||||
return
|
return
|
||||||
@ -179,20 +334,35 @@ func _unhandled_key_input(e):
|
|||||||
helper.toggle_comment(self)
|
helper.toggle_comment(self)
|
||||||
get_tree().set_input_as_handled()
|
get_tree().set_input_as_handled()
|
||||||
|
|
||||||
|
func _file_renamed(old_path:String, new_path:String):
|
||||||
|
if old_path == file_path:
|
||||||
|
file_path = new_path
|
||||||
|
update_name()
|
||||||
|
update_colors()
|
||||||
|
|
||||||
func _file_selected(p:String):
|
func _file_selected(p:String):
|
||||||
if not p:
|
if p != file_path:
|
||||||
return
|
return
|
||||||
|
|
||||||
if p == file_path:
|
|
||||||
grab_focus()
|
|
||||||
grab_click_focus()
|
|
||||||
update_symbols()
|
update_symbols()
|
||||||
update_heading()
|
update_heading()
|
||||||
|
|
||||||
func goto_line(line:int):
|
# yield(get_tree(), "idle_frame")
|
||||||
|
#
|
||||||
|
# grab_focus()
|
||||||
|
# grab_click_focus()
|
||||||
|
|
||||||
|
func goto_symbol(index:int):
|
||||||
|
var syms = symbols.keys()
|
||||||
|
if syms and index >= 0 and index < len(syms):
|
||||||
|
goto_line(syms[index])
|
||||||
|
|
||||||
|
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
|
||||||
|
if bottom:
|
||||||
cursor_set_line(get_line_count())
|
cursor_set_line(get_line_count())
|
||||||
cursor_set_line(line)
|
cursor_set_line(line)
|
||||||
|
_update_selected_line()
|
||||||
|
|
||||||
func text_changed():
|
func text_changed():
|
||||||
if last_selected:
|
if last_selected:
|
||||||
@ -224,6 +394,8 @@ func set_temporary(t):
|
|||||||
update_name()
|
update_name()
|
||||||
|
|
||||||
func update_symbols():
|
func update_symbols():
|
||||||
|
update_helper()
|
||||||
|
|
||||||
symbols.clear()
|
symbols.clear()
|
||||||
tags.clear()
|
tags.clear()
|
||||||
|
|
||||||
@ -239,38 +411,56 @@ func update_symbols():
|
|||||||
else:
|
else:
|
||||||
tags[tag] += 1
|
tags[tag] += 1
|
||||||
|
|
||||||
# var _e = TE_Util.sort(tags, true)
|
|
||||||
editor._file_symbols_updated(file_path)
|
editor._file_symbols_updated(file_path)
|
||||||
|
|
||||||
func close():
|
func close():
|
||||||
if modified:
|
if modified:
|
||||||
|
if not editor.popup_unsaved.visible:
|
||||||
var _e
|
var _e
|
||||||
_e = editor.popup_unsaved.connect("confirmed", self, "_popup", ["close"], CONNECT_ONESHOT)
|
_e = editor.popup_unsaved.connect("confirmed", self, "_popup", ["confirm_close"], CONNECT_ONESHOT)
|
||||||
_e = editor.popup_unsaved.connect("custom_action", self, "_popup", [], CONNECT_ONESHOT)
|
_e = editor.popup_unsaved.connect("custom_action", self, "_popup", [], CONNECT_ONESHOT)
|
||||||
|
# _e = editor.popup_unsaved.connect("hide", self, "_popup", ["cancel"], CONNECT_ONESHOT)
|
||||||
editor.popup_unsaved.show()
|
editor.popup_unsaved.show()
|
||||||
else:
|
else:
|
||||||
editor._close_file(file_path)
|
editor._close_file(file_path)
|
||||||
|
|
||||||
func _popup(msg):
|
func _popup(msg):
|
||||||
match msg:
|
match msg:
|
||||||
"close":
|
"confirm_close":
|
||||||
editor._close_file(file_path)
|
editor._close_file(file_path)
|
||||||
"save_and_close":
|
"save_and_close":
|
||||||
save_file()
|
save_file()
|
||||||
editor._close_file(file_path)
|
editor._close_file(file_path)
|
||||||
|
editor.popup_unsaved.disconnect("confirmed", self, "_popup")
|
||||||
|
editor.popup_unsaved.disconnect("custom_action", self, "_popup")
|
||||||
|
|
||||||
func load_file(path:String):
|
func load_file(path:String):
|
||||||
file_path = path
|
file_path = path
|
||||||
text = TE_Util.load_text(path)
|
if path != "":
|
||||||
update_name()
|
text = editor.load_file(path)
|
||||||
|
clear_undo_history()
|
||||||
update_colors()
|
update_colors()
|
||||||
|
update_name()
|
||||||
|
|
||||||
func update_colors():
|
func update_helper():
|
||||||
clear_colors()
|
|
||||||
helper = editor.get_extension_helper(file_path)
|
helper = editor.get_extension_helper(file_path)
|
||||||
helper.apply_colors(editor, self)
|
helper.apply_colors(editor, self)
|
||||||
|
|
||||||
|
func update_colors():
|
||||||
|
clear_colors()
|
||||||
|
update_helper()
|
||||||
|
|
||||||
|
func _created_nonexisting(fp:String):
|
||||||
|
file_path = fp
|
||||||
|
modified = false
|
||||||
|
update_name()
|
||||||
|
update_symbols()
|
||||||
|
|
||||||
func save_file():
|
func save_file():
|
||||||
|
if file_path == "" and text:
|
||||||
|
editor.popup_create_file(editor.current_directory, text, funcref(self, "_created_nonexisting"))
|
||||||
|
|
||||||
|
else:
|
||||||
if modified:
|
if modified:
|
||||||
if not file_path.begins_with(editor.current_directory):
|
if not file_path.begins_with(editor.current_directory):
|
||||||
var err_msg = "can't save to %s" % file_path
|
var err_msg = "can't save to %s" % file_path
|
||||||
@ -284,12 +474,35 @@ func save_file():
|
|||||||
update_symbols()
|
update_symbols()
|
||||||
|
|
||||||
func update_name():
|
func update_name():
|
||||||
var n = file_path.get_file().split(".", true, 1)[0]
|
var n:String
|
||||||
|
|
||||||
|
if file_path == "":
|
||||||
|
n = "UNSAVED"
|
||||||
|
|
||||||
|
else:
|
||||||
|
n = file_path.get_file().split(".", true, 1)[0]
|
||||||
|
|
||||||
|
if editor.ignore_head_numbers:
|
||||||
|
n = editor._split_header(n)[1]
|
||||||
|
|
||||||
if temporary: n = "?" + n
|
if temporary: n = "?" + n
|
||||||
if modified: n = "*" + n
|
if modified: n = "*" + n
|
||||||
|
|
||||||
|
if len(n) > 12:
|
||||||
|
n = n.substr(0, 9) + "..."
|
||||||
|
|
||||||
|
if editor.show_tab_color:
|
||||||
|
var color = editor.get_file_tint_name(file_path)
|
||||||
|
var path = "res://addons/text_editor/icons/icon_%s.png" % color
|
||||||
|
if File.new().file_exists(path):
|
||||||
|
editor.tab_parent.set_tab_icon(get_index(), load(path))
|
||||||
|
else:
|
||||||
|
editor.tab_parent.set_tab_icon(get_index(), null)
|
||||||
|
else:
|
||||||
|
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)
|
||||||
update_heading()
|
name = n
|
||||||
|
|
||||||
func update_heading():
|
func update_heading():
|
||||||
if Engine.editor_hint:
|
if Engine.editor_hint:
|
||||||
@ -306,5 +519,5 @@ func update_heading():
|
|||||||
OS.set_window_title("%s - Text Editor" % f)
|
OS.set_window_title("%s - Text Editor" % f)
|
||||||
|
|
||||||
func needs_save() -> bool:
|
func needs_save() -> bool:
|
||||||
return modified or not File.new().file_exists(file_path)
|
return modified or (not File.new().file_exists(file_path) and text)
|
||||||
|
|
||||||
|
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]
|
@ -1,7 +1,9 @@
|
|||||||
extends TabContainer
|
extends TabContainer
|
||||||
|
|
||||||
onready var editor:TE_TextEditor = owner
|
onready var editor:TE_Editor = owner
|
||||||
var mouse:bool = false
|
var mouse:bool = false
|
||||||
|
var last_tab_index:int = -1
|
||||||
|
var tab_menu:PopupMenu
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
if not editor.is_plugin_active():
|
if not editor.is_plugin_active():
|
||||||
@ -10,9 +12,72 @@ func _ready():
|
|||||||
var _e
|
var _e
|
||||||
_e = connect("mouse_entered", self, "set", ["mouse", true])
|
_e = connect("mouse_entered", self, "set", ["mouse", true])
|
||||||
_e = connect("mouse_exited", self, "set", ["mouse", false])
|
_e = connect("mouse_exited", self, "set", ["mouse", false])
|
||||||
|
_e = connect("tab_changed", self, "_tab_changed")
|
||||||
|
_e = connect("pre_popup_pressed", self, "update_popup")
|
||||||
|
|
||||||
add_font_override("font", editor.FONT_R)
|
add_font_override("font", editor.FONT_R)
|
||||||
|
|
||||||
|
tab_menu = owner.get_node("popup_tab_menu")
|
||||||
|
tab_menu.connect("index_pressed", self, "_popup_selected")
|
||||||
|
|
||||||
|
func _tab_changed(index):
|
||||||
|
var tab = get_child(index)
|
||||||
|
tab.grab_focus()
|
||||||
|
|
||||||
|
last_tab_index = index
|
||||||
|
|
||||||
|
func _popup_selected(index:int):
|
||||||
|
var tindex := tab_menu.get_item_id(index)
|
||||||
|
if tindex >= 100:
|
||||||
|
current_tab = tindex - 100
|
||||||
|
return
|
||||||
|
|
||||||
|
match tindex:
|
||||||
|
0: # close
|
||||||
|
get_child(hovered_tab_index).close()
|
||||||
|
|
||||||
|
1: # close others
|
||||||
|
var all_tabs = owner.get_tabs()
|
||||||
|
var hovered = get_child(hovered_tab_index)
|
||||||
|
for tab in all_tabs:
|
||||||
|
if tab != hovered:
|
||||||
|
tab.close()
|
||||||
|
|
||||||
|
2: # close left
|
||||||
|
var all_tabs = owner.get_tabs()
|
||||||
|
for i in range(0, hovered_tab_index):
|
||||||
|
all_tabs[i].close()
|
||||||
|
current_tab = 0
|
||||||
|
|
||||||
|
3: # close right
|
||||||
|
var all_tabs = owner.get_tabs()
|
||||||
|
for i in range(hovered_tab_index+1, len(all_tabs)):
|
||||||
|
all_tabs[i].close()
|
||||||
|
|
||||||
|
var hovered_tab_index:int
|
||||||
|
func update_popup(index:int=current_tab):
|
||||||
|
var all_tabs = owner.get_tabs()
|
||||||
|
|
||||||
|
hovered_tab_index = index
|
||||||
|
|
||||||
|
tab_menu.clear()
|
||||||
|
tab_menu.rect_size = Vector2.ZERO
|
||||||
|
tab_menu.add_item("Close", 0)
|
||||||
|
tab_menu.add_item("Close others", 1)
|
||||||
|
|
||||||
|
if index > 0:
|
||||||
|
tab_menu.add_item("Close all to left", 2)
|
||||||
|
|
||||||
|
if index < len(all_tabs)-1:
|
||||||
|
tab_menu.add_item("Close all to right", 3)
|
||||||
|
|
||||||
|
tab_menu.add_separator()
|
||||||
|
|
||||||
|
var i = 0
|
||||||
|
for tab in owner.get_tabs():
|
||||||
|
tab_menu.add_item(tab.name, 100+i)
|
||||||
|
i += 1
|
||||||
|
|
||||||
func _input(e):
|
func _input(e):
|
||||||
if not editor.is_plugin_active():
|
if not editor.is_plugin_active():
|
||||||
return
|
return
|
||||||
@ -26,6 +91,14 @@ func _input(e):
|
|||||||
next()
|
next()
|
||||||
get_tree().set_input_as_handled()
|
get_tree().set_input_as_handled()
|
||||||
|
|
||||||
|
elif e.button_index == BUTTON_RIGHT:
|
||||||
|
var index := get_tab_idx_at_point(get_local_mouse_position())
|
||||||
|
if index != -1:
|
||||||
|
update_popup(index)
|
||||||
|
tab_menu.rect_global_position = get_global_mouse_position()
|
||||||
|
tab_menu.popup()
|
||||||
|
get_tree().set_input_as_handled()
|
||||||
|
|
||||||
if e is InputEventKey and e.pressed and e.control and e.scancode == KEY_TAB:
|
if e is InputEventKey and e.pressed and e.control and e.scancode == KEY_TAB:
|
||||||
if e.shift:
|
if e.shift:
|
||||||
prev()
|
prev()
|
||||||
|
@ -7,6 +7,8 @@ onready var dir_popup:PopupMenu = $dir_popup
|
|||||||
const DragLabel = preload("res://addons/text_editor/TE_DragLabel.gd")
|
const DragLabel = preload("res://addons/text_editor/TE_DragLabel.gd")
|
||||||
var drag_label:RichTextLabel
|
var drag_label:RichTextLabel
|
||||||
|
|
||||||
|
export var p_filter:NodePath
|
||||||
|
var filter:String = ""
|
||||||
var selected:Array = []
|
var selected:Array = []
|
||||||
var dragging:Array = []
|
var dragging:Array = []
|
||||||
var drag_start:Vector2
|
var drag_start:Vector2
|
||||||
@ -20,6 +22,10 @@ func _ready():
|
|||||||
_e = editor.connect("file_selected", self, "_file_selected")
|
_e = editor.connect("file_selected", self, "_file_selected")
|
||||||
_e = editor.connect("file_renamed", self, "_file_renamed")
|
_e = editor.connect("file_renamed", self, "_file_renamed")
|
||||||
|
|
||||||
|
var le:LineEdit = get_node(p_filter)
|
||||||
|
_e = le.connect("text_changed", self, "_filter_changed")
|
||||||
|
le.add_font_override("font", editor.FONT_R)
|
||||||
|
|
||||||
# file popup
|
# file popup
|
||||||
file_popup.clear()
|
file_popup.clear()
|
||||||
file_popup.rect_size = Vector2.ZERO
|
file_popup.rect_size = Vector2.ZERO
|
||||||
@ -33,9 +39,14 @@ func _ready():
|
|||||||
dir_popup.clear()
|
dir_popup.clear()
|
||||||
dir_popup.rect_size = Vector2.ZERO
|
dir_popup.rect_size = Vector2.ZERO
|
||||||
dir_popup.add_item("New File")
|
dir_popup.add_item("New File")
|
||||||
dir_popup.add_item("New Folder")
|
|
||||||
dir_popup.add_separator()
|
dir_popup.add_separator()
|
||||||
dir_popup.add_item("Remove")
|
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")
|
_e = dir_popup.connect("index_pressed", self, "_dir_popup")
|
||||||
dir_popup.add_font_override("font", editor.FONT)
|
dir_popup.add_font_override("font", editor.FONT)
|
||||||
|
|
||||||
@ -44,6 +55,10 @@ func _ready():
|
|||||||
add_font_override("italics_font", editor.FONT_I)
|
add_font_override("italics_font", editor.FONT_I)
|
||||||
add_font_override("bold_italics_font", editor.FONT_BI)
|
add_font_override("bold_italics_font", editor.FONT_BI)
|
||||||
|
|
||||||
|
func _filter_changed(t:String):
|
||||||
|
filter = t
|
||||||
|
_redraw()
|
||||||
|
|
||||||
func _dir_popup(index:int):
|
func _dir_popup(index:int):
|
||||||
var type = selected[0]
|
var type = selected[0]
|
||||||
var file = selected[1]
|
var file = selected[1]
|
||||||
@ -51,9 +66,32 @@ func _dir_popup(index:int):
|
|||||||
file = file.file_path
|
file = file.file_path
|
||||||
|
|
||||||
match dir_popup.get_item_text(index):
|
match dir_popup.get_item_text(index):
|
||||||
"New File": editor.popup_create_file(file)
|
"New File":
|
||||||
"New Folder": editor.popup_create_dir(file)
|
editor.popup_create_file(file)
|
||||||
"Remove": editor.recycle(file)
|
|
||||||
|
"Remove":
|
||||||
|
editor.recycle(file, type == "f")
|
||||||
|
|
||||||
|
"Tint Yellow":
|
||||||
|
selected[1].tint = "yellow"#Color.gold
|
||||||
|
editor.emit_signal("dir_tint_changed", selected[1].file_path)
|
||||||
|
_redraw()
|
||||||
|
"Tint Red":
|
||||||
|
selected[1].tint = "red"#Color.tomato
|
||||||
|
editor.emit_signal("dir_tint_changed", selected[1].file_path)
|
||||||
|
_redraw()
|
||||||
|
"Tint Blue":
|
||||||
|
selected[1].tint = "blue"#Color.deepskyblue
|
||||||
|
editor.emit_signal("dir_tint_changed", selected[1].file_path)
|
||||||
|
_redraw()
|
||||||
|
"Tint Green":
|
||||||
|
selected[1].tint = "green"#Color.chartreuse
|
||||||
|
editor.emit_signal("dir_tint_changed", selected[1].file_path)
|
||||||
|
_redraw()
|
||||||
|
"Reset Tint":
|
||||||
|
selected[1].tint = ""#Color.white
|
||||||
|
editor.emit_signal("dir_tint_changed", selected[1].file_path)
|
||||||
|
_redraw()
|
||||||
|
|
||||||
func _file_popup(index:int):
|
func _file_popup(index:int):
|
||||||
var type = selected[0]
|
var type = selected[0]
|
||||||
@ -70,7 +108,7 @@ func _file_popup(index:int):
|
|||||||
|
|
||||||
"Remove":
|
"Remove":
|
||||||
if type == "f":
|
if type == "f":
|
||||||
editor.recycle(file)
|
editor.recycle(file, true)
|
||||||
|
|
||||||
_:
|
_:
|
||||||
selected = []
|
selected = []
|
||||||
@ -95,14 +133,21 @@ func _input(e:InputEvent):
|
|||||||
var file = meta_hovered[1]
|
var file = meta_hovered[1]
|
||||||
|
|
||||||
if e.button_index == BUTTON_LEFT:
|
if e.button_index == BUTTON_LEFT:
|
||||||
|
|
||||||
if e.pressed:
|
if e.pressed:
|
||||||
if type in ["f", "d"]:
|
if type in ["f", "d"]:
|
||||||
|
|
||||||
|
if type == "f" and Input.is_key_pressed(KEY_CONTROL):
|
||||||
|
editor.file_data[file].open = not editor.file_data[file].open
|
||||||
|
_redraw()
|
||||||
|
|
||||||
|
else:
|
||||||
var file_path = file if type == "f" else file.file_path
|
var file_path = file if type == "f" else file.file_path
|
||||||
|
|
||||||
if file_path.begins_with(editor.PATH_TRASH):
|
# can't move recycling
|
||||||
return # can't move recycling
|
if editor.is_trash_path(file_path):
|
||||||
|
return
|
||||||
|
|
||||||
|
# select for drag
|
||||||
else:
|
else:
|
||||||
dragging = meta_hovered
|
dragging = meta_hovered
|
||||||
|
|
||||||
@ -110,14 +155,19 @@ func _input(e:InputEvent):
|
|||||||
drag_label.editor = editor
|
drag_label.editor = editor
|
||||||
editor.add_child(drag_label)
|
editor.add_child(drag_label)
|
||||||
|
|
||||||
|
else:
|
||||||
|
if type == "f" and Input.is_key_pressed(KEY_CONTROL):
|
||||||
|
pass
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if dragging and dragging != meta_hovered:
|
if dragging and dragging != meta_hovered:
|
||||||
var drag_type = dragging[0]
|
var drag_type = dragging[0]
|
||||||
var drag_file = dragging[1]
|
var drag_file = dragging[1]
|
||||||
|
|
||||||
|
# dragged onto directory?
|
||||||
if type == "d":
|
if type == "d":
|
||||||
var dir:String = file.file_path
|
var dir:String = file.file_path
|
||||||
var old_path:String = drag_file
|
var old_path:String = drag_file if drag_type == "f" else drag_file.file_path
|
||||||
var new_path:String = dir.plus_file(old_path.get_file())
|
var new_path:String = dir.plus_file(old_path.get_file())
|
||||||
editor.rename_file(old_path, new_path)
|
editor.rename_file(old_path, new_path)
|
||||||
|
|
||||||
@ -132,12 +182,19 @@ func _input(e:InputEvent):
|
|||||||
|
|
||||||
# unrecycle
|
# unrecycle
|
||||||
"unrecycle":
|
"unrecycle":
|
||||||
editor.unrecycle(file)
|
editor.unrecycle(file.file_path)
|
||||||
|
|
||||||
# select
|
# select
|
||||||
"f":
|
"f":
|
||||||
editor.select_file(file)
|
editor.select_file(file)
|
||||||
|
|
||||||
|
# select file symbol
|
||||||
|
"fs":
|
||||||
|
editor.select_file(file)
|
||||||
|
var tab = editor.get_selected_tab()
|
||||||
|
yield(get_tree(), "idle_frame")
|
||||||
|
tab.goto_symbol(meta_hovered[2])
|
||||||
|
|
||||||
get_tree().set_input_as_handled()
|
get_tree().set_input_as_handled()
|
||||||
|
|
||||||
elif e.button_index == BUTTON_RIGHT:
|
elif e.button_index == BUTTON_RIGHT:
|
||||||
@ -162,69 +219,139 @@ var lines:PoolStringArray = PoolStringArray()
|
|||||||
|
|
||||||
func _redraw():
|
func _redraw():
|
||||||
lines = PoolStringArray()
|
lines = PoolStringArray()
|
||||||
_draw_dir(editor.file_list[""], 0)
|
lines.append_array(_draw_dir(editor.file_list[""], 0))
|
||||||
set_bbcode(lines.join("\n"))
|
set_bbcode(lines.join("\n"))
|
||||||
|
|
||||||
const FOLDER:String = "🗀" # not visible in godot
|
func _dull_nonwords(s:String, clr:Color, dull:Color) -> String:
|
||||||
func _draw_dir(dir:Dictionary, deep:int):
|
var on = false
|
||||||
|
var parts = []
|
||||||
|
for c in s:
|
||||||
|
on = c in "0123456789_-"
|
||||||
|
if not parts or parts[-1][0] != on:
|
||||||
|
parts.append([on, ""])
|
||||||
|
parts[-1][1] += c
|
||||||
|
var out = ""
|
||||||
|
for p in parts:
|
||||||
|
out += clr(p[1], dull if p[0] else clr)
|
||||||
|
return out
|
||||||
|
|
||||||
|
const FOLDER_CLOSED:String = "🗀" # not visible in Godot.
|
||||||
|
const FOLDER_OPEN:String = "🗁" # not visible in Godot.
|
||||||
|
|
||||||
|
func _draw_dir(dir:Dictionary, deep:int) -> Array:
|
||||||
var is_tagging = editor.is_tagging()
|
var is_tagging = editor.is_tagging()
|
||||||
var dimmest:float = .5 if is_tagging else 0.0
|
var dimmest:float = .5 if is_tagging else 0.0
|
||||||
|
var tint = editor.get_tint_color(dir.tint)
|
||||||
|
var dull = Color.white.darkened(.65)
|
||||||
|
var dull_tint = tint.darkened(.5)
|
||||||
|
|
||||||
var space = clr("┃ ".repeat(deep), Color.white.darkened(.8))
|
var space = ""
|
||||||
var file:String = dir.file_path
|
var file:String = dir.file_path
|
||||||
var head:String = "▼" if dir.open else "▶"
|
|
||||||
head = clr(space+FOLDER+head, Color.white.darkened(.5))
|
|
||||||
head += " " + b(file.get_file())
|
|
||||||
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)))
|
|
||||||
|
|
||||||
|
space = clr("┃ ".repeat(deep), Color.white.darkened(.8))
|
||||||
|
|
||||||
|
var head:String = "▼" if dir.open else "▶"
|
||||||
|
var fold:String = FOLDER_OPEN if dir.open else FOLDER_CLOSED
|
||||||
|
var dname = b(_dull_nonwords(file.get_file(), tint.darkened(0 if editor.is_dir_tagged(dir) else 0.5), dull))
|
||||||
|
dname = clr("「", dull) + dname + clr("」", dull)
|
||||||
|
head = clr(space+fold, Color.gold) + clr(head, Color.white.darkened(.5))
|
||||||
|
head += " %s" % dname
|
||||||
|
|
||||||
|
var link:String = meta(head, ["d", dir], editor.get_localized_path(file))
|
||||||
|
if editor.is_trash_path(file):
|
||||||
|
link += " " + meta(clr("⬅", Color.yellowgreen), ["unrecycle", dir], file)
|
||||||
|
|
||||||
|
var out = []
|
||||||
var sel = editor.get_selected_tab()
|
var sel = editor.get_selected_tab()
|
||||||
sel = sel.file_path if sel else ""
|
sel = sel.file_path if sel else ""
|
||||||
|
|
||||||
if dir.open:
|
if dir.open or filter:
|
||||||
# draw dirs
|
# draw dirs
|
||||||
for path in dir.dirs:
|
for path in dir.dirs:
|
||||||
var file_path = dir.all[path]
|
var file_path = dir.all[path]
|
||||||
if file_path is Dictionary and file_path.show:
|
if file_path is Dictionary and (file_path.show or filter):
|
||||||
_draw_dir(file_path, deep+1)
|
out.append_array(_draw_dir(file_path, deep+1))
|
||||||
|
|
||||||
# draw files
|
# draw files
|
||||||
var last = len(dir.files)-1
|
var last = len(dir.files)-1
|
||||||
for i in len(dir.files):
|
for i in len(dir.files):
|
||||||
var file_path = dir.files[i]
|
var file_path = dir.files[i]
|
||||||
file = file_path.get_file()
|
var fname = file_path.get_file()
|
||||||
var p = file.split(".", true, 1)
|
file = fname
|
||||||
|
var p = [file, ""] if not "." in file else file.split(".", true, 1)
|
||||||
file = p[0]
|
file = p[0]
|
||||||
var ext = p[1]
|
var ext = p[1]
|
||||||
|
|
||||||
var is_selected = file_path == sel
|
var is_selected = file_path == sel
|
||||||
var is_opened = editor.is_opened(file_path)
|
var is_opened = editor.is_opened(file_path)
|
||||||
var color = Color.white
|
var color = tint
|
||||||
head = "┣╸" if i != last else "┗╸"
|
head = "" if filter else "┣╸" if i != last else "┗╸"
|
||||||
|
|
||||||
if "readme" in file.to_lower():
|
var fname_lower = fname.to_lower()
|
||||||
|
|
||||||
|
if "readme" in fname_lower:
|
||||||
head = "🛈"
|
head = "🛈"
|
||||||
|
|
||||||
if is_selected:
|
|
||||||
head = "● "
|
|
||||||
|
|
||||||
elif is_opened:
|
|
||||||
head = "○ "
|
|
||||||
|
|
||||||
head = clr(head, Color.white.darkened(.5 if is_opened else .75))
|
head = clr(head, Color.white.darkened(.5 if is_opened else .75))
|
||||||
|
|
||||||
|
var bold = false
|
||||||
if is_tagging:
|
if is_tagging:
|
||||||
if editor.is_tagged(file_path):
|
if editor.is_tagged(file_path):
|
||||||
file = b(file)
|
bold = true
|
||||||
|
|
||||||
else:
|
else:
|
||||||
color = color.darkened(dimmest)
|
color = color.darkened(dimmest)
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
file = clr(file, color)
|
file = _dull_nonwords(file, color, dull)
|
||||||
ext = clr("." + ext, Color.white.darkened(.65))
|
|
||||||
var line = space + head + file + ext
|
if bold:
|
||||||
lines.append(meta(line, ["f", file_path], file_path))
|
file = b(file)
|
||||||
|
|
||||||
|
ext = "" if not ext else clr("." + ext, dull)
|
||||||
|
|
||||||
|
var line = file + ext
|
||||||
|
|
||||||
|
if is_selected:
|
||||||
|
line = u(line)
|
||||||
|
|
||||||
|
var hint_path = editor.get_localized_path(file_path)
|
||||||
|
|
||||||
|
var file_lines = []
|
||||||
|
|
||||||
|
if not editor._scanning:
|
||||||
|
var fdata = editor.get_file_data(file_path)
|
||||||
|
var symbols = fdata.symbols.values()
|
||||||
|
for j in range(1, len(symbols)):
|
||||||
|
if fdata.open or filter:
|
||||||
|
var sdata:Dictionary = symbols[j]
|
||||||
|
var sname:String = sdata.name
|
||||||
|
var index = sname.to_lower().find(filter)
|
||||||
|
|
||||||
|
if filter and index == -1:
|
||||||
|
continue
|
||||||
|
|
||||||
|
var sname_highlighted = TE_Util.highlight(sname, index, len(filter), TE_Util.hue_shift(dull_tint, -.075), Color.white)
|
||||||
|
|
||||||
|
var s = clr(" @ " + "-".repeat(sdata.deep), dull) + sname_highlighted
|
||||||
|
var h = hint_path + " @" + sname
|
||||||
|
file_lines.append(meta(space + s, ["fs", file_path, j], h))
|
||||||
|
|
||||||
|
if filter:
|
||||||
|
var index = fname_lower.find(filter)
|
||||||
|
if index != -1:
|
||||||
|
line = TE_Util.highlight(fname, index, len(filter), dull_tint, Color.white)
|
||||||
|
|
||||||
|
# show file name if not filtering, or if
|
||||||
|
if not filter or file_lines:
|
||||||
|
file_lines.push_front(meta(space + head + line, ["f", file_path], hint_path))
|
||||||
|
# file_lines.push_front(space + head + line)
|
||||||
|
|
||||||
|
out.append_array(file_lines)
|
||||||
|
|
||||||
|
# show folder name if not filtering, or if filter catches a sub file or subsymbol
|
||||||
|
if not filter or out:
|
||||||
|
out.push_front(link)
|
||||||
|
|
||||||
|
return out
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
tool
|
tool
|
||||||
extends LineEdit
|
extends LineEdit
|
||||||
|
|
||||||
onready var editor:TE_TextEditor = owner
|
onready var editor:TE_Editor = owner
|
||||||
var fr:FuncRef
|
var fr:FuncRef
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
@ -33,6 +33,5 @@ func _lost_focus():
|
|||||||
|
|
||||||
func _enter(t:String):
|
func _enter(t:String):
|
||||||
if fr:
|
if fr:
|
||||||
print("calling %s with %s" % [fr, t])
|
|
||||||
fr.call_func(t)
|
fr.call_func(t)
|
||||||
hide()
|
hide()
|
||||||
|
@ -17,6 +17,9 @@ func _file_saved(_file_path:String):
|
|||||||
_redraw()
|
_redraw()
|
||||||
|
|
||||||
func _redraw():
|
func _redraw():
|
||||||
|
if not visible:
|
||||||
|
return
|
||||||
|
|
||||||
var tab = editor.get_selected_tab()
|
var tab = editor.get_selected_tab()
|
||||||
if tab:
|
if tab:
|
||||||
tab.helper.generate_meta(tab, self)
|
tab.helper.generate_meta(tab, self)
|
||||||
|
@ -1,19 +1,39 @@
|
|||||||
tool
|
tool
|
||||||
extends TabContainer
|
extends TabContainer
|
||||||
|
|
||||||
onready var editor:TE_TextEditor = owner
|
onready var editor:TE_Editor = owner
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
if not editor.is_plugin_active():
|
if not editor.is_plugin_active():
|
||||||
return
|
return
|
||||||
|
|
||||||
|
set_visible(false)
|
||||||
add_font_override("font", editor.FONT_R)
|
add_font_override("font", editor.FONT_R)
|
||||||
|
|
||||||
func _unhandled_key_input(e):
|
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:
|
||||||
visible = not visible
|
# show this menu
|
||||||
|
KEY_M:
|
||||||
|
set_visible(not get_parent().visible)
|
||||||
get_tree().set_input_as_handled()
|
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
|
||||||
|
select_tab($image)
|
||||||
|
$image/image.texture = TE_Util.load_image(file_path)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
extends RichTextLabel
|
extends RichTextLabel
|
||||||
|
|
||||||
onready var editor:TE_TextEditor = owner
|
onready var editor:TE_Editor = owner
|
||||||
|
|
||||||
var meta_items:Array = []
|
var meta_items:Array = []
|
||||||
var meta_hovered:Array = []
|
var meta_hovered:Array = []
|
||||||
@ -97,6 +97,7 @@ func table(rows) -> String:
|
|||||||
|
|
||||||
func b(t:String) -> String: return "[b]%s[/b]" % t
|
func b(t:String) -> String: return "[b]%s[/b]" % t
|
||||||
func i(t:String) -> String: return "[i]%s[/i]" % 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]
|
func clr(t:String, c:Color) -> String: return "[color=#%s]%s[/color]" % [c.to_html(), t]
|
||||||
func center(t:String): return "[center]%s[/center]" % t
|
func center(t:String): return "[center]%s[/center]" % t
|
||||||
|
|
||||||
|
@ -3,44 +3,97 @@ extends "res://addons/text_editor/TE_RichTextLabel.gd"
|
|||||||
|
|
||||||
var chapter_info:Array = []
|
var chapter_info:Array = []
|
||||||
var sort_on:String = "words"
|
var sort_on:String = "words"
|
||||||
var sort_reverse:Dictionary = { id=false, words=false, unique=false }
|
var sort_on_index:int = 1
|
||||||
|
var sort_reverse:Dictionary = { id=true, chaps=true, words=true, uwords=true, "%":true, modified=true }
|
||||||
|
var skip_words:PoolStringArray
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
var _e
|
var btn = get_parent().get_node("update")
|
||||||
_e = editor.connect("file_opened", self, "_update")
|
btn.add_font_override("font", editor.FONT_R)
|
||||||
_e = editor.connect("file_saved", self, "_update")
|
|
||||||
|
|
||||||
func _update(f):
|
var _e = btn.connect("pressed", self, "_update")
|
||||||
set_process(true)
|
|
||||||
|
|
||||||
func _process(_delta):
|
func _update():
|
||||||
chapter_info.clear()
|
chapter_info.clear()
|
||||||
|
|
||||||
|
# load block list
|
||||||
|
var skip_list = editor.current_directory.plus_file("word_skip_list.txt")
|
||||||
|
if File.new().file_exists(skip_list):
|
||||||
|
skip_words = TE_Util.load_text(skip_list).replace("\n", " ").strip_edges().to_lower().split(" ")
|
||||||
|
else:
|
||||||
|
skip_words = PoolStringArray()
|
||||||
|
|
||||||
for path in editor.file_paths:
|
for path in editor.file_paths:
|
||||||
var file = path.get_file()
|
var file = path.get_file()
|
||||||
var ext = file.get_extension()
|
var ext = file.get_extension()
|
||||||
match ext:
|
match ext:
|
||||||
"md": _process_md(path)
|
"md": _process_md(path)
|
||||||
|
|
||||||
|
# clear empty
|
||||||
|
for i in range(len(chapter_info)-1, -1, -1):
|
||||||
|
var info = chapter_info[i]
|
||||||
|
if not info.words:
|
||||||
|
chapter_info.remove(i)
|
||||||
|
|
||||||
_sort()
|
_sort()
|
||||||
_redraw()
|
_redraw()
|
||||||
|
|
||||||
set_process(false)
|
const WEEKDAYS = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
|
||||||
|
const MONTHS = ["Januaray", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
|
||||||
|
|
||||||
func _chapter(path:String, line:int, id:String):
|
const TIMES:Dictionary = {
|
||||||
chapter_info.append({ path=path, line=line, id=id, words=0, chars=0, unique=0 })
|
"second": 60,
|
||||||
|
"minute": 60,
|
||||||
|
"hour": 24,
|
||||||
|
"day": INF
|
||||||
|
}
|
||||||
|
func get_time(t:int) -> String:
|
||||||
|
for k in TIMES:
|
||||||
|
if t < TIMES[k]:
|
||||||
|
return "%s %s ago" % [t, k + ("" if t == 1 else "s")]
|
||||||
|
t /= TIMES[k]
|
||||||
|
return "???"
|
||||||
|
|
||||||
func _process_md(path:String):
|
func _process_md(path:String):
|
||||||
var lines = TE_Util.load_text(path).split("\n")
|
var lines = TE_Util.load_text(path).split("\n")
|
||||||
_chapter(path, 0, "NOH")
|
var file_time = File.new().get_modified_time(path)
|
||||||
|
var curr_time = OS.get_unix_time()
|
||||||
|
var diff_time = curr_time - file_time
|
||||||
|
var time_nice = get_time(diff_time)
|
||||||
|
|
||||||
|
if false and diff_time > 9999999:
|
||||||
|
time_nice = OS.get_datetime_from_unix_time(file_time)
|
||||||
|
time_nice.weekday = WEEKDAYS[time_nice.weekday-1].substr(0, 3).to_lower()
|
||||||
|
time_nice.month = MONTHS[time_nice.month-1].substr(0, 3).to_lower()
|
||||||
|
time_nice.hour12 = str(time_nice.hour % 12)
|
||||||
|
time_nice.ampm = "am" if time_nice.hour > 12 else "pm"
|
||||||
|
time_nice = "{weekday} {month} {day}, {year} {hour12}:{minute}:{second}{ampm}".format(time_nice)
|
||||||
|
|
||||||
|
var out = { path=path, line=0, id=editor.get_localized_path(path), modified=file_time, time_nice=time_nice, words=0, uwords={}, chaps=0, "%":0.0 }
|
||||||
|
chapter_info.append(out)
|
||||||
var i = 0
|
var i = 0
|
||||||
while i < len(lines):
|
while i < len(lines):
|
||||||
# skip head meta
|
# skip head meta
|
||||||
if i == 0 and lines[i].begins_with("---"):
|
if i == 0 and lines[i].begins_with("---"):
|
||||||
i += 1
|
i += 1
|
||||||
while i < len(lines) and not lines[i].begins_with("---"):
|
while i < len(lines) and not lines[i].begins_with("---"):
|
||||||
|
if ":" in lines[i]:
|
||||||
|
var p = lines[i].split(":", true, 1)
|
||||||
|
var k = p[0].strip_edges()
|
||||||
|
var v = p[1].strip_edges()
|
||||||
|
match k:
|
||||||
|
"name":
|
||||||
|
out.id = v
|
||||||
|
|
||||||
|
"prog", "progress":
|
||||||
|
out["%"] = float(v.replace("%", ""))
|
||||||
|
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
|
# skip comments
|
||||||
|
elif "<!--" in lines[i]:
|
||||||
|
pass
|
||||||
|
|
||||||
# skip code blocks
|
# skip code blocks
|
||||||
elif lines[i].begins_with("~~~") or lines[i].begins_with("```"):
|
elif lines[i].begins_with("~~~") or lines[i].begins_with("```"):
|
||||||
var head = lines[i].substr(0, 3)
|
var head = lines[i].substr(0, 3)
|
||||||
@ -51,28 +104,32 @@ func _process_md(path:String):
|
|||||||
# heading
|
# heading
|
||||||
elif lines[i].begins_with("#"):
|
elif lines[i].begins_with("#"):
|
||||||
var p = lines[i].split(" ", true, 1)
|
var p = lines[i].split(" ", true, 1)
|
||||||
var id = lines[i].split(" ", true, 1)[1].strip_edges()
|
var id = lines[i].split(" ", true, 1)
|
||||||
_chapter(path, i, id)
|
var deep = len(id[0])
|
||||||
|
id = "???" if len(id) == 1 else id[1].strip_edges()
|
||||||
|
out.chaps += 1
|
||||||
|
|
||||||
else:
|
else:
|
||||||
var words = lines[i].split(" ", false)
|
out.words += TE_Util.count_words(lines[i], out.uwords, skip_words)
|
||||||
var unique = []
|
|
||||||
for word in words:
|
|
||||||
var w = clean_word(word.to_lower())
|
|
||||||
if w and not w in unique:
|
|
||||||
unique.append(w)
|
|
||||||
|
|
||||||
chapter_info[-1].words += len(words)
|
|
||||||
chapter_info[-1].unique += len(unique)
|
|
||||||
|
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
func clean_word(w:String):
|
# sort word counts
|
||||||
var out = ""
|
TE_Util.sort_vals(out.uwords)
|
||||||
for c in w:
|
var words = PoolStringArray(out.uwords.keys())
|
||||||
if c in "abcdefghijklmnopqrstuvwxyz":
|
var words_top = words
|
||||||
out += c
|
if len(words_top) > 16:
|
||||||
return out
|
words_top.resize(16)
|
||||||
|
out.uwords = words_top.join(" ")
|
||||||
|
|
||||||
|
var word_lines = [""]
|
||||||
|
for word in words:
|
||||||
|
if len(word_lines[-1]) >= 64:
|
||||||
|
word_lines.append("")
|
||||||
|
if word_lines[-1]:
|
||||||
|
word_lines[-1] += " "
|
||||||
|
word_lines[-1] += word
|
||||||
|
out.uwords_all = PoolStringArray(word_lines).join("\n")
|
||||||
|
|
||||||
func _clicked(args):
|
func _clicked(args):
|
||||||
match args[0]:
|
match args[0]:
|
||||||
@ -80,6 +137,7 @@ func _clicked(args):
|
|||||||
var key = args[1]
|
var key = args[1]
|
||||||
if sort_on != key:
|
if sort_on != key:
|
||||||
sort_on = key
|
sort_on = key
|
||||||
|
sort_on_index = sort_reverse.keys().find(sort_on)
|
||||||
else:
|
else:
|
||||||
sort_reverse[key] = not sort_reverse[key]
|
sort_reverse[key] = not sort_reverse[key]
|
||||||
|
|
||||||
@ -87,35 +145,46 @@ func _clicked(args):
|
|||||||
_redraw()
|
_redraw()
|
||||||
|
|
||||||
"goto":
|
"goto":
|
||||||
print(args)
|
|
||||||
var tab = editor.open_file(args[1])
|
var tab = editor.open_file(args[1])
|
||||||
editor.select_file(args[1])
|
editor.select_file(args[1])
|
||||||
tab.goto_line(args[2])
|
tab.goto_line(args[2])
|
||||||
|
|
||||||
func _sort():
|
func _sort():
|
||||||
if sort_reverse[sort_on]:
|
if sort_reverse[sort_on]:
|
||||||
chapter_info.sort_custom(self, "_sort_chapters")
|
|
||||||
else:
|
|
||||||
chapter_info.sort_custom(self, "_sort_chapters_r")
|
chapter_info.sort_custom(self, "_sort_chapters_r")
|
||||||
|
else:
|
||||||
|
chapter_info.sort_custom(self, "_sort_chapters")
|
||||||
|
|
||||||
func _sort_chapters(a, b): return a[sort_on] < b[sort_on]
|
func _sort_chapters(a, b):
|
||||||
func _sort_chapters_r(a, b): return a[sort_on] >= b[sort_on]
|
return a[sort_on] < b[sort_on]
|
||||||
|
|
||||||
|
func _sort_chapters_r(a, b):
|
||||||
|
return a[sort_on] > b[sort_on]
|
||||||
|
|
||||||
func _redraw():
|
func _redraw():
|
||||||
clear()
|
clear()
|
||||||
|
|
||||||
var c1 = Color.white.darkened(.4)
|
var c1 = Color.white.darkened(.4)
|
||||||
var c2 = Color.white.darkened(.3)
|
var c2 = Color.white.darkened(.3)
|
||||||
|
var ch1 = lerp(c1, Color.yellowgreen, .5)
|
||||||
|
var ch2 = lerp(c2, Color.yellowgreen, .5)
|
||||||
|
|
||||||
|
var cols = ["id", "chaps", "words", "uwords", "%", "modified"]
|
||||||
push_align(RichTextLabel.ALIGN_CENTER)
|
push_align(RichTextLabel.ALIGN_CENTER)
|
||||||
push_table(3)
|
push_table(len(cols))
|
||||||
for id in ["id", "words", "unique"]:
|
add_constant_override("table_hseparation", 8)
|
||||||
|
|
||||||
|
for id in cols:
|
||||||
push_cell()
|
push_cell()
|
||||||
push_bold()
|
push_bold()
|
||||||
push_meta(add_meta(["sort_table", id], "sort on %s" % id))
|
push_meta(add_meta(["sort_table", id], "sort on %s" % id))
|
||||||
add_text(id)
|
add_text(id)
|
||||||
if sort_on == id:
|
if sort_on == id:
|
||||||
push_color(Color.white.darkened(.5))
|
push_color(Color.greenyellow.darkened(.25))
|
||||||
|
add_text(" ⯅" if sort_reverse[id] else " ⯆")
|
||||||
|
pop()
|
||||||
|
else:
|
||||||
|
push_color(Color.white.darkened(.7))
|
||||||
add_text(" ⯅" if sort_reverse[id] else " ⯆")
|
add_text(" ⯅" if sort_reverse[id] else " ⯆")
|
||||||
pop()
|
pop()
|
||||||
pop()
|
pop()
|
||||||
@ -124,26 +193,50 @@ func _redraw():
|
|||||||
|
|
||||||
for i in len(chapter_info):
|
for i in len(chapter_info):
|
||||||
var item = chapter_info[i]
|
var item = chapter_info[i]
|
||||||
|
|
||||||
if item.id == "NOH" and not item.words:
|
|
||||||
continue
|
|
||||||
|
|
||||||
var clr = c1 if i%2==0 else c2
|
var clr = c1 if i%2==0 else c2
|
||||||
|
var clrh = ch1 if i%2==0 else ch2
|
||||||
|
|
||||||
# id
|
# id
|
||||||
push_cell()
|
push_cell()
|
||||||
push_color(clr)
|
push_color(clrh if sort_on_index == 0 else clr)
|
||||||
push_meta(add_meta(["goto", item.path, item.line], item.path))
|
push_meta(add_meta(["goto", item.path, item.line], item.path + "\n" + item.uwords_all))
|
||||||
add_text(item.id)
|
add_text(item.id)
|
||||||
pop()
|
pop()
|
||||||
pop()
|
pop()
|
||||||
pop()
|
pop()
|
||||||
|
|
||||||
# word cound
|
# chapters
|
||||||
for w in ["words", "unique"]:
|
|
||||||
push_cell()
|
push_cell()
|
||||||
push_color(clr)
|
push_color(clrh if sort_on_index == 1 else clr)
|
||||||
add_text(TE_Util.commas(item[w]))
|
add_text(TE_Util.commas(item.chaps))
|
||||||
|
pop()
|
||||||
|
pop()
|
||||||
|
|
||||||
|
# word cound
|
||||||
|
push_cell()
|
||||||
|
push_color(clrh if sort_on_index == 2 else clr)
|
||||||
|
add_text(TE_Util.commas(item.words))
|
||||||
|
pop()
|
||||||
|
pop()
|
||||||
|
|
||||||
|
# unique words
|
||||||
|
push_cell()
|
||||||
|
push_color(clrh if sort_on_index == 3 else clr)
|
||||||
|
add_text(item.uwords)
|
||||||
|
pop()
|
||||||
|
pop()
|
||||||
|
|
||||||
|
# percent
|
||||||
|
push_cell()
|
||||||
|
push_color(clrh if sort_on_index == 4 else clr)
|
||||||
|
add_text(str(int(item["%"])))
|
||||||
|
pop()
|
||||||
|
pop()
|
||||||
|
|
||||||
|
# time
|
||||||
|
push_cell()
|
||||||
|
push_color(clrh if sort_on_index == 5 else clr)
|
||||||
|
add_text(item.time_nice)
|
||||||
pop()
|
pop()
|
||||||
pop()
|
pop()
|
||||||
|
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
tool
|
tool
|
||||||
extends "res://addons/text_editor/TE_RichTextLabel.gd"
|
extends "res://addons/text_editor/TE_RichTextLabel.gd"
|
||||||
|
|
||||||
onready var line_edit:LineEdit = get_parent().get_node("le")
|
onready var line_edit:LineEdit = get_parent().get_node("c/le")
|
||||||
|
onready var all_toggle:CheckBox = get_parent().get_node("c/all")
|
||||||
|
onready var case_toggle:CheckBox = get_parent().get_node("c/case")
|
||||||
|
|
||||||
var console_urls:Array = []
|
var console_urls:Array = []
|
||||||
var last_search:String = ""
|
var last_search:String = ""
|
||||||
@ -10,26 +12,33 @@ func _ready():
|
|||||||
var _e
|
var _e
|
||||||
_e = line_edit.connect("text_entered", self, "_text_entered")
|
_e = line_edit.connect("text_entered", self, "_text_entered")
|
||||||
|
|
||||||
|
# fix fonts
|
||||||
line_edit.add_font_override("font", editor.FONT_R)
|
line_edit.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)
|
||||||
|
|
||||||
func _unhandled_key_input(e):
|
func select():
|
||||||
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_focus()
|
||||||
line_edit.grab_click_focus()
|
line_edit.grab_click_focus()
|
||||||
get_parent().get_parent().show()
|
line_edit.select_all()
|
||||||
get_parent().get_parent().current_tab = get_index()
|
|
||||||
get_tree().set_input_as_handled()
|
|
||||||
|
|
||||||
func _clicked(args):
|
func _clicked(args):
|
||||||
match args[0]:
|
match args[0]:
|
||||||
"goto":
|
"goto":
|
||||||
var tab = editor.open_file(args[1])
|
var tab:TextEdit = editor.open_file(args[1])
|
||||||
editor.select_file(args[1])
|
editor.select_file(args[1])
|
||||||
tab.goto_line(int(args[2]))
|
yield(get_tree(), "idle_frame")
|
||||||
|
# goto 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[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):
|
func _text_entered(search_for:String):
|
||||||
last_search = search_for
|
last_search = search_for
|
||||||
@ -44,61 +53,111 @@ func _text_entered(search_for:String):
|
|||||||
|
|
||||||
var file_path:String = fpaths[k]
|
var file_path:String = fpaths[k]
|
||||||
var l = clr("%s/%s " % [k+1, len(fpaths)], Color.orange) + clr(file_path.get_file(), Color.yellow)
|
var l = clr("%s/%s " % [k+1, len(fpaths)], Color.orange) + clr(file_path.get_file(), Color.yellow)
|
||||||
l = meta(l, ["goto", file_path, 0], file_path)
|
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)+1)
|
# var midd:String = line.substr(char_index, len(search_for))
|
||||||
var tail:String = line.substr(char_index+len(search_for)+1)
|
# var tail:String = line.substr(char_index+len(search_for))
|
||||||
head = clr(head, Color.tomato.lightened(.5))
|
# head = clr(head, Color.white.darkened(.25))
|
||||||
midd = clr(midd, Color.tomato.darkened(.25))
|
# midd = b(clr(midd, Color.white))
|
||||||
tail = clr(tail, Color.tomato.lightened(.5))
|
# tail = clr(tail, Color.white.darkened(.25))
|
||||||
l = "\t" + clr(str(line_index-2+i+1) + ": ", Color.tomato.lightened(.5)) + (head+midd+tail)
|
|
||||||
|
|
||||||
elif line_index-2+i >= 0:
|
var h = TE_Util.highlight(ltext, char_index, len(search_for), Color.white.darkened(.25), Color.white)
|
||||||
l = "\t" + clr(str(line_index-2+i+1) + ": ", Color.gray) + got_lines[i]
|
|
||||||
|
l = "\t" + clr(str(lindex) + ": ", Color.white.darkened(.25)) + h
|
||||||
|
|
||||||
|
else:
|
||||||
|
l = "\t" + clr(str(lindex) + ": ", Color.white.darkened(.65)) + clr(ltext, Color.white.darkened(.5))
|
||||||
|
|
||||||
if l:
|
if l:
|
||||||
l = meta(l, ["goto", file_path, line_index])
|
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"))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# get a list of files containging lines
|
# get a list of files containging lines
|
||||||
func _search(search_for:String) -> Dictionary:
|
func _search(search_for:String) -> Dictionary:
|
||||||
var found = {}
|
var out = {}
|
||||||
var search_for_l = search_for.to_lower() # lowercase. TODO: match case
|
var search_for_l:String
|
||||||
for path in editor.file_paths:
|
|
||||||
|
if case_toggle.pressed:
|
||||||
|
search_for_l = search_for
|
||||||
|
else:
|
||||||
|
search_for_l = search_for.to_lower()
|
||||||
|
|
||||||
|
var paths:Array
|
||||||
|
|
||||||
|
# search all
|
||||||
|
if all_toggle.pressed:
|
||||||
|
paths = editor.file_paths
|
||||||
|
|
||||||
|
# only search selected
|
||||||
|
else:
|
||||||
|
var sel = editor.get_selected_file()
|
||||||
|
if not sel:
|
||||||
|
var err_msg = "no file open to search"
|
||||||
|
editor.console.err(err_msg)
|
||||||
|
push_error(err_msg)
|
||||||
|
return out
|
||||||
|
|
||||||
|
else:
|
||||||
|
paths = [sel]
|
||||||
|
|
||||||
|
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):
|
||||||
var line:String = lines[line_index].to_lower()
|
var line:String = lines[line_index]
|
||||||
|
|
||||||
|
# make lowercase, if case doesn't matter
|
||||||
|
if not case_toggle.pressed:
|
||||||
|
line = line.to_lower()
|
||||||
|
|
||||||
# find index where result is found
|
# find index where result is found
|
||||||
var char_index:int = line.find(search_for_l)
|
var char_index:int = line.find(search_for_l)
|
||||||
if char_index != -1:
|
if char_index != -1:
|
||||||
if not path in found:
|
if not path in out:
|
||||||
found[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.
|
|
||||||
for i in range(-2, 3):
|
# previous few lines before a blank
|
||||||
if line_index+i >= 0 and line_index+i < len(lines):
|
for i in range(1, 3):
|
||||||
preview_lines.append(lines[line_index+i])
|
if line_index-i >= 0:
|
||||||
else:
|
if not lines[line_index-i].strip_edges():
|
||||||
preview_lines.append("")
|
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
|
# lines, index in file, index in line
|
||||||
found[path].append([preview_lines, line_index, char_index])
|
out[path].append([preview_lines, highlight_from, line_index, char_index])
|
||||||
return found
|
|
||||||
|
return out
|
||||||
|
3
addons/text_editor/TE_StopWords.gd
Normal file
@ -1,10 +1,26 @@
|
|||||||
tool
|
tool
|
||||||
extends "res://addons/text_editor/TE_RichTextLabel.gd"
|
extends "res://addons/text_editor/TE_RichTextLabel.gd"
|
||||||
|
|
||||||
|
var hscrolls:Dictionary = {}
|
||||||
|
var selected_line:int = 0
|
||||||
|
var current_file:String = ""
|
||||||
|
|
||||||
|
var filter:String = ""
|
||||||
|
export var p_filter:NodePath
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
var _e
|
var _e
|
||||||
_e = editor.connect("symbols_updated", self, "_redraw")
|
_e = editor.connect("symbols_updated", self, "_redraw")
|
||||||
_e = editor.connect("tags_updated", self, "_redraw")
|
_e = editor.connect("tags_updated", self, "_redraw")
|
||||||
|
_e = editor.connect("file_selected", self, "_file_selected")
|
||||||
|
_e = editor.connect("file_closed", self, "_file_closed")
|
||||||
|
_e = editor.connect("file_renamed", self, "_file_renamed")
|
||||||
|
_e = editor.connect("selected_symbol_line", self, "_selected_symbol_line")
|
||||||
|
_e = get_v_scroll().connect("value_changed", self, "_scrolling")
|
||||||
|
|
||||||
|
var le:LineEdit = get_node(p_filter)
|
||||||
|
_e = le.connect("text_changed", self, "_filter_changed")
|
||||||
|
le.add_font_override("font", editor.FONT_R)
|
||||||
|
|
||||||
add_font_override("normal_font", editor.FONT_R)
|
add_font_override("normal_font", editor.FONT_R)
|
||||||
add_font_override("bold_font", editor.FONT_B)
|
add_font_override("bold_font", editor.FONT_B)
|
||||||
@ -13,8 +29,61 @@ func _ready():
|
|||||||
|
|
||||||
call_deferred("_redraw")
|
call_deferred("_redraw")
|
||||||
|
|
||||||
|
func _filter_changed(t:String):
|
||||||
|
filter = t.to_lower()
|
||||||
|
_redraw()
|
||||||
|
|
||||||
|
func _selected_symbol_line(line:int):
|
||||||
|
selected_line = clamp(line, 0, get_line_count())
|
||||||
|
scroll_to_line(clamp(line-1, 0, get_line_count()-1))
|
||||||
|
_redraw()
|
||||||
|
|
||||||
|
func _file_selected(file_path:String):
|
||||||
|
current_file = file_path
|
||||||
|
yield(get_tree(), "idle_frame")
|
||||||
|
get_v_scroll().value = hscrolls.get(file_path, 0)
|
||||||
|
|
||||||
|
func _file_renamed(old:String, new:String):
|
||||||
|
current_file = new
|
||||||
|
yield(get_tree(), "idle_frame")
|
||||||
|
_redraw()
|
||||||
|
|
||||||
|
func _file_closed(file_path:String):
|
||||||
|
if file_path == current_file:
|
||||||
|
current_file = ""
|
||||||
|
_redraw()
|
||||||
|
|
||||||
|
func _scrolling(v):
|
||||||
|
hscrolls[editor.get_selected_file()] = get_v_scroll().value
|
||||||
|
|
||||||
func _clicked(args:Array):
|
func _clicked(args:Array):
|
||||||
var te:TextEdit = editor.get_selected_tab()
|
var te:TextEdit = editor.get_selected_tab()
|
||||||
|
|
||||||
|
# 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])
|
te.goto_line(args[1])
|
||||||
|
|
||||||
func _redraw():
|
func _redraw():
|
||||||
@ -37,22 +106,37 @@ func _redraw():
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
var t = PoolStringArray()
|
var t = PoolStringArray()
|
||||||
|
var i = -1
|
||||||
for line_index in symbols:
|
for line_index in symbols:
|
||||||
|
i += 1
|
||||||
if line_index == -1:
|
if line_index == -1:
|
||||||
continue # special file chapter
|
continue # special file chapter
|
||||||
|
|
||||||
var symbol_info = symbols[line_index]
|
var symbol_info = symbols[line_index]
|
||||||
var deep = symbol_info.deep
|
var deep = symbol_info.deep
|
||||||
var space = "" if not deep else clr("-".repeat(deep), Color.white.darkened(.75))
|
var space = "" if not deep else clr("-".repeat(deep), Color.white.darkened(.75))
|
||||||
var cl = Color.deepskyblue if deep == 0 else Color.white
|
var cl = Color.white
|
||||||
|
|
||||||
|
if filter and not filter in symbol_info.name.to_lower():
|
||||||
|
continue
|
||||||
|
|
||||||
|
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):
|
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(", ")
|
||||||
t.append(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:
|
||||||
|
text = b(u(text))
|
||||||
|
|
||||||
|
t.append(text)
|
||||||
|
|
||||||
set_bbcode(t.join("\n"))
|
set_bbcode(t.join("\n"))
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
tool
|
tool
|
||||||
extends TabContainer
|
extends TabContainer
|
||||||
|
|
||||||
onready var editor:TE_TextEditor = owner
|
onready var editor:TE_Editor = owner
|
||||||
|
|
||||||
var mouse_over:bool = false
|
var mouse_over:bool = false
|
||||||
|
|
||||||
|
@ -16,40 +16,37 @@ func _ready():
|
|||||||
theme.set_font("font", "TooltipLabel", editor.FONT_R)
|
theme.set_font("font", "TooltipLabel", editor.FONT_R)
|
||||||
|
|
||||||
call_deferred("_redraw")
|
call_deferred("_redraw")
|
||||||
#
|
|
||||||
#func _hovered(index):
|
|
||||||
# var tag = tag_indices[int(index)]
|
|
||||||
# var count = editor.tag_counts[tag]
|
|
||||||
# hint_tooltip =
|
|
||||||
|
|
||||||
#func _unhover(t):
|
|
||||||
# hint_tooltip = ""
|
|
||||||
|
|
||||||
func _clicked(args:Array):
|
func _clicked(args:Array):
|
||||||
var tag = args[0]
|
var tag = args[0]
|
||||||
editor.enable_tag(tag, not editor.is_tag_enabled(tag))
|
var was_enabled = editor.is_tag_enabled(tag)
|
||||||
|
|
||||||
func sort_tags(tags:Dictionary):
|
if not Input.is_key_pressed(KEY_CONTROL):
|
||||||
var sorter:Array = []
|
editor.tags_enabled.clear()
|
||||||
for tag in tags:
|
|
||||||
sorter.append([tag, tags[tag]])
|
|
||||||
|
|
||||||
sorter.sort_custom(self, "_sort_tags")
|
editor.enable_tag(tag, not was_enabled)
|
||||||
|
|
||||||
tags.clear()
|
#func sort_tags(tags:Dictionary):
|
||||||
for item in sorter:
|
# var sorter:Array = []
|
||||||
tags[item[0]] = item[1]
|
# for tag in tags:
|
||||||
return tags
|
# sorter.append([tag, tags[tag]])
|
||||||
|
#
|
||||||
func _sort_tags(a, b):
|
# sorter.sort_custom(self, "_sort_tags")
|
||||||
return a[0] < b[0]
|
#
|
||||||
|
# tags.clear()
|
||||||
|
# for item in sorter:
|
||||||
|
# tags[item[0]] = item[1]
|
||||||
|
# return tags
|
||||||
|
#
|
||||||
|
#func _sort_tags(a, b):
|
||||||
|
# return a[0] < b[0]
|
||||||
|
|
||||||
func _redraw():
|
func _redraw():
|
||||||
var tab = editor.get_selected_tab()
|
var tab = editor.get_selected_tab()
|
||||||
var tags = editor.tag_counts
|
var tags = editor.tags
|
||||||
var tab_tags = {} if not tab else tab.tags
|
var tab_tags = {} if not tab else tab.tags
|
||||||
|
|
||||||
sort_tags(tags)
|
# sort_tags(tags)
|
||||||
|
|
||||||
if not tags:
|
if not tags:
|
||||||
set_bbcode("[color=#%s][i][center]*No tags*" % [Color.webgray.to_html()])
|
set_bbcode("[color=#%s][i][center]*No tags*" % [Color.webgray.to_html()])
|
||||||
@ -59,7 +56,7 @@ func _redraw():
|
|||||||
var count_color1 = Color.tomato.to_html()
|
var count_color1 = Color.tomato.to_html()
|
||||||
var count_color2 = Color.tomato.darkened(.75).to_html()
|
var count_color2 = Color.tomato.darkened(.75).to_html()
|
||||||
for tag in tags:
|
for tag in tags:
|
||||||
var count = editor.tag_counts[tag]
|
var count = editor.tags[tag]
|
||||||
var enabled = editor.is_tag_enabled(tag)
|
var enabled = editor.is_tag_enabled(tag)
|
||||||
|
|
||||||
var x = tag
|
var x = tag
|
||||||
|
@ -1,5 +1,77 @@
|
|||||||
class_name TE_Util
|
class_name TE_Util
|
||||||
|
|
||||||
|
class Sorter:
|
||||||
|
var d:Dictionary
|
||||||
|
var a:Array = []
|
||||||
|
|
||||||
|
func _init(dict:Dictionary):
|
||||||
|
d = dict
|
||||||
|
for k in d:
|
||||||
|
a.append([k, d[k]])
|
||||||
|
|
||||||
|
func on_keys(reverse:bool=false):
|
||||||
|
a.sort_custom(self, "_sort_keys_rev" if reverse else "_sort_keys")
|
||||||
|
return _out()
|
||||||
|
|
||||||
|
func on_vals(reverse:bool=false):
|
||||||
|
a.sort_custom(self, "_sort_vals_rev" if reverse else "_sort_vals")
|
||||||
|
return _out()
|
||||||
|
|
||||||
|
func _sort_keys(a, b): return a[0] > b[0]
|
||||||
|
func _sort_keys_rev(a, b): return a[0] < b[0]
|
||||||
|
func _sort_vals(a, b): return a[1] > b[1]
|
||||||
|
func _sort_vals_rev(a, b): return a[1] < b[1]
|
||||||
|
|
||||||
|
func _out() -> Dictionary:
|
||||||
|
d.clear()
|
||||||
|
for item in a:
|
||||||
|
d[item[0]] = item[1]
|
||||||
|
return d
|
||||||
|
|
||||||
|
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, 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 stop_words and word in TE_StopWords.STOP_WORDS: continue
|
||||||
|
if skip_words and word in skip_words: continue
|
||||||
|
|
||||||
|
word_count += 1
|
||||||
|
|
||||||
|
if not word in counter:
|
||||||
|
counter[word] = 1
|
||||||
|
else:
|
||||||
|
counter[word] += 1
|
||||||
|
|
||||||
|
return word_count
|
||||||
|
|
||||||
|
static func _sanitize_word(word:String):
|
||||||
|
var out = ""
|
||||||
|
var has_letter = false
|
||||||
|
|
||||||
|
for c in word.to_lower():
|
||||||
|
if c in "abcdefghijklmnopqrstuvwxyz":
|
||||||
|
out += c
|
||||||
|
has_letter = true
|
||||||
|
|
||||||
|
elif c in "-'0123456789":
|
||||||
|
out += c
|
||||||
|
|
||||||
|
if not has_letter:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
if out.ends_with("'s"):
|
||||||
|
return out.substr(0, len(out)-2)
|
||||||
|
|
||||||
|
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):
|
||||||
@ -21,6 +93,16 @@ static func load_json(path:String, loud:bool=false) -> Dictionary:
|
|||||||
push_error("no json at \"%s\"" % path)
|
push_error("no json at \"%s\"" % path)
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
static func load_image(path:String) -> ImageTexture:
|
||||||
|
var f:File = File.new()
|
||||||
|
if f.file_exists(path):
|
||||||
|
var image:Image = Image.new()
|
||||||
|
image.load(path)
|
||||||
|
var texture:ImageTexture = ImageTexture.new()
|
||||||
|
texture.create_from_image(image)
|
||||||
|
return texture
|
||||||
|
return null
|
||||||
|
|
||||||
static func save_json(path:String, data:Dictionary):
|
static func save_json(path:String, data:Dictionary):
|
||||||
var f:File = File.new()
|
var f:File = File.new()
|
||||||
f.open(path, File.WRITE)
|
f.open(path, File.WRITE)
|
||||||
@ -57,23 +139,55 @@ static func get_whitespace_tail(t:String):
|
|||||||
var length = len(t) - len(t.strip_edges(false, true))
|
var length = len(t) - len(t.strip_edges(false, true))
|
||||||
return t.substr(len(t)-length)
|
return t.substr(len(t)-length)
|
||||||
|
|
||||||
static func dig(d, obj:Object, fname:String):
|
const _dig = {depth=0}
|
||||||
var f = funcref(obj, fname)
|
|
||||||
if d is Dictionary:
|
|
||||||
_dig_dict(d, f)
|
|
||||||
elif d is Node:
|
|
||||||
_dig_node(d, f)
|
|
||||||
|
|
||||||
static func _dig_dict(d:Dictionary, f:FuncRef):
|
static func get_dig_depth() -> int:
|
||||||
|
return _dig.depth
|
||||||
|
|
||||||
|
static func dig_for(d, property:String, value):
|
||||||
|
var depth:int = 0
|
||||||
|
if d is Dictionary:
|
||||||
|
return _dig_for_dict(d, property, value, depth)
|
||||||
|
# elif d is Node:
|
||||||
|
# return _dig_for_node(d, propert, value, depth)
|
||||||
|
return null
|
||||||
|
|
||||||
|
static func _dig_for_dict(d:Dictionary, property:String, value, depth:int):
|
||||||
|
_dig.depth = depth
|
||||||
|
if property in d and d[property] == value:
|
||||||
|
return d
|
||||||
|
for k in d:
|
||||||
|
if d[k] is Dictionary:
|
||||||
|
var got = _dig_for_dict(d[k], property, value, depth+1)
|
||||||
|
if got != null:
|
||||||
|
return got
|
||||||
|
return null
|
||||||
|
#static func _dig_for_node(d:Node, f:FuncRef, depth:int):
|
||||||
|
# _dig.depth = depth
|
||||||
|
# f.call_func(d)
|
||||||
|
# for i in d.get_child_count():
|
||||||
|
# _dig_node(d.get_child(i), f, depth+1)
|
||||||
|
|
||||||
|
static func dig(d, obj:Object, fname:String):
|
||||||
|
var f:FuncRef = funcref(obj, fname)
|
||||||
|
var depth:int = 0
|
||||||
|
if d is Dictionary:
|
||||||
|
_dig_dict(d, f, depth)
|
||||||
|
elif d is Node:
|
||||||
|
_dig_node(d, f, depth)
|
||||||
|
|
||||||
|
static func _dig_dict(d:Dictionary, f:FuncRef, depth:int):
|
||||||
|
_dig.depth = depth
|
||||||
f.call_func(d)
|
f.call_func(d)
|
||||||
for k in d:
|
for k in d:
|
||||||
if d[k] is Dictionary:
|
if d[k] is Dictionary:
|
||||||
_dig_dict(d[k], f)
|
_dig_dict(d[k], f, depth+1)
|
||||||
|
|
||||||
static func _dig_node(d:Node, f:FuncRef):
|
static func _dig_node(d:Node, f:FuncRef, depth:int):
|
||||||
|
_dig.depth = depth
|
||||||
f.call_func(d)
|
f.call_func(d)
|
||||||
for i in d.get_child_count():
|
for i in d.get_child_count():
|
||||||
_dig_node(d.get_child(i), f)
|
_dig_node(d.get_child(i), f, depth+1)
|
||||||
|
|
||||||
static func file_size(path:String) -> String:
|
static func file_size(path:String) -> String:
|
||||||
var f:File = File.new()
|
var f:File = File.new()
|
||||||
@ -86,6 +200,21 @@ 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 highlight(line:String, start:int, length:int, default_color:Color, highlight_color:Color) -> String:
|
||||||
|
var head:String = line.substr(0, start)
|
||||||
|
var midd:String = line.substr(start, length)
|
||||||
|
var tail:String = line.substr(start + length)
|
||||||
|
head = clr(head, default_color)
|
||||||
|
midd = b(clr(midd, highlight_color))
|
||||||
|
tail = clr(tail, default_color)
|
||||||
|
return head + midd + tail
|
||||||
|
|
||||||
|
static func b(t:String) -> String: return "[b]%s[/b]" % t
|
||||||
|
static func clr(t:String, c:Color) -> String: return "[color=#%s]%s[/color]" % [c.to_html(), t]
|
||||||
|
|
||||||
|
#static func saturate(c:Color, s:float=1.0, v:float=1.0) -> Color:
|
||||||
|
# return c.from_hsv(c.h, c.s * s, c.v * v, c.a)
|
||||||
|
|
||||||
#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,7 +1,7 @@
|
|||||||
[gd_scene load_steps=24 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_TextEditor.gd" type="Script" id=2]
|
[ext_resource path="res://addons/text_editor/TE_Editor.gd" type="Script" id=2]
|
||||||
[ext_resource path="res://addons/text_editor/TE_FilesList.gd" type="Script" id=3]
|
[ext_resource path="res://addons/text_editor/TE_FilesList.gd" type="Script" id=3]
|
||||||
[ext_resource path="res://addons/text_editor/TE_FileEditor.gd" type="Script" id=4]
|
[ext_resource path="res://addons/text_editor/TE_FileEditor.gd" type="Script" id=4]
|
||||||
[ext_resource path="res://addons/text_editor/TE_SymbolsList.gd" type="Script" id=5]
|
[ext_resource path="res://addons/text_editor/TE_SymbolsList.gd" type="Script" id=5]
|
||||||
@ -17,26 +17,34 @@
|
|||||||
[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=1]
|
[sub_resource type="Theme" id=8]
|
||||||
|
|
||||||
|
[sub_resource type="Theme" id=9]
|
||||||
TooltipLabel/fonts/font = ExtResource( 12 )
|
TooltipLabel/fonts/font = ExtResource( 12 )
|
||||||
|
|
||||||
[sub_resource type="Theme" id=2]
|
[sub_resource type="Theme" id=10]
|
||||||
TooltipLabel/fonts/font = ExtResource( 12 )
|
TooltipLabel/fonts/font = ExtResource( 12 )
|
||||||
|
|
||||||
[sub_resource type="Theme" id=3]
|
[sub_resource type="Theme" id=11]
|
||||||
TooltipLabel/fonts/font = ExtResource( 12 )
|
TooltipLabel/fonts/font = ExtResource( 12 )
|
||||||
|
|
||||||
[sub_resource type="Theme" id=4]
|
[sub_resource type="Theme" id=12]
|
||||||
TooltipLabel/fonts/font = ExtResource( 12 )
|
TooltipLabel/fonts/font = ExtResource( 12 )
|
||||||
|
|
||||||
[sub_resource type="Theme" id=5]
|
[sub_resource type="Theme" id=13]
|
||||||
TooltipLabel/fonts/font = ExtResource( 12 )
|
TooltipLabel/fonts/font = ExtResource( 12 )
|
||||||
|
|
||||||
[sub_resource type="Theme" id=6]
|
[sub_resource type="Theme" id=14]
|
||||||
TooltipLabel/fonts/font = ExtResource( 12 )
|
TooltipLabel/fonts/font = ExtResource( 12 )
|
||||||
|
|
||||||
[node name="text_editor" type="Control"]
|
[sub_resource type="Theme" id=15]
|
||||||
|
TooltipLabel/fonts/font = ExtResource( 12 )
|
||||||
|
|
||||||
|
[node name="editor" type="Control"]
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
@ -45,6 +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_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
|
||||||
@ -56,6 +71,7 @@ margin_right = 214.0
|
|||||||
margin_bottom = 30.0
|
margin_bottom = 30.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
|
theme = SubResource( 8 )
|
||||||
custom_fonts/font = ExtResource( 14 )
|
custom_fonts/font = ExtResource( 14 )
|
||||||
highlight_current_line = true
|
highlight_current_line = true
|
||||||
syntax_highlighting = true
|
syntax_highlighting = true
|
||||||
@ -63,6 +79,7 @@ show_line_numbers = true
|
|||||||
draw_tabs = true
|
draw_tabs = true
|
||||||
fold_gutter = true
|
fold_gutter = true
|
||||||
highlight_all_occurrences = true
|
highlight_all_occurrences = true
|
||||||
|
hiding_enabled = true
|
||||||
minimap_draw = true
|
minimap_draw = true
|
||||||
script = ExtResource( 4 )
|
script = ExtResource( 4 )
|
||||||
|
|
||||||
@ -76,33 +93,33 @@ __meta__ = {
|
|||||||
|
|
||||||
[node name="c" type="PanelContainer" parent="c"]
|
[node name="c" type="PanelContainer" parent="c"]
|
||||||
margin_right = 1024.0
|
margin_right = 1024.0
|
||||||
margin_bottom = 34.0
|
margin_bottom = 38.0
|
||||||
|
|
||||||
[node name="c" type="HBoxContainer" parent="c/c"]
|
[node name="c" type="HBoxContainer" parent="c/c"]
|
||||||
margin_left = 7.0
|
margin_left = 7.0
|
||||||
margin_top = 7.0
|
margin_top = 7.0
|
||||||
margin_right = 1017.0
|
margin_right = 1017.0
|
||||||
margin_bottom = 27.0
|
margin_bottom = 31.0
|
||||||
|
|
||||||
[node name="test" type="Button" parent="c/c/c"]
|
[node name="test" type="Button" parent="c/c/c"]
|
||||||
margin_right = 12.0
|
margin_right = 12.0
|
||||||
margin_bottom = 20.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 = 20.0
|
margin_bottom = 24.0
|
||||||
text = "file"
|
text = "file"
|
||||||
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 ]
|
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__ = {
|
__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 = 20.0
|
margin_bottom = 24.0
|
||||||
focus_mode = 2
|
focus_mode = 2
|
||||||
text = "view"
|
text = "view"
|
||||||
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 ]
|
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 ]
|
||||||
@ -110,8 +127,56 @@ __meta__ = {
|
|||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[node name="insert" type="MenuButton" parent="c/c/c"]
|
||||||
|
margin_left = 97.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 = 212.0
|
||||||
|
margin_right = 303.0
|
||||||
|
margin_bottom = 24.0
|
||||||
|
text = "tab colors"
|
||||||
|
|
||||||
|
[node name="space" type="Control" parent="c/c/c"]
|
||||||
|
margin_left = 307.0
|
||||||
|
margin_right = 971.0
|
||||||
|
margin_bottom = 24.0
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 3
|
||||||
|
|
||||||
|
[node name="progress" type="ProgressBar" parent="c/c/c"]
|
||||||
|
visible = false
|
||||||
|
margin_left = 878.0
|
||||||
|
margin_right = 978.0
|
||||||
|
margin_bottom = 24.0
|
||||||
|
rect_min_size = Vector2( 100, 0 )
|
||||||
|
size_flags_vertical = 3
|
||||||
|
|
||||||
|
[node name="version" type="Label" parent="c/c/c"]
|
||||||
|
modulate = Color( 1, 1, 1, 0.521569 )
|
||||||
|
margin_left = 975.0
|
||||||
|
margin_top = 3.0
|
||||||
|
margin_right = 1010.0
|
||||||
|
margin_bottom = 20.0
|
||||||
|
custom_fonts/font = ExtResource( 12 )
|
||||||
|
text = "v1.12"
|
||||||
|
align = 2
|
||||||
|
|
||||||
[node name="div1" type="HSplitContainer" parent="c"]
|
[node name="div1" type="HSplitContainer" parent="c"]
|
||||||
margin_top = 34.0
|
margin_top = 38.0
|
||||||
margin_right = 1024.0
|
margin_right = 1024.0
|
||||||
margin_bottom = 600.0
|
margin_bottom = 600.0
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
@ -122,7 +187,7 @@ __meta__ = {
|
|||||||
|
|
||||||
[node name="c2" type="PanelContainer" parent="c/div1"]
|
[node name="c2" type="PanelContainer" parent="c/div1"]
|
||||||
margin_right = 206.0
|
margin_right = 206.0
|
||||||
margin_bottom = 566.0
|
margin_bottom = 562.0
|
||||||
rect_min_size = Vector2( 200, 0 )
|
rect_min_size = Vector2( 200, 0 )
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
@ -131,16 +196,31 @@ size_flags_vertical = 3
|
|||||||
margin_left = 7.0
|
margin_left = 7.0
|
||||||
margin_top = 7.0
|
margin_top = 7.0
|
||||||
margin_right = 199.0
|
margin_right = 199.0
|
||||||
margin_bottom = 559.0
|
margin_bottom = 555.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
|
|
||||||
[node name="list_files" type="RichTextLabel" parent="c/div1/c2/c"]
|
[node name="c" type="VBoxContainer" parent="c/div1/c2/c"]
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
|
__meta__ = {
|
||||||
|
"_edit_use_anchors_": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[node name="filter" type="LineEdit" parent="c/div1/c2/c/c"]
|
||||||
|
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
|
||||||
|
margin_right = 192.0
|
||||||
|
margin_bottom = 548.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
theme = SubResource( 1 )
|
theme = SubResource( 9 )
|
||||||
custom_fonts/bold_italics_font = ExtResource( 13 )
|
custom_fonts/bold_italics_font = ExtResource( 13 )
|
||||||
custom_fonts/italics_font = ExtResource( 10 )
|
custom_fonts/italics_font = ExtResource( 10 )
|
||||||
custom_fonts/bold_font = ExtResource( 11 )
|
custom_fonts/bold_font = ExtResource( 11 )
|
||||||
@ -151,23 +231,24 @@ script = ExtResource( 3 )
|
|||||||
__meta__ = {
|
__meta__ = {
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
p_filter = NodePath("../filter")
|
||||||
|
|
||||||
[node name="file_popup" type="PopupMenu" parent="c/div1/c2/c/list_files"]
|
[node name="file_popup" type="PopupMenu" parent="c/div1/c2/c/c/list_files"]
|
||||||
margin_right = 20.0
|
margin_right = 20.0
|
||||||
margin_bottom = 20.0
|
margin_bottom = 20.0
|
||||||
custom_fonts/font = ExtResource( 14 )
|
custom_fonts/font = ExtResource( 14 )
|
||||||
items = [ "Rename", 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 ]
|
items = [ "Rename", 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="dir_popup" type="PopupMenu" parent="c/div1/c2/c/list_files"]
|
[node name="dir_popup" type="PopupMenu" parent="c/div1/c2/c/c/list_files"]
|
||||||
margin_right = 20.0
|
margin_right = 20.0
|
||||||
margin_bottom = 20.0
|
margin_bottom = 20.0
|
||||||
custom_fonts/font = ExtResource( 14 )
|
custom_fonts/font = ExtResource( 14 )
|
||||||
items = [ "New File", null, 0, false, false, 0, 0, null, "", false, "New Folder", null, 0, false, false, 1, 0, null, "", false, "", 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, "", null, 0, false, false, -1, 0, null, "", true, "Tint Yellow", null, 0, false, false, 4, 0, null, "", false, "Tint Red", null, 0, false, false, 5, 0, null, "", false, "Tint Blue", null, 0, false, false, 6, 0, null, "", false, "Tint Green", null, 0, false, false, 7, 0, null, "", false, "Reset Tint", null, 0, false, false, 8, 0, null, "", false ]
|
||||||
|
|
||||||
[node name="div2" type="HSplitContainer" parent="c/div1"]
|
[node name="div2" type="HSplitContainer" parent="c/div1"]
|
||||||
margin_left = 218.0
|
margin_left = 218.0
|
||||||
margin_right = 1024.0
|
margin_right = 1024.0
|
||||||
margin_bottom = 566.0
|
margin_bottom = 562.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
split_offset = -80
|
split_offset = -80
|
||||||
@ -177,7 +258,7 @@ __meta__ = {
|
|||||||
|
|
||||||
[node name="c" type="VBoxContainer" parent="c/div1/div2"]
|
[node name="c" type="VBoxContainer" parent="c/div1/div2"]
|
||||||
margin_right = 614.0
|
margin_right = 614.0
|
||||||
margin_bottom = 566.0
|
margin_bottom = 562.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
|
|
||||||
@ -190,16 +271,24 @@ script = ExtResource( 8 )
|
|||||||
|
|
||||||
[node name="c" type="VSplitContainer" parent="c/div1/div2/c"]
|
[node name="c" type="VSplitContainer" parent="c/div1/div2/c"]
|
||||||
margin_right = 614.0
|
margin_right = 614.0
|
||||||
margin_bottom = 566.0
|
margin_bottom = 562.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
split_offset = -200
|
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 = 566.0
|
margin_bottom = 375.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
size_flags_vertical = 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
|
||||||
|
custom_constants/side_margin = 0
|
||||||
custom_fonts/font = ExtResource( 12 )
|
custom_fonts/font = ExtResource( 12 )
|
||||||
tab_align = 0
|
tab_align = 0
|
||||||
drag_to_rearrange_enabled = true
|
drag_to_rearrange_enabled = true
|
||||||
@ -208,28 +297,78 @@ __meta__ = {
|
|||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="meta_tabs" type="TabContainer" parent="c/div1/div2/c/c"]
|
[node name="c" type="HBoxContainer" parent="c/div1/div2/c/c/c2"]
|
||||||
visible = false
|
margin_top = 357.0
|
||||||
margin_top = 288.0
|
|
||||||
margin_right = 614.0
|
margin_right = 614.0
|
||||||
margin_bottom = 566.0
|
margin_bottom = 375.0
|
||||||
script = ExtResource( 16 )
|
size_flags_horizontal = 3
|
||||||
|
script = ExtResource( 18 )
|
||||||
|
|
||||||
[node name="console" type="RichTextLabel" parent="c/div1/div2/c/c/meta_tabs"]
|
[node name="l" type="RichTextLabel" parent="c/div1/div2/c/c/c2/c"]
|
||||||
anchor_right = 1.0
|
margin_right = 202.0
|
||||||
anchor_bottom = 1.0
|
margin_bottom = 18.0
|
||||||
margin_left = 4.0
|
|
||||||
margin_top = 32.0
|
|
||||||
margin_right = -4.0
|
|
||||||
margin_bottom = -4.0
|
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
size_flags_vertical = 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
|
bbcode_enabled = true
|
||||||
meta_underlined = false
|
fit_content_height = true
|
||||||
script = ExtResource( 1 )
|
script = ExtResource( 19 )
|
||||||
|
|
||||||
[node name="search" type="VBoxContainer" parent="c/div1/div2/c/c/meta_tabs"]
|
[node name="m" type="RichTextLabel" parent="c/div1/div2/c/c/c2/c"]
|
||||||
visible = false
|
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 = 387.0
|
||||||
|
margin_right = 614.0
|
||||||
|
margin_bottom = 562.0
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 3
|
||||||
|
|
||||||
|
[node name="meta_tabs" type="TabContainer" parent="c/div1/div2/c/c/c"]
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 3
|
||||||
|
script = ExtResource( 16 )
|
||||||
|
__meta__ = {
|
||||||
|
"_edit_use_anchors_": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[node name="console" type="RichTextLabel" parent="c/div1/div2/c/c/c/meta_tabs"]
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
margin_left = 4.0
|
margin_left = 4.0
|
||||||
@ -238,29 +377,18 @@ margin_right = -4.0
|
|||||||
margin_bottom = -4.0
|
margin_bottom = -4.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
|
theme = SubResource( 10 )
|
||||||
[node name="le" type="LineEdit" parent="c/div1/div2/c/c/meta_tabs/search"]
|
|
||||||
margin_right = 58.0
|
|
||||||
margin_bottom = 24.0
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
custom_fonts/font = ExtResource( 12 )
|
|
||||||
|
|
||||||
[node name="rte" type="RichTextLabel" parent="c/div1/div2/c/c/meta_tabs/search"]
|
|
||||||
margin_top = 28.0
|
|
||||||
margin_right = 58.0
|
|
||||||
margin_bottom = 28.0
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
size_flags_vertical = 3
|
|
||||||
theme = SubResource( 2 )
|
|
||||||
custom_fonts/bold_italics_font = ExtResource( 13 )
|
custom_fonts/bold_italics_font = ExtResource( 13 )
|
||||||
custom_fonts/italics_font = ExtResource( 10 )
|
custom_fonts/italics_font = ExtResource( 10 )
|
||||||
custom_fonts/bold_font = ExtResource( 11 )
|
custom_fonts/bold_font = ExtResource( 11 )
|
||||||
custom_fonts/normal_font = ExtResource( 12 )
|
custom_fonts/normal_font = ExtResource( 12 )
|
||||||
bbcode_enabled = true
|
bbcode_enabled = true
|
||||||
meta_underlined = false
|
meta_underlined = false
|
||||||
script = ExtResource( 15 )
|
text = "active: False
|
||||||
|
"
|
||||||
|
script = ExtResource( 1 )
|
||||||
|
|
||||||
[node name="meta" type="RichTextLabel" parent="c/div1/div2/c/c/meta_tabs"]
|
[node name="meta" type="RichTextLabel" parent="c/div1/div2/c/c/c/meta_tabs"]
|
||||||
visible = false
|
visible = false
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
@ -270,7 +398,7 @@ margin_right = -4.0
|
|||||||
margin_bottom = -4.0
|
margin_bottom = -4.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
theme = SubResource( 3 )
|
theme = SubResource( 11 )
|
||||||
custom_constants/table_hseparation = 16
|
custom_constants/table_hseparation = 16
|
||||||
custom_fonts/bold_italics_font = ExtResource( 13 )
|
custom_fonts/bold_italics_font = ExtResource( 13 )
|
||||||
custom_fonts/italics_font = ExtResource( 10 )
|
custom_fonts/italics_font = ExtResource( 10 )
|
||||||
@ -279,7 +407,7 @@ custom_fonts/normal_font = ExtResource( 12 )
|
|||||||
bbcode_enabled = true
|
bbcode_enabled = true
|
||||||
script = ExtResource( 9 )
|
script = ExtResource( 9 )
|
||||||
|
|
||||||
[node name="sys" type="RichTextLabel" parent="c/div1/div2/c/c/meta_tabs"]
|
[node name="search" type="VBoxContainer" parent="c/div1/div2/c/c/c/meta_tabs"]
|
||||||
visible = false
|
visible = false
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
@ -289,7 +417,69 @@ margin_right = -4.0
|
|||||||
margin_bottom = -4.0
|
margin_bottom = -4.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
theme = SubResource( 4 )
|
|
||||||
|
[node name="c" type="HBoxContainer" parent="c/div1/div2/c/c/c/meta_tabs/search"]
|
||||||
|
margin_right = 606.0
|
||||||
|
margin_bottom = 27.0
|
||||||
|
|
||||||
|
[node name="le" type="LineEdit" parent="c/div1/div2/c/c/c/meta_tabs/search/c"]
|
||||||
|
margin_right = 409.0
|
||||||
|
margin_bottom = 27.0
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
custom_fonts/font = ExtResource( 12 )
|
||||||
|
|
||||||
|
[node name="all" type="CheckBox" parent="c/div1/div2/c/c/c/meta_tabs/search/c"]
|
||||||
|
margin_left = 413.0
|
||||||
|
margin_right = 504.0
|
||||||
|
margin_bottom = 27.0
|
||||||
|
custom_fonts/font = ExtResource( 12 )
|
||||||
|
text = "all files"
|
||||||
|
|
||||||
|
[node name="case" type="CheckBox" parent="c/div1/div2/c/c/c/meta_tabs/search/c"]
|
||||||
|
margin_left = 508.0
|
||||||
|
margin_right = 606.0
|
||||||
|
margin_bottom = 27.0
|
||||||
|
custom_fonts/font = ExtResource( 12 )
|
||||||
|
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 = 139.0
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 3
|
||||||
|
theme = SubResource( 12 )
|
||||||
|
custom_fonts/bold_italics_font = ExtResource( 13 )
|
||||||
|
custom_fonts/italics_font = ExtResource( 10 )
|
||||||
|
custom_fonts/bold_font = ExtResource( 11 )
|
||||||
|
custom_fonts/normal_font = ExtResource( 12 )
|
||||||
|
bbcode_enabled = true
|
||||||
|
meta_underlined = false
|
||||||
|
script = ExtResource( 15 )
|
||||||
|
|
||||||
|
[node name="sys" 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
|
||||||
|
margin_top = 32.0
|
||||||
|
margin_right = -4.0
|
||||||
|
margin_bottom = -4.0
|
||||||
|
|
||||||
|
[node name="update" type="Button" parent="c/div1/div2/c/c/c/meta_tabs/sys"]
|
||||||
|
margin_right = 606.0
|
||||||
|
margin_bottom = 23.0
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
custom_fonts/font = ExtResource( 12 )
|
||||||
|
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 = 239.0
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 3
|
||||||
|
theme = SubResource( 13 )
|
||||||
custom_constants/table_hseparation = 101
|
custom_constants/table_hseparation = 101
|
||||||
custom_fonts/bold_italics_font = ExtResource( 13 )
|
custom_fonts/bold_italics_font = ExtResource( 13 )
|
||||||
custom_fonts/italics_font = ExtResource( 10 )
|
custom_fonts/italics_font = ExtResource( 10 )
|
||||||
@ -300,10 +490,27 @@ meta_underlined = false
|
|||||||
text = "idwords ⯆unique"
|
text = "idwords ⯆unique"
|
||||||
script = ExtResource( 17 )
|
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
|
||||||
|
margin_top = 32.0
|
||||||
|
margin_right = -4.0
|
||||||
|
margin_bottom = -4.0
|
||||||
|
|
||||||
|
[node name="image" type="TextureRect" parent="c/div1/div2/c/c/c/meta_tabs/image"]
|
||||||
|
margin_right = 606.0
|
||||||
|
margin_bottom = 239.0
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 3
|
||||||
|
expand = true
|
||||||
|
stretch_mode = 6
|
||||||
|
|
||||||
[node name="c2" type="PanelContainer" parent="c/div1/div2"]
|
[node name="c2" type="PanelContainer" parent="c/div1/div2"]
|
||||||
margin_left = 626.0
|
margin_left = 626.0
|
||||||
margin_right = 806.0
|
margin_right = 806.0
|
||||||
margin_bottom = 566.0
|
margin_bottom = 562.0
|
||||||
rect_min_size = Vector2( 100, 0 )
|
rect_min_size = Vector2( 100, 0 )
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
|
|
||||||
@ -311,20 +518,38 @@ size_flags_vertical = 3
|
|||||||
margin_left = 7.0
|
margin_left = 7.0
|
||||||
margin_top = 7.0
|
margin_top = 7.0
|
||||||
margin_right = 173.0
|
margin_right = 173.0
|
||||||
margin_bottom = 559.0
|
margin_bottom = 555.0
|
||||||
custom_constants/autohide = 0
|
custom_constants/autohide = 0
|
||||||
|
split_offset = 180
|
||||||
|
|
||||||
[node name="c" type="Panel" parent="c/div1/div2/c2/c"]
|
[node name="c" type="Panel" parent="c/div1/div2/c2/c"]
|
||||||
margin_right = 166.0
|
margin_right = 166.0
|
||||||
margin_bottom = 270.0
|
margin_bottom = 448.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
|
|
||||||
[node name="list_symbols" type="RichTextLabel" parent="c/div1/div2/c2/c/c"]
|
[node name="c" type="VBoxContainer" parent="c/div1/div2/c2/c/c"]
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
|
size_flags_horizontal = 3
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
theme = SubResource( 5 )
|
__meta__ = {
|
||||||
|
"_edit_use_anchors_": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[node name="filter" type="LineEdit" parent="c/div1/div2/c2/c/c/c"]
|
||||||
|
margin_right = 166.0
|
||||||
|
margin_bottom = 27.0
|
||||||
|
custom_fonts/font = ExtResource( 12 )
|
||||||
|
clear_button_enabled = true
|
||||||
|
placeholder_text = "Symbol Filter"
|
||||||
|
|
||||||
|
[node name="list_symbols" type="RichTextLabel" parent="c/div1/div2/c2/c/c/c"]
|
||||||
|
margin_top = 31.0
|
||||||
|
margin_right = 166.0
|
||||||
|
margin_bottom = 448.0
|
||||||
|
size_flags_vertical = 3
|
||||||
|
theme = SubResource( 14 )
|
||||||
custom_fonts/bold_italics_font = ExtResource( 13 )
|
custom_fonts/bold_italics_font = ExtResource( 13 )
|
||||||
custom_fonts/italics_font = ExtResource( 10 )
|
custom_fonts/italics_font = ExtResource( 10 )
|
||||||
custom_fonts/bold_font = ExtResource( 11 )
|
custom_fonts/bold_font = ExtResource( 11 )
|
||||||
@ -337,11 +562,12 @@ script = ExtResource( 5 )
|
|||||||
__meta__ = {
|
__meta__ = {
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
p_filter = NodePath("../filter")
|
||||||
|
|
||||||
[node name="c2" type="Panel" parent="c/div1/div2/c2/c"]
|
[node name="c2" type="Panel" parent="c/div1/div2/c2/c"]
|
||||||
margin_top = 282.0
|
margin_top = 460.0
|
||||||
margin_right = 166.0
|
margin_right = 166.0
|
||||||
margin_bottom = 552.0
|
margin_bottom = 548.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
|
|
||||||
@ -350,7 +576,7 @@ anchor_right = 1.0
|
|||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
theme = SubResource( 6 )
|
theme = SubResource( 15 )
|
||||||
custom_fonts/bold_italics_font = ExtResource( 13 )
|
custom_fonts/bold_italics_font = ExtResource( 13 )
|
||||||
custom_fonts/italics_font = ExtResource( 10 )
|
custom_fonts/italics_font = ExtResource( 10 )
|
||||||
custom_fonts/bold_font = ExtResource( 11 )
|
custom_fonts/bold_font = ExtResource( 11 )
|
||||||
@ -400,3 +626,7 @@ current_path = "res://test_files/"
|
|||||||
__meta__ = {
|
__meta__ = {
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[node name="popup_tab_menu" type="PopupMenu" parent="."]
|
||||||
|
margin_right = 124.0
|
||||||
|
margin_bottom = 112.0
|
||||||
|
@ -4,12 +4,15 @@ class_name TE_ExtensionHelper
|
|||||||
|
|
||||||
var symbols:Dictionary = {}
|
var symbols:Dictionary = {}
|
||||||
|
|
||||||
|
func get_tab() -> String:
|
||||||
|
return " "
|
||||||
|
|
||||||
func generate_meta(t:TextEdit, r:RichTextLabel):
|
func generate_meta(t:TextEdit, r:RichTextLabel):
|
||||||
var chars = TE_Util.commas(len(t.text))
|
var chars = TE_Util.commas(len(t.text))
|
||||||
var words = TE_Util.commas(len(t.text.split(" ", false)))
|
var words = TE_Util.commas(len(t.text.split(" ", false)))
|
||||||
var lines = TE_Util.commas(len(TE_Util.split_many(t.text, ".?!\n", false)))
|
var lines = TE_Util.commas(len(TE_Util.split_many(t.text, ".?!\n", false)))
|
||||||
var bytes = TE_Util.file_size(t.file_path)
|
var bytes = TE_Util.file_size(t.file_path)
|
||||||
# r.add_constant_override("table_hseparation", int(r.rect_size.x / 5.0))
|
|
||||||
r.set_bbcode(r.table([
|
r.set_bbcode(r.table([
|
||||||
["chars", "words", "lines", "bytes"],
|
["chars", "words", "lines", "bytes"],
|
||||||
[chars, words, lines, bytes]
|
[chars, words, lines, bytes]
|
||||||
@ -68,6 +71,23 @@ func get_symbols(t:String) -> Dictionary:
|
|||||||
symbols = {}
|
symbols = {}
|
||||||
return symbols
|
return symbols
|
||||||
|
|
||||||
|
#func get_symbol_names(s:Dictionary):
|
||||||
|
# var out = []
|
||||||
|
# for k in s:
|
||||||
|
# if k != -1:
|
||||||
|
# out.append(s[k].name)
|
||||||
|
# return out
|
||||||
|
|
||||||
|
func get_tag_counts(s:Dictionary) -> Dictionary:
|
||||||
|
var out = {}
|
||||||
|
for k in s:
|
||||||
|
for tag in s[k].tags:
|
||||||
|
if not tag in out:
|
||||||
|
out[tag] = 1
|
||||||
|
else:
|
||||||
|
out[tag] += 1
|
||||||
|
return out
|
||||||
|
|
||||||
func apply_colors(e, t:TextEdit):
|
func apply_colors(e, t:TextEdit):
|
||||||
t.add_color_override("font_color", e.color_text)
|
t.add_color_override("font_color", e.color_text)
|
||||||
t.add_color_override("number_color", e.color_var)
|
t.add_color_override("number_color", e.color_var)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
tool
|
tool
|
||||||
extends TE_ExtensionHelper
|
extends TE_ExtensionHelper
|
||||||
|
|
||||||
func apply_colors(e:TE_TextEditor, t:TextEdit):
|
func apply_colors(e:TE_Editor, t:TextEdit):
|
||||||
.apply_colors(e, t)
|
.apply_colors(e, t)
|
||||||
# symbols
|
# symbols
|
||||||
t.add_color_region("[", "]", e.color_symbol, false)
|
t.add_color_region("[", "]", e.color_symbol, false)
|
||||||
@ -27,6 +27,7 @@ func get_symbols(t:String) -> Dictionary:
|
|||||||
# tags
|
# tags
|
||||||
elif lines[i].begins_with(";") and "#" in lines[i]:
|
elif lines[i].begins_with(";") and "#" in lines[i]:
|
||||||
for t in lines[i].substr(1).split("#"):
|
for t in lines[i].substr(1).split("#"):
|
||||||
|
t = t.strip_edges()
|
||||||
if t:
|
if t:
|
||||||
last.tags.append(t)
|
last.tags.append(t)
|
||||||
|
|
||||||
|
@ -17,33 +17,32 @@ func get_symbols(t:String):
|
|||||||
var deep = max(0, len(lines[i]) - len(lines[i].strip_edges(true, false)) - 1)
|
var deep = max(0, len(lines[i]) - len(lines[i].strip_edges(true, false)) - 1)
|
||||||
last = add_symbol(i, deep, key)
|
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]:
|
elif '"#": "' in lines[i]:
|
||||||
for tag in lines[i].split('"#": "', true, 1)[1].split('"', true, 1)[0].split("#"):
|
for tag in lines[i].split('"#": "', true, 1)[1].split('"', true, 1)[0].split("#"):
|
||||||
tag = tag.strip_edges()
|
tag = tag.strip_edges()
|
||||||
if tag:
|
if tag:
|
||||||
last.tags.append(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
|
i += 1
|
||||||
|
|
||||||
return out
|
return out
|
||||||
|
|
||||||
func apply_colors(e:TE_TextEditor, t:TextEdit):
|
func apply_colors(e:TE_Editor, t:TextEdit):
|
||||||
.apply_colors(e, t)
|
.apply_colors(e, t)
|
||||||
|
|
||||||
# vars
|
# vars
|
||||||
t.add_color_region(' "', '"', e.color_var)
|
t.add_color_region(' "', '"', e.color_varname)
|
||||||
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("true", e.color_var)
|
||||||
t.add_keyword_color("false", e.color_var)
|
t.add_keyword_color("false", e.color_var)
|
||||||
t.add_keyword_color("null", e.color_var)
|
t.add_keyword_color("null", e.color_var)
|
||||||
|
|
||||||
# comments
|
# comments
|
||||||
t.add_color_region("/*", "*/", e.color_comment)
|
# t.add_color_region("/*", "*/", e.color_comment)
|
||||||
t.add_color_region("//", "", e.color_comment, true)
|
t.add_color_region('\t"#"', ",", e.color_comment, false)
|
||||||
|
@ -1,14 +1,137 @@
|
|||||||
tool
|
tool
|
||||||
extends TE_ExtensionHelper
|
extends TE_ExtensionHelper
|
||||||
|
|
||||||
|
func generate_meta(t:TextEdit, r:RichTextLabel):
|
||||||
|
.generate_meta(t, r)
|
||||||
|
|
||||||
|
var i = 0
|
||||||
|
var meta = {}
|
||||||
|
var words = {}
|
||||||
|
var word_count = 0
|
||||||
|
var chaps = [{i=0, id="???", words={}, word_count=0 }]
|
||||||
|
while i < t.get_line_count():
|
||||||
|
var line = t.get_line(i)
|
||||||
|
|
||||||
|
# get meta
|
||||||
|
if i == 0 and line.begins_with("---"):
|
||||||
|
i += 1
|
||||||
|
while i < t.get_line_count() and not t.get_line(i).begins_with("---"):
|
||||||
|
if ":" in t.get_line(i):
|
||||||
|
var p = t.get_line(i).split(":", true, 1)
|
||||||
|
var k = p[0].strip_edges()
|
||||||
|
var v = p[1].strip_edges()
|
||||||
|
meta[k] = v
|
||||||
|
if k == "name":
|
||||||
|
chaps[-1].id = v
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
# ignore comments
|
||||||
|
elif "<!--" in line:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# ignore tables
|
||||||
|
elif "|" in line:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# ignore code
|
||||||
|
elif line.begins_with("```") or line.begins_with("~~~"):
|
||||||
|
var head = line.substr(0, 3)
|
||||||
|
i += 1
|
||||||
|
while i < t.get_line_count() and not t.get_line(i).begins_with(head):
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
# get chapter info
|
||||||
|
elif line.begins_with("#"):
|
||||||
|
var id = line.split(" ", true, 1)[1].strip_edges()
|
||||||
|
chaps.append({i=i, id=id, words={}, word_count=0 })
|
||||||
|
|
||||||
|
else:
|
||||||
|
var last = chaps[-1]
|
||||||
|
last.word_count += TE_Util.count_words(line, last.words)
|
||||||
|
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
# total words
|
||||||
|
for chap in chaps:
|
||||||
|
word_count += chap.word_count
|
||||||
|
for word in chap.words:
|
||||||
|
if not word in words:
|
||||||
|
words[word] = chap.words[word]
|
||||||
|
else:
|
||||||
|
words[word] += chap.words[word]
|
||||||
|
|
||||||
|
# sort
|
||||||
|
TE_Util.sort_vals(chap.words)
|
||||||
|
|
||||||
|
r.push_align(RichTextLabel.ALIGN_CENTER)
|
||||||
|
r.push_table(4)
|
||||||
|
for x in ["#", "id", "word %s" % word_count, "words"]:
|
||||||
|
r.push_cell()
|
||||||
|
r.push_bold()
|
||||||
|
r.add_text(x)
|
||||||
|
r.pop()
|
||||||
|
r.pop()
|
||||||
|
|
||||||
|
var index:int = 0
|
||||||
|
for chap in chaps:
|
||||||
|
|
||||||
|
if chap.id == "???" and not chap.word_count:
|
||||||
|
continue
|
||||||
|
|
||||||
|
index += 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
r.push_cell()
|
||||||
|
r.push_color(Color.webgray)
|
||||||
|
r.add_text(str(index))
|
||||||
|
r.pop()
|
||||||
|
r.pop()
|
||||||
|
|
||||||
|
r.push_cell()
|
||||||
|
r.push_color(Color.webgray)
|
||||||
|
r.add_text(chap.id)
|
||||||
|
r.pop()
|
||||||
|
r.pop()
|
||||||
|
|
||||||
|
var div = 0 if not chap.word_count or not word_count else chap.word_count / float(word_count)
|
||||||
|
div *= 100.0
|
||||||
|
div = "%" + str(stepify(div, .1))
|
||||||
|
r.push_cell()
|
||||||
|
r.push_color(Color.webgray)
|
||||||
|
r.add_text(str(chap.word_count))
|
||||||
|
r.pop()
|
||||||
|
r.push_color(Color.gray)
|
||||||
|
r.add_text(" %s" % div)
|
||||||
|
r.pop()
|
||||||
|
r.pop()
|
||||||
|
|
||||||
|
r.push_cell()
|
||||||
|
r.push_color(Color.webgray)
|
||||||
|
r.add_text(PoolStringArray(chap.words.keys()).join(" "))
|
||||||
|
r.pop()
|
||||||
|
r.pop()
|
||||||
|
|
||||||
|
r.pop()
|
||||||
|
r.pop()
|
||||||
|
|
||||||
|
func _sort(a, b):
|
||||||
|
return a[1] > b[1]
|
||||||
|
|
||||||
func toggle_comment(t:TextEdit, head:String="<!-- ", tail:String=" -->"):
|
func toggle_comment(t:TextEdit, head:String="<!-- ", tail:String=" -->"):
|
||||||
return .toggle_comment(t, head, tail)
|
return .toggle_comment(t, head, tail)
|
||||||
|
|
||||||
func apply_colors(e:TE_TextEditor, t:TextEdit):
|
func apply_colors(e:TE_Editor, t:TextEdit):
|
||||||
.apply_colors(e, t)
|
.apply_colors(e, t)
|
||||||
|
|
||||||
t.add_keyword_color("true", e.color_var)
|
var code:Color = lerp(Color.white.darkened(.5), Color.deepskyblue, .333)
|
||||||
t.add_keyword_color("false", e.color_var)
|
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)
|
||||||
|
|
||||||
# bold italic
|
# bold italic
|
||||||
t.add_color_region("***", "***", Color.tomato.darkened(.3), false)
|
t.add_color_region("***", "***", Color.tomato.darkened(.3), false)
|
||||||
@ -18,33 +141,40 @@ func apply_colors(e:TE_TextEditor, t:TextEdit):
|
|||||||
t.add_color_region("*", "*", Color.tomato.lightened(.3), false)
|
t.add_color_region("*", "*", Color.tomato.lightened(.3), false)
|
||||||
|
|
||||||
# quote
|
# quote
|
||||||
t.add_color_region("> ", "", e.color_text.darkened(.6), true)
|
t.add_color_region("> ", "", quote, true)
|
||||||
|
|
||||||
# comment
|
# comment
|
||||||
t.add_color_region("<!--", "-->", e.color_comment, false)
|
t.add_color_region("<!--", "-->", e.color_comment, false)
|
||||||
|
|
||||||
# headings
|
# non official markdown:
|
||||||
var head = e.color_symbol
|
# formatted
|
||||||
var tint1 = TE_Util.hue_shift(head, -.33)
|
t.add_color_region("{", "}", lerp(e.color_text, e.color_var, .5).darkened(.25), false)
|
||||||
var tint2 = TE_Util.hue_shift(head, .33)
|
# t.add_color_region("[", "]", lerp(e.color_text, e.color_var, .5).darkened(.25), false)
|
||||||
for i in range(1, 6):
|
# t.add_color_region("(", ")", lerp(e.color_text, e.color_var, .5).darkened(.25), false)
|
||||||
var h = "#".repeat(i)
|
if false:
|
||||||
t.add_color_region("%s *" % h, "*", tint1, true)
|
# quote
|
||||||
t.add_color_region("%s \"" % h, "\"", tint2, true)
|
t.add_color_region('"', '"', quote, false)
|
||||||
t.add_color_region("%s " % h, "*", head, true)
|
# brackets
|
||||||
|
t.add_color_region('(', ')', quote, false)
|
||||||
|
else:
|
||||||
# url links
|
# url links
|
||||||
# t.add_color_region("[]", ")", e.color_var.lightened(.5))
|
|
||||||
t.add_color_region("![", ")", e.color_var.lightened(.5))
|
t.add_color_region("![", ")", e.color_var.lightened(.5))
|
||||||
|
|
||||||
|
# headings
|
||||||
|
for i in range(1, 7):
|
||||||
|
var h = "#".repeat(i)
|
||||||
|
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
|
# lists
|
||||||
t.add_color_region("- [x", "]", Color.yellowgreen, false)
|
t.add_color_region("- [x", "]", Color.yellowgreen, false)
|
||||||
t.add_color_region("- [", " ]", e.color_text.darkened(.6), false)
|
t.add_color_region("- [", " ]", e.color_text.darkened(.6), false)
|
||||||
|
|
||||||
# code blocks
|
# code blocks
|
||||||
var code:Color = lerp(e.color_text.darkened(.5), Color.yellowgreen, .5)
|
|
||||||
t.add_color_region("```", "```", code, false)
|
t.add_color_region("```", "```", code, false)
|
||||||
t.add_color_region("~~~", "~~~", code, false)
|
t.add_color_region("~~~", "~~~", code, false)
|
||||||
|
t.add_color_region("---", "---", code, false)
|
||||||
|
|
||||||
# strikeout
|
# strikeout
|
||||||
t.add_color_region("~~", "~~", Color.tomato, false)
|
t.add_color_region("~~", "~~", Color.tomato, false)
|
||||||
@ -58,7 +188,6 @@ func apply_colors(e:TE_TextEditor, t:TextEdit):
|
|||||||
# tables
|
# tables
|
||||||
t.add_color_region("|", "", Color.tan, true)
|
t.add_color_region("|", "", Color.tan, true)
|
||||||
|
|
||||||
|
|
||||||
func get_symbols(t:String) -> Dictionary:
|
func get_symbols(t:String) -> Dictionary:
|
||||||
var out = .get_symbols(t)
|
var out = .get_symbols(t)
|
||||||
var last = add_symbol()
|
var last = add_symbol()
|
||||||
@ -66,11 +195,33 @@ func get_symbols(t:String) -> Dictionary:
|
|||||||
var i = 0
|
var i = 0
|
||||||
|
|
||||||
while i < len(lines):
|
while i < len(lines):
|
||||||
|
# initial meta data
|
||||||
|
if i == 0 and lines[i].begins_with("---"):
|
||||||
|
i += 1
|
||||||
|
while i < len(lines) and not lines[i].begins_with("---"):
|
||||||
|
if "tags: " in lines[i]:
|
||||||
|
for tag in lines[i].split("tags: ", true, 1)[1].split("#"):
|
||||||
|
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
|
||||||
|
|
||||||
|
elif lines[i].begins_with("```") or lines[i].begins_with("~~~"):
|
||||||
|
var head = lines[i].substr(0, 3)
|
||||||
|
i += 1
|
||||||
|
while i < len(lines) and not lines[i].begins_with(head):
|
||||||
|
i += 1
|
||||||
|
|
||||||
# symbols
|
# symbols
|
||||||
if lines[i].begins_with("#"):
|
elif lines[i].begins_with("#"):
|
||||||
var p = lines[i].split(" ", true, 1)
|
var p = lines[i].split(" ", true, 1)
|
||||||
var deep = len(p[0])-1
|
var deep = len(p[0])-1
|
||||||
var name = p[1].strip_edges()
|
var name = "???" if len(p) == 1 else p[1].strip_edges()
|
||||||
last = add_symbol(i, deep, name)
|
last = add_symbol(i, deep, name)
|
||||||
|
|
||||||
# tags
|
# tags
|
||||||
|
50
addons/text_editor/ext/ext_rpy.gd
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
tool
|
||||||
|
extends TE_ExtensionHelper
|
||||||
|
|
||||||
|
func get_tab() -> String:
|
||||||
|
return " "
|
||||||
|
|
||||||
|
func apply_colors(e:TE_Editor, t:TextEdit):
|
||||||
|
.apply_colors(e, t)
|
||||||
|
|
||||||
|
for k in "label menu define default scene show with play return jump call".split(" "):
|
||||||
|
t.add_keyword_color(k, e.color_symbol)
|
||||||
|
|
||||||
|
# strings
|
||||||
|
t.add_color_region('"', '"', e.color_var)
|
||||||
|
# bools
|
||||||
|
t.add_keyword_color("True", e.color_var)
|
||||||
|
t.add_keyword_color("False", e.color_var)
|
||||||
|
|
||||||
|
# comments
|
||||||
|
t.add_color_region("#", "", e.color_comment, true)
|
||||||
|
t.add_color_region("$ ", "", e.color_comment, true)
|
||||||
|
|
||||||
|
func get_symbols(t:String):
|
||||||
|
var out = .get_symbols(t)
|
||||||
|
var last = add_symbol()
|
||||||
|
var lines = t.split("\n")
|
||||||
|
var i = 0
|
||||||
|
|
||||||
|
while i < len(lines):
|
||||||
|
# symbols
|
||||||
|
if lines[i].begins_with("label "):
|
||||||
|
var key = lines[i].substr(len("label ")).strip_edges()
|
||||||
|
key = key.substr(0, len(key)-1)
|
||||||
|
last = add_symbol(i, 0, key)
|
||||||
|
|
||||||
|
elif lines[i].begins_with("menu "):
|
||||||
|
var key = lines[i].substr(len("menu ")).strip_edges()
|
||||||
|
key = key.substr(0, len(key)-1)
|
||||||
|
last = add_symbol(i, 0, key)
|
||||||
|
|
||||||
|
# tags
|
||||||
|
elif "#" in lines[i]:
|
||||||
|
var p = lines[i].rsplit("#", true, 1)[1]
|
||||||
|
if "#" in p:
|
||||||
|
for tag in p.split("#"):
|
||||||
|
last.tags.append(tag)
|
||||||
|
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
return out
|
2
addons/text_editor/ext/ext_txt.gd
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
tool
|
||||||
|
extends TE_ExtensionHelper
|
@ -1,6 +1,9 @@
|
|||||||
tool
|
tool
|
||||||
extends TE_ExtensionHelper
|
extends TE_ExtensionHelper
|
||||||
|
|
||||||
|
func get_tab() -> String:
|
||||||
|
return " "
|
||||||
|
|
||||||
func _is_commented(lines) -> bool:
|
func _is_commented(lines) -> bool:
|
||||||
for i in len(lines):
|
for i in len(lines):
|
||||||
if not lines[i].strip_edges():
|
if not lines[i].strip_edges():
|
||||||
@ -43,7 +46,7 @@ func toggle_comment(t:TextEdit, head:String="", tail:String=""):
|
|||||||
|
|
||||||
return [old, new]
|
return [old, new]
|
||||||
|
|
||||||
func apply_colors(e:TE_TextEditor, t:TextEdit):
|
func apply_colors(e:TE_Editor, t:TextEdit):
|
||||||
.apply_colors(e, t)
|
.apply_colors(e, t)
|
||||||
|
|
||||||
# strings
|
# strings
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
[ext_resource path="res://addons/text_editor/fonts/unifont-13.0.01.ttf" type="DynamicFontData" id=3]
|
[ext_resource path="res://addons/text_editor/fonts/unifont-13.0.01.ttf" type="DynamicFontData" id=3]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
|
size = 12
|
||||||
|
use_filter = true
|
||||||
font_data = ExtResource( 1 )
|
font_data = ExtResource( 1 )
|
||||||
fallback/0 = ExtResource( 3 )
|
fallback/0 = ExtResource( 3 )
|
||||||
fallback/1 = ExtResource( 2 )
|
fallback/1 = ExtResource( 2 )
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
[ext_resource path="res://addons/text_editor/fonts/unifont-13.0.01.ttf" type="DynamicFontData" id=3]
|
[ext_resource path="res://addons/text_editor/fonts/unifont-13.0.01.ttf" type="DynamicFontData" id=3]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
|
size = 12
|
||||||
|
use_filter = true
|
||||||
font_data = ExtResource( 1 )
|
font_data = ExtResource( 1 )
|
||||||
fallback/0 = ExtResource( 3 )
|
fallback/0 = ExtResource( 3 )
|
||||||
fallback/1 = ExtResource( 2 )
|
fallback/1 = ExtResource( 2 )
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
[ext_resource path="res://addons/text_editor/fonts/unifont-13.0.01.ttf" type="DynamicFontData" id=3]
|
[ext_resource path="res://addons/text_editor/fonts/unifont-13.0.01.ttf" type="DynamicFontData" id=3]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
|
size = 12
|
||||||
|
use_filter = true
|
||||||
font_data = ExtResource( 1 )
|
font_data = ExtResource( 1 )
|
||||||
fallback/0 = ExtResource( 3 )
|
fallback/0 = ExtResource( 3 )
|
||||||
fallback/1 = ExtResource( 2 )
|
fallback/1 = ExtResource( 2 )
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
[ext_resource path="res://addons/text_editor/fonts/unifont-13.0.01.ttf" type="DynamicFontData" id=3]
|
[ext_resource path="res://addons/text_editor/fonts/unifont-13.0.01.ttf" type="DynamicFontData" id=3]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
|
size = 12
|
||||||
|
use_filter = true
|
||||||
font_data = ExtResource( 1 )
|
font_data = ExtResource( 1 )
|
||||||
fallback/0 = ExtResource( 3 )
|
fallback/0 = ExtResource( 3 )
|
||||||
fallback/1 = ExtResource( 2 )
|
fallback/1 = ExtResource( 2 )
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
[ext_resource path="res://addons/text_editor/fonts/unifont-13.0.01.ttf" type="DynamicFontData" id=3]
|
[ext_resource path="res://addons/text_editor/fonts/unifont-13.0.01.ttf" type="DynamicFontData" id=3]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
|
size = 12
|
||||||
|
use_filter = true
|
||||||
font_data = ExtResource( 1 )
|
font_data = ExtResource( 1 )
|
||||||
fallback/0 = ExtResource( 3 )
|
fallback/0 = ExtResource( 3 )
|
||||||
fallback/1 = ExtResource( 2 )
|
fallback/1 = ExtResource( 2 )
|
||||||
|
BIN
addons/text_editor/icons/icon_blue.png
Normal file
After Width: | Height: | Size: 478 B |
35
addons/text_editor/icons/icon_blue.png.import
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="StreamTexture"
|
||||||
|
path="res://.import/icon_blue.png-4b6f1e67dbe59cc990b970ce70a743ca.stex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/text_editor/icons/icon_blue.png"
|
||||||
|
dest_files=[ "res://.import/icon_blue.png-4b6f1e67dbe59cc990b970ce70a743ca.stex" ]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_mode=0
|
||||||
|
compress/bptc_ldr=0
|
||||||
|
compress/normal_map=0
|
||||||
|
flags/repeat=0
|
||||||
|
flags/filter=true
|
||||||
|
flags/mipmaps=false
|
||||||
|
flags/anisotropic=false
|
||||||
|
flags/srgb=2
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/HDR_as_SRGB=false
|
||||||
|
process/invert_color=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
stream=false
|
||||||
|
size_limit=0
|
||||||
|
detect_3d=true
|
||||||
|
svg/scale=1.0
|
BIN
addons/text_editor/icons/icon_green.png
Normal file
After Width: | Height: | Size: 478 B |
35
addons/text_editor/icons/icon_green.png.import
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="StreamTexture"
|
||||||
|
path="res://.import/icon_green.png-01008ffea524815bdbefdafa2b021148.stex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/text_editor/icons/icon_green.png"
|
||||||
|
dest_files=[ "res://.import/icon_green.png-01008ffea524815bdbefdafa2b021148.stex" ]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_mode=0
|
||||||
|
compress/bptc_ldr=0
|
||||||
|
compress/normal_map=0
|
||||||
|
flags/repeat=0
|
||||||
|
flags/filter=true
|
||||||
|
flags/mipmaps=false
|
||||||
|
flags/anisotropic=false
|
||||||
|
flags/srgb=2
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/HDR_as_SRGB=false
|
||||||
|
process/invert_color=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
stream=false
|
||||||
|
size_limit=0
|
||||||
|
detect_3d=true
|
||||||
|
svg/scale=1.0
|
BIN
addons/text_editor/icons/icon_red.png
Normal file
After Width: | Height: | Size: 478 B |
35
addons/text_editor/icons/icon_red.png.import
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="StreamTexture"
|
||||||
|
path="res://.import/icon_red.png-68ce187cb535e9b040383f41e156a86c.stex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/text_editor/icons/icon_red.png"
|
||||||
|
dest_files=[ "res://.import/icon_red.png-68ce187cb535e9b040383f41e156a86c.stex" ]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_mode=0
|
||||||
|
compress/bptc_ldr=0
|
||||||
|
compress/normal_map=0
|
||||||
|
flags/repeat=0
|
||||||
|
flags/filter=true
|
||||||
|
flags/mipmaps=false
|
||||||
|
flags/anisotropic=false
|
||||||
|
flags/srgb=2
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/HDR_as_SRGB=false
|
||||||
|
process/invert_color=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
stream=false
|
||||||
|
size_limit=0
|
||||||
|
detect_3d=true
|
||||||
|
svg/scale=1.0
|
BIN
addons/text_editor/icons/icon_yellow.png
Normal file
After Width: | Height: | Size: 478 B |
35
addons/text_editor/icons/icon_yellow.png.import
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="StreamTexture"
|
||||||
|
path="res://.import/icon_yellow.png-4fd0044497c78a10c7a9305f6c12f846.stex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/text_editor/icons/icon_yellow.png"
|
||||||
|
dest_files=[ "res://.import/icon_yellow.png-4fd0044497c78a10c7a9305f6c12f846.stex" ]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_mode=0
|
||||||
|
compress/bptc_ldr=0
|
||||||
|
compress/normal_map=0
|
||||||
|
flags/repeat=0
|
||||||
|
flags/filter=true
|
||||||
|
flags/mipmaps=false
|
||||||
|
flags/anisotropic=false
|
||||||
|
flags/srgb=2
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/HDR_as_SRGB=false
|
||||||
|
process/invert_color=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
stream=false
|
||||||
|
size_limit=0
|
||||||
|
detect_3d=true
|
||||||
|
svg/scale=1.0
|
@ -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.4"
|
version="1.12"
|
||||||
script="plugin.gd"
|
script="plugin.gd"
|
||||||
|
3
addons/text_editor/te_empty_style.tres
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[gd_resource type="StyleBoxEmpty" format=2]
|
||||||
|
|
||||||
|
[resource]
|
3
default_bus_layout.tres
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[gd_resource type="AudioBusLayout" format=2]
|
||||||
|
|
||||||
|
[resource]
|