master e5007ae892de cached
14 files
20.8 KB
5.8k tokens
1 requests
Download .txt
Repository: godot-extended-libraries/godot-plugin-refresher
Branch: master
Commit: e5007ae892de
Files: 14
Total size: 20.8 KB

Directory structure:
gitextract_17kfx187/

├── .gitattributes
├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       └── static_checks.yml
├── .gitignore
├── LICENSE
├── README.md
├── addons/
│   └── godot-plugin-refresher/
│       ├── LICENSE
│       ├── plugin.cfg
│       ├── plugin_refresher.gd
│       ├── plugin_refresher.tscn
│       └── plugin_refresher_plugin.gd
├── file_format.sh
├── icon.png.import
└── project.godot

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitattributes
================================================
# Normalize EOL for all files that Git considers text files.
* text=auto eol=lf

# Ignore everything outside of the addons folder when exporting.
/.github                   export-ignore
/.gitattributes            export-ignore
/.gitignore                export-ignore
/file_format.sh            export-ignore
/icon.png                  export-ignore
/icon.png.import           export-ignore
/LICENSE.md                export-ignore
/project.godot             export-ignore
/README.md                 export-ignore


================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "daily"


================================================
FILE: .github/workflows/static_checks.yml
================================================
name: 📊 Static Checks
on: [push, pull_request]

jobs:
  format:
    name: File formatting (file_format.sh)
    runs-on: ubuntu-20.04
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Install dependencies
        run: |
          sudo apt-get update -qq
          sudo apt-get install -qq dos2unix recode

      - name: File formatting checks (file_format.sh)
        run: |
          bash ./file_format.sh


================================================
FILE: .gitignore
================================================
# Godot 4+ specific ignores
.godot/

# Godot-specific ignores
.import/
export.cfg
export_presets.cfg

# Imported translations (automatically generated from CSV files)
*.translation

# Mono-specific ignores
.mono/
data_*/
mono_crash.*.json

# System/tool-specific ignores
.directory
*~


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2018-2021 Will Nations

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
# godot-plugin-refresher

This plugin simplifies plugin development for those wanting to make tools for the Godot Editor.

> The `master` branch supports Godot 4.2+. For Godot 4.0-4.1, see the `4.0` branch. For Godot 3, see the `3.x` branch.

The plugin adds a dropdown and refresh button to the main toolbar in the top-right corner of the Godot Editor. *Other* plugins' names will show up in the dropdown. Clicking the refresh button will toggle the plugin off and then back on. Disabled plugins still appear in the list & be toggleable (effectively just enabling them), but will ask to confirm beforehand.

Here's an example of working on a WIP internal "GodotTools" plugin amidst an in-development project:

![example of dropdown](./example_dropdown.png)

This makes it much easier to iterate on a single plugin since rather than having to...

1. Click Project Settings.
2. Go to Plugins tab (first time).
3. Find the desired plugin.
4. Click the dropdown.
5. Select the opposite option.
6. Click the dropdown again.
7. Click the original option.
8. Close the Project Settings.

You instead just...

1. Click the dropdown (first time).
2. Select your WIP plugin (first time).
3. Click the refresh button.

Please consider starring the repo if you like the project and let me know if you have any feedback for bugs / feature improvements in the Issues. If you'd like to support my work, please [send tips to my Kofi](https://ko-fi.com/willnationsdev). Cheers!


================================================
FILE: addons/godot-plugin-refresher/LICENSE
================================================
MIT License

Copyright (c) 2018-2021 Will Nations

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: addons/godot-plugin-refresher/plugin.cfg
================================================
[plugin]

name="Godot Plugin Refresher"
description="A toolbar addition to facilitate toggling off/on a selected plugin. Updated for Godot 4.3"
author="willnationsdev"
version="1.2"
script="plugin_refresher_plugin.gd"


================================================
FILE: addons/godot-plugin-refresher/plugin_refresher.gd
================================================
@tool
extends HBoxContainer

signal request_refresh_plugin(p_name: String)
signal confirm_refresh_plugin(p_name: String)

@onready var options: OptionButton = $OptionButton


func _ready() -> void:
	if get_tree().edited_scene_root == self:
		return # This is the scene opened in the editor!
	$RefreshButton.icon = EditorInterface.get_editor_theme().get_icon("Reload", "EditorIcons")


func update_items(p_plugins_info: Array) -> void:
	if not options:
		return
	options.clear()

	var plugins := p_plugins_info[0] as Dictionary
	var display_names_map := p_plugins_info[1] as Dictionary

	var plugin_dirs: Array[String] = []
	plugin_dirs.assign(plugins.keys())
	for idx in plugin_dirs.size():
		var plugin_dirname := plugin_dirs[idx]
		var plugin_data = plugins[plugin_dirname] # Array[String] used as a Tuple<String, String>.
		var plugin_name := plugin_data[0] as String
		var plugin_path := plugin_data[1] as String
		var display_name := display_names_map[plugin_path] as String

		options.add_item(display_name, idx)
		options.set_item_metadata(idx, plugin_path)


