108 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			108 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from textual.app import App
 | |
| from pathlib import Path
 | |
| import os
 | |
| import configparser
 | |
| from typing import Any
 | |
| 
 | |
| 
 | |
| class ConfigHandler:
 | |
| 	def __init__(self, app: App):
 | |
| 		self.app: App = app
 | |
| 		self.config: configparser.ConfigParser = configparser.ConfigParser()
 | |
| 		
 | |
| 		self.plugin_defined_settings = {}
 | |
| 		self.config_dir: str = self.ensure_hidden_config_dir()
 | |
| 		self.load_settings()
 | |
| 
 | |
| 	def define_plugin_setting(self, plugin_name: str, option_name: str, description: str, option_type: str, default_value: Any, on_changed_func = None):
 | |
| 		actual_type = None
 | |
| 		if option_type == "boolean":
 | |
| 			actual_type = bool
 | |
| 		elif option_type == "string":
 | |
| 			actual_type = str
 | |
| 		elif option_type == "float":
 | |
| 			actual_type = float
 | |
| 		elif option_type == "integer":
 | |
| 			actual_type = int
 | |
| 		else:
 | |
| 			raise Exception(f"Invalid type name \"{option_type}\".")
 | |
| 
 | |
| 		if plugin_name in self.plugin_defined_settings:
 | |
| 			self.plugin_defined_settings[plugin_name][option_name] = {
 | |
| 				"option_name": option_name,
 | |
| 				"description": description,
 | |
| 				"type": actual_type,
 | |
| 				"default_value": default_value,
 | |
| 				"on_changed_func": on_changed_func
 | |
| 			}
 | |
| 		else:
 | |
| 			self.plugin_defined_settings[plugin_name] = {option_name: {
 | |
| 				"option_name": option_name,
 | |
| 				"description": description,
 | |
| 				"type": actual_type,
 | |
| 				"default_value": default_value,
 | |
| 				"on_changed_func": on_changed_func
 | |
| 			}}
 | |
| 
 | |
| 		# user hasnt used this plugin before
 | |
| 		if self.get("plugin_" + plugin_name, option_name) == None:
 | |
| 			self.set("plugin_" + plugin_name, option_name, default_value)
 | |
| 	
 | |
| 	def ensure_hidden_config_dir(self):
 | |
| 		config_dir = Path.home() / ".berry"
 | |
| 		config_dir.mkdir(parents=True, exist_ok=True)
 | |
| 
 | |
| 		return config_dir
 | |
| 
 | |
| 	def get(self, section: str, option: str):
 | |
| 		if not self.config.has_section(section):
 | |
| 			self.config.add_section(section)
 | |
| 		if not self.config.has_option(section, option):
 | |
| 			self.set(section, option, "0")
 | |
| 			return "0"
 | |
| 
 | |
| 		return self.config.get(section, option, fallback=None)
 | |
| 	
 | |
| 	def set(self, section: str, option: str, new_value: str):
 | |
| 		if not self.config.has_section(section):
 | |
| 			self.config.add_section(section)
 | |
| 		self.config.set(section, option, new_value)
 | |
| 
 | |
| 		if section.startswith("plugin_"):
 | |
| 			section = section.removeprefix("plugin_")
 | |
| 			if self.plugin_defined_settings[section].get("on_changed_func", None) != None:
 | |
| 				self.plugin_defined_settings[section]["on_changed_func"](new_value)
 | |
| 			
 | |
| 		self.write_settings()
 | |
| 
 | |
| 	def apply_settings(self):
 | |
| 		self.app.query_one("#code-editor").soft_wrap = bool(int(self.get("editor", "word_wrap")))
 | |
| 		self.app.theme = self.get("appearance", "colour_theme")
 | |
| 
 | |
| 	def write_settings(self):
 | |
| 		with open(self.config_dir / "config.ini", "w") as configfile:
 | |
| 			self.config.write(configfile)
 | |
| 
 | |
| 	def load_settings(self):
 | |
| 		if os.path.isfile(self.config_dir / "config.ini"):
 | |
| 			self.config.read(self.config_dir / "config.ini")
 | |
| 			return
 | |
| 
 | |
| 		self.config["config"] = {
 | |
| 			"version": "1"
 | |
| 		}
 | |
| 		self.config["editor"] = {
 | |
| 			"word_wrap": "0",
 | |
| 			"line_numbers": "1"
 | |
| 		}
 | |
| 		self.config["plugins"] = {
 | |
| 			"enabled": "1",
 | |
| 			"log": "1",
 | |
| 			"log_timeout": "10"
 | |
| 		}
 | |
| 		self.config["appearance"] = {
 | |
| 			"colour_theme": "textual-dark"
 | |
| 		}
 | |
| 
 | |
| 		with open(self.config_dir / "config.ini", "w") as configfile:
 | |
| 			self.config.write(configfile) | 