# Note: For whatever reason, statically typing `p_name` inexplicably causes
# an error about converting from Nil to String, even if the value is converted.
func select_plugin(p_name) -> void:
	if not options or not p_name:
		return

	for idx in options.get_item_count():
		var plugin := str(options.get_item_metadata(idx))
		if plugin == str(p_name):
			options.selected = options.get_item_id(idx)
			break


func _on_RefreshButton_pressed() -> void:
	if options.selected == -1:
		return # nothing selected

	var plugin := str(options.get_item_metadata(options.selected))
	if not plugin:
		return
	emit_signal("request_refresh_plugin", plugin)


func show_warning(p_name: String) -> void:
	$ConfirmationDialog.dialog_text = (
		"""
		Plugin `%s` is currently disabled.\n
		Do you want to enable it now?
	"""
		% [p_name]
	)
	$ConfirmationDialog.popup_centered()


func _on_ConfirmationDialog_confirmed() -> void:
	var plugin := options.get_item_metadata(options.selected) as String
	emit_signal("confirm_refresh_plugin", plugin)


================================================
FILE: addons/godot-plugin-refresher/plugin_refresher.tscn
================================================
[gd_scene load_steps=2 format=3 uid="uid://dnladpgp5dwts"]

[ext_resource type="Script" path="res://addons/godot-plugin-refresher/plugin_refresher.gd" id="1"]

[node name="HBoxContainer" type="HBoxContainer"]
script = ExtResource("1")

[node name="VSeparator" type="VSeparator" parent="."]
layout_mode = 2

[node name="OptionButton" type="OptionButton" parent="."]
layout_mode = 2

[node name="RefreshButton" type="Button" parent="."]
layout_mode = 2

[node name="ConfirmationDialog" type="ConfirmationDialog" parent="."]
dialog_autowrap = true

[connection signal="pressed" from="RefreshButton" to="." method="_on_RefreshButton_pressed"]
[connection signal="confirmed" from="ConfirmationDialog" to="." method="_on_ConfirmationDialog_confirmed"]


================================================
FILE: addons/godot-plugin-refresher/plugin_refresher_plugin.gd
================================================
@tool
extends EditorPlugin

const ADDONS_PATH := "res://addons/"
const PLUGIN_CONFIG_DIR := "plugins/plugin_refresher"
const PLUGIN_CONFIG := "settings.cfg"
const PLUGIN_NAME := "Godot Plugin Refresher"
const SETTINGS := "settings"
const SETTING_RECENT := "recently_used"
const Refresher := preload("plugin_refresher.gd")

var plugin_config := ConfigFile.new()
var refresher: Refresher = null


func _enter_tree() -> void:
	refresher = preload("plugin_refresher.tscn").instantiate() as Refresher
	add_control_to_container(CONTAINER_TOOLBAR, refresher)

	# Watch whether any plugin is changed, added or removed on the filesystem
	var efs := EditorInterface.get_resource_filesystem()
	efs.filesystem_changed.connect(_on_filesystem_changed)

	refresher.request_refresh_plugin.connect(_on_request_refresh_plugin)
	refresher.confirm_refresh_plugin.connect(_on_confirm_refresh_plugin)

	_reload_plugins_list()
	_load_settings()


func _exit_tree() -> void:
	remove_control_from_container(CONTAINER_TOOLBAR, refresher)
	refresher.free()


func _reload_plugins_list() -> void:
	var cfg_paths: Array[String] = []
	var plugins := {}
	var display_names_map := {} # full path to display name

	find_cfgs(ADDONS_PATH, cfg_paths)

	for cfg_path in cfg_paths:
		var plugin_cfg := ConfigFile.new()
		var err := plugin_cfg.load(cfg_path)
		if err:
			push_error("ERROR LOADING PLUGIN FILE: %s" % err)
		else:
			var plugin_name := plugin_cfg.get_value("plugin", "name")
			if plugin_name != PLUGIN_NAME:
				var addon_dir_name = cfg_path.split("addons/")[-1].split("/plugin.cfg")[0]
				plugins[addon_dir_name] = [plugin_name, cfg_path]

	# This will be an array of the addon/* directory names.
	var plugin_dirs: Array[String] = []
	plugin_dirs.assign(plugins.keys()) # typed array "casting"

	var plugin_names: Array[String] = []
	plugin_names.assign(plugin_dirs.map(func(k): return plugins[k][0]))

	for plugin_dirname in plugin_dirs:
		var plugin_name = plugins[plugin_dirname][0]
		var display_name = plugin_name if plugin_names.count(plugin_name) == 1 else "%s (%s)" % [plugin_name, plugin_dirname]
		display_names_map[plugins[plugin_dirname][1]] = display_name

	refresher.update_items([plugins, display_names_map])


func find_cfgs(dir_path: String, cfgs: Array):
	var dir := DirAccess.open(dir_path)
	var cfg_path := dir_path.path_join("plugin.cfg")

	if dir.file_exists(cfg_path):
		cfgs.append(cfg_path)
		return

	if dir:
		dir.list_dir_begin()
		var file_name := dir.get_next()
		while file_name != "":
			if dir.current_is_dir():
				find_cfgs(dir_path.path_join(file_name), cfgs)
			file_name = dir.get_next()


func _load_settings() -> void:
	var path := get_settings_path()

	if not FileAccess.file_exists(path):
		# Create new if running for the first time
		var config := ConfigFile.new()
		DirAccess.make_dir_recursive_absolute(path.get_base_dir())
		config.save(path)
	else:
		plugin_config.load(path)


func _save_settings() -> void:
	plugin_config.save(get_settings_path())


func get_settings_path() -> String:
	var editor_paths := EditorInterface.get_editor_paths()
	var dir := editor_paths.get_project_settings_dir()

	var home := dir.path_join(PLUGIN_CONFIG_DIR)
	var path := home.path_join(PLUGIN_CONFIG)

	return path


func _on_filesystem_changed() -> void:
	if refresher:
		_reload_plugins_list()
		var recent = get_recent_plugin()
		if recent:
			refresher.select_plugin(recent)


func get_recent_plugin() -> String:
	if not plugin_config.has_section_key(SETTINGS, SETTING_RECENT):
		return "" # not saved yet

	var recent = str(plugin_config.get_value(SETTINGS, SETTING_RECENT))
	return recent


func _on_request_refresh_plugin(p_path: String) -> void:
	assert(not p_path.is_empty())

	var disabled := not EditorInterface.is_plugin_enabled(p_path)
	if disabled:
		refresher.show_warning(p_path)
	else:
		refresh_plugin(p_path)


func _on_confirm_refresh_plugin(p_path: String) -> void:
	refresh_plugin(p_path)


func get_plugin_path() -> String:
	return get_script().resource_path.get_base_dir()


func refresh_plugin(p_path: String) -> void:
	print("Refreshing plugin: ", p_path)

	var enabled := EditorInterface.is_plugin_enabled(p_path)
	if enabled: # can only disable an active plugin
		EditorInterface.set_plugin_enabled(p_path, false)

	EditorInterface.set_plugin_enabled(p_path, true)

	plugin_config.set_value(SETTINGS, SETTING_RECENT, p_path)
	_save_settings()


================================================
FILE: file_format.sh
================================================
#!/usr/bin/env bash

# This script ensures proper POSIX text file formatting and a few other things.

set -uo pipefail
IFS=$'\n\t'

# Loops through all text files tracked by Git.
git grep -zIl '' |
while IFS= read -rd '' f; do
    # Ensure that files are UTF-8 formatted.
    recode UTF-8 "$f" 2> /dev/null
    # Ensure that files have LF line endings and do not contain a BOM.
    dos2unix "$f" 2> /dev/null
    # Remove trailing space characters and ensures that files end
    # with newline characters. -l option handles newlines conveniently.
    perl -i -ple 's/\s*$//g' "$f"
    # Remove the character sequence "== true" if it has a leading space.
    perl -i -pe 's/\x20== true//g' "$f"
done

git diff > patch.patch
FILESIZE="$(stat -c%s patch.patch)"
MAXSIZE=5

# If no patch has been generated all is OK, clean up, and exit.
if (( FILESIZE < MAXSIZE )); then
    printf "Files in this commit comply with the formatting rules.\n"
    rm -f patch.patch
    exit 0
fi

# A patch has been created, notify the user, clean up, and exit.
printf "\n*** The following differences were found between the code "
printf "and the formatting rules:\n\n"
cat patch.patch
printf "\n*** Aborting, please fix your commit(s) with 'git commit --amend' or 'git rebase -i <hash>'\n"
rm -f patch.patch
exit 1


================================================
FILE: icon.png.import
================================================
[remap]

importer="texture"
type="CompressedTexture2D"
uid="uid://c1hfjj7vmjkda"
path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"
metadata={
"vram_texture": false
}

[deps]

source_file="res://icon.png"
dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"]

[params]

compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1


================================================
FILE: project.godot
================================================
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
;   [section] ; section goes between []
;   param=value ; assign values to parameters

config_version=5

[application]

config/name="Godot Plugin Refresher"
run/main_scene="res://addons/godot-plugin-refresher/plugin_refresher.tscn"
config/features=PackedStringArray("4.3")
config/icon="res://icon.png"

[dotnet]

project/assembly_name="Godot Plugin Refresher"

[editor_plugins]

enabled=PackedStringArray("res://addons/godot-plugin-refresher/plugin.cfg")

[input]

ui_accept={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":0,"pressure":0.0,"pressed":false,"script":null)
]
}
ui_select={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":3,"pressure":0.0,"pressed":false,"script":null)
]
}
ui_cancel={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":1,"pressure":0.0,"pressed":false,"script":null)
]
}
ui_focus_next={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
ui_focus_prev={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
ui_left={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null)
]
}
ui_right={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":15,"pressure":0.0,"pressed":false,"script":null)
]
}
ui_up={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
]
}
ui_down={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
]
}
ui_page_up={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
ui_page_down={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
ui_home={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
ui_end={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}

[rendering]

quality/driver/driver_name="GLES2"
vram_compression/import_etc=true
vram_compression/import_etc2=false
Download .txt
gitextract_17kfx187/

├── .gitattributes
├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       └── static_checks.yml
├── .gitignore
├── LICENSE
├── README.md
├── addons/
│   └── godot-plugin-refresher/
│       ├── LICENSE
│       ├── plugin.cfg
│       ├── plugin_refresher.gd
│       ├── plugin_refresher.tscn
│       └── plugin_refresher_plugin.gd
├── file_format.sh
├── icon.png.import
└── project.godot
Condensed preview — 14 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (24K chars).
[
  {
    "path": ".gitattributes",
    "chars": 515,
    "preview": "# Normalize EOL for all files that Git considers text files.\n* text=auto eol=lf\n\n# Ignore everything outside of the addo"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 117,
    "preview": "version: 2\nupdates:\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"daily\"\n"
  },
  {
    "path": ".github/workflows/static_checks.yml",
    "chars": 439,
    "preview": "name: 📊 Static Checks\non: [push, pull_request]\n\njobs:\n  format:\n    name: File formatting (file_format.sh)\n    runs-on: "
  },
  {
    "path": ".gitignore",
    "chars": 285,
    "preview": "# Godot 4+ specific ignores\n.godot/\n\n# Godot-specific ignores\n.import/\nexport.cfg\nexport_presets.cfg\n\n# Imported transla"
  },
  {
    "path": "LICENSE",
    "chars": 1074,
    "preview": "MIT License\n\nCopyright (c) 2018-2021 Will Nations\n\nPermission is hereby granted, free of charge, to any person obtaining"
  },
  {
    "path": "README.md",
    "chars": 1462,
    "preview": "# godot-plugin-refresher\n\nThis plugin simplifies plugin development for those wanting to make tools for the Godot Editor"
  },
  {
    "path": "addons/godot-plugin-refresher/LICENSE",
    "chars": 1074,
    "preview": "MIT License\n\nCopyright (c) 2018-2021 Will Nations\n\nPermission is hereby granted, free of charge, to any person obtaining"
  },
  {
    "path": "addons/godot-plugin-refresher/plugin.cfg",
    "chars": 218,
    "preview": "[plugin]\n\nname=\"Godot Plugin Refresher\"\ndescription=\"A toolbar addition to facilitate toggling off/on a selected plugin."
  },
  {
    "path": "addons/godot-plugin-refresher/plugin_refresher.gd",
    "chars": 2096,
    "preview": "@tool\nextends HBoxContainer\n\nsignal request_refresh_plugin(p_name: String)\nsignal confirm_refresh_plugin(p_name: String)"
  },
  {
    "path": "addons/godot-plugin-refresher/plugin_refresher.tscn",
    "chars": 746,
    "preview": "[gd_scene load_steps=2 format=3 uid=\"uid://dnladpgp5dwts\"]\n\n[ext_resource type=\"Script\" path=\"res://addons/godot-plugin-"
  },
  {
    "path": "addons/godot-plugin-refresher/plugin_refresher_plugin.gd",
    "chars": 4385,
    "preview": "@tool\nextends EditorPlugin\n\nconst ADDONS_PATH := \"res://addons/\"\nconst PLUGIN_CONFIG_DIR := \"plugins/plugin_refresher\"\nc"
  },
  {
    "path": "file_format.sh",
    "chars": 1295,
    "preview": "#!/usr/bin/env bash\n\n# This script ensures proper POSIX text file formatting and a few other things.\n\nset -uo pipefail\nI"
  },
  {
    "path": "icon.png.import",
    "chars": 746,
    "preview": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://c1hfjj7vmjkda\"\npath=\"res://.godot/imported/icon.png-48"
  },
  {
    "path": "project.godot",
    "chars": 6869,
    "preview": "; Engine configuration file.\n; It's best edited using the editor UI and not directly,\n; since the parameters that go her"
  }
]

About this extraction

This page contains the full source code of the godot-extended-libraries/godot-plugin-refresher GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 14 files (20.8 KB), approximately 5.8k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!