<commit_before># -*- coding: utf-8 -*-

import os
import sublime
import sublime_plugin
import sys
import logging

log = logging.getLogger(__name__)

PACKAGE_SETTINGS = "GDL.sublime-settings"
DEFAULT_AC_PATH = "C:/Program Files/GRAPHISOFT/ARCHICAD 23"

def save_all_files():
	""" Saves all files open in Sublime.
		Mimics the 'save on build' behavior of Sublime Text.
	"""
	for window in sublime.windows():
		for view in window.views():
			if view.file_name() and view.is_dirty():
				view.run_command("save")

def get_project_data(view, invoke):
	""" Gets the data of the .sublime-project file.
		Returns additional arguments for the commandline operation,
		if the user has set any.
	"""
	# invoke options: 'to-hsf' / 'to-gsm' / 'proj_gsm_path'
	project_data = view.window().project_data()
	if not project_data:
		sublime.error_message("You must create a project first! (Project > Save Project As...)")
		return

	project_settings = project_data.get('cmdargs', {})
	if type(project_settings) is dict:
		# check if dict is empty
		if bool(project_settings):
			return project_settings.get(invoke, "")
		else:
			# dict is empty, which means user hasn't set any cmdargs
			return ""
	else:
		sublime.error_message("Something went wrong.")
		return

def get_project_newroot(view):
	""" Gets the data of the .sublime-project file.
		Returns a relative path, if set.
		(Useful, if you have many subfolders.)
	"""
	try:
		project_data = view.window().project_data()
		new_root_setting = project_data.get('root')
	except:
		new_root_setting = ""
	
	return new_root_setting


# Future addition. Sadly not working as by now.		
# class AutocompleteCaps(sublime_plugin.EventListener):
# 	def on_query_completions(self, view, prefix, locations):
# 		return suggestions


class Builder(sublime_plugin.WindowCommand):

	def run(self, *args, **kwargs):
		self.lp_conv_path = self.check_system()
		self.pckg_settings = sublime.load_settings(PACKAGE_SETTINGS)
		self.AC_path = str(self.pckg_settings.get("AC_path", DEFAULT_AC_PATH))
		self.converter = os.path.join(self.AC_path, self.lp_conv_path)

		self.project_path_abs_root = self.window.folders()[0]

		self.view = self.window.active_view()
		if self.view.settings().get("auto_save", True):
			save_all_files()

		self.nr_path = get_project_newroot(self.view)
		log.debug(self.nr_path)
		# see if there is a relative path set in the project settings
		if self.nr_path != None:  # empty path is of type 'None'
			nr_path_abs = os.path.join(self.project_path_abs_root, self.nr_path)
			self.folders = [directory for directory in os.listdir(nr_path_abs) if os.path.isdir(os.path.join(nr_path_abs, directory))]
		else:
			self.folders = self.window.folders()

		if len(self.folders) <= 0:
			sublime.error_message("GDL build command error: You must have a project open.")
		else:
			if len(self.folders) == 1:
				self.multipleFolders = False
				self.project_folder = self.folders[0]
				self.delegator()
			else:
				self.multipleFolders = True
				self.pick_project_folder(self.folders)

	def check_system(self):
		""" Returns the path to the LP_XML converter.
		"""
		if sys.platform.startswith('darwin'): # OSX
			self.os_win = "false"
			return "Contents/MacOS/LP_XMLConverter.app/Contents/MacOS/LP_XMLConverter"
		elif sys.platform.startswith('win'):  # Windows
			self.os_win = "true"
			return "LP_XMLConverter.exe"
		else:
			sublime.error_message("GDL build error: Your OS is not supported.")
			return

	def normpath(self, path):
		""" Normalize a pathname by collapsing redundant separators.
			On Windows, it converts forward slashes to backward slashes.
		"""
		return '"{}"'.format(os.path.normpath(path))

	def pick_project_folder(self, folders):
		""" Gets called if there are multiple folders in the project. 
		"""
		folderNames = []
		for folder in folders:
			index = folder.rfind('/') + 1
			if index > 0:
				folderNames.append(folder[index:])
			else:
				folderNames.append(folder)

		# self.sel_proj will be called once, with the index of the selected item
		self.show_quick_panel(folderNames, self.select_project)

	def select_project(self, select):
		folders = self.folders
		if select < 0:  # will be -1 if panel was cancelled
			return
		self.project_folder = os.path.join(self.nr_path, folders[select])
		self.project_folder = folders[select]
		self.delegator()  # go on here

	def show_quick_panel(self, options, done):
		""" Shows the Sublime Text quick panel with the invoked options. """
		# Sublime Text 3 requires a short timeout between quick panels
		sublime.set_timeout(lambda: self.window.show_quick_panel(options, done), 10)

	def delegator(self):
		""" Delegates back to the specific calling class.
			Also makes the `project_folder` path absolut.
		"""
		# join with new root
		self.project_folder = os.path.join(self.nr_path, self.project_folder)
		# make absolut path, since relative paths might introduce errors
		self.project_folder = os.path.join(self.project_path_abs_root, self.project_folder)
		
		log.debug("project_folder: " + self.project_folder)
		
		# this delegates back to the calling class.
		self.on_done_proj()


# 	@classmethod
# 	def is_enabled(self):
# 		return "/GDL/" in self.window.active_view().settings().get("syntax")

		
# go to
# http://gdl.graphisoft.com/tips-and-tricks/how-to-use-the-lp_xmlconverter-tool
# for detailed information
class HsfBuildCommand(Builder):
	""" Converts a GSM into human readable GDL scripts. """

	def run(self, *args, **kwargs):
		""" Sublime Text will call this function. """
		super().run(self)

	def on_done_proj(self):
		# we're coming from super().delegator()
		# own function because quick panel is async
		self.find_gsm()

	def find_gsm(self):
		self.files = []
		log.debug(self.project_folder)
		# r=root, d=directories, f=files
		for r, d, f in os.walk(self.project_folder):
			for file in f:
				if '.gsm' in file:
					self.files.append(os.path.join(r, file))

		if len(self.files) <= 0:
			sublime.error_message("GDL build error: No GSM found.")
		elif len(self.files) > 1:
			self.show_quick_panel(self.files, self.select_gsm)<commit_msg>better comments<commit_after># -*- coding: utf-8 -*-

import os
import sublime
import sublime_plugin
import sys
import logging

log = logging.getLogger(__name__)

PACKAGE_SETTINGS = "GDL.sublime-settings"
DEFAULT_AC_PATH = "C:/Program Files/GRAPHISOFT/ARCHICAD 23"

def save_all_files():
	""" Saves all files open in Sublime.
		Mimics the 'save on build' behavior of Sublime Text.
	"""
	for window in sublime.windows():
		for view in window.views():
			if view.file_name() and view.is_dirty():
				view.run_command("save")

def get_project_data(view, invoke):
	""" Gets the data of the .sublime-project file.
		Returns additional arguments for the commandline operation,
		if the user has set any.
	"""
	# invoke options: 'to-hsf' / 'to-gsm' / 'proj_gsm_path'
	project_data = view.window().project_data()
	if not project_data:
		sublime.error_message("You must create a project first! (Project > Save Project As...)")
		return

	project_settings = project_data.get('cmdargs', {})
	if type(project_settings) is dict:
		# check if dict is empty
		if bool(project_settings):
			return project_settings.get(invoke, "")
		else:
			# dict is empty, which means user hasn't set any cmdargs
			return ""
	else:
		sublime.error_message("Something went wrong.")
		return

def get_project_newroot(view):
	""" Gets the data of the .sublime-project file.
		Returns a relative path, if set.
		(Useful, if you have many subfolders and want to assign
		a new root, where all the objects are in.)
	"""
	try:
		project_data = view.window().project_data()
		new_root_setting = project_data.get('root')
	except:
		new_root_setting = ""
	
	return new_root_setting


# Future addition. Sadly not working as by now.		
# class AutocompleteCaps(sublime_plugin.EventListener):
# 	def on_query_completions(self, view, prefix, locations):
# 		return suggestions


class Builder(sublime_plugin.WindowCommand):

	def run(self, *args, **kwargs):
		self.lp_conv_path = self.check_system()
		self.pckg_settings = sublime.load_settings(PACKAGE_SETTINGS)
		self.AC_path = str(self.pckg_settings.get("AC_path", DEFAULT_AC_PATH))
		self.converter = os.path.join(self.AC_path, self.lp_conv_path)

		self.project_path_abs_root = self.window.folders()[0]

		self.view = self.window.active_view()
		if self.view.settings().get("auto_save", True):
			save_all_files()

		self.nr_path = get_project_newroot(self.view)
		log.debug(self.nr_path)
		# see if there is a relative path set in the project settings
		if self.nr_path != None:  # empty path is of type 'None'
			nr_path_abs = os.path.join(self.project_path_abs_root, self.nr_path)
			self.folders = [directory for directory in os.listdir(nr_path_abs) if os.path.isdir(os.path.join(nr_path_abs, directory))]
		else:
			self.folders = self.window.folders()

		if len(self.folders) <= 0:
			sublime.error_message("GDL build command error: You must have a project open.")
		else:
			if len(self.folders) == 1:
				self.multipleFolders = False
				self.project_folder = self.folders[0]
				self.delegator()
			else:
				self.multipleFolders = True
				self.pick_project_folder(self.folders)

	def check_system(self):
		""" Returns the path to the LP_XML converter.
		"""
		if sys.platform.startswith('darwin'): # OSX
			self.os_win = "false"
			return "Contents/MacOS/LP_XMLConverter.app/Contents/MacOS/LP_XMLConverter"
		elif sys.platform.startswith('win'):  # Windows
			self.os_win = "true"
			return "LP_XMLConverter.exe"
		else:
			sublime.error_message("GDL build error: Your OS is not supported.")
			return

	def normpath(self, path):
		""" Normalize a pathname by collapsing redundant separators.
			On Windows, it converts forward slashes to backward slashes.
			Returns the object as an quote encapsulated string.
		"""
		return '"{}"'.format(os.path.normpath(path))

	def pick_project_folder(self, folders):
		""" Gets called if there are multiple folders in the project. 
		"""
		folderNames = []
		for folder in folders:
			index = folder.rfind('/') + 1
			if index > 0:
				folderNames.append(folder[index:])
			else:
				folderNames.append(folder)

		# self.sel_proj will be called once, with the index of the selected item
		self.show_quick_panel(folderNames, self.select_project)

	def select_project(self, select):
		folders = self.folders
		if select < 0:  # will be -1 if panel was cancelled
			return
		self.project_folder = os.path.join(self.nr_path, folders[select])
		self.project_folder = folders[select]
		self.delegator()  # go on here

	def show_quick_panel(self, options, done):
		""" Shows the Sublime Text quick panel with the invoked options. """
		# Sublime Text 3 requires a short timeout between quick panels
		sublime.set_timeout(lambda: self.window.show_quick_panel(options, done), 10)

	def delegator(self):
		""" Delegates back to the specific calling class.
			Also makes the `project_folder` path absolut.
		"""
		# join with new root
		self.project_folder = os.path.join(self.nr_path, self.project_folder)
		# make absolut path, since relative paths might introduce errors
		self.project_folder = os.path.join(self.project_path_abs_root, self.project_folder)
		
		log.debug("project_folder: " + self.project_folder)
		
		# this delegates back to the calling class.
		self.on_done_proj()


# 	@classmethod
# 	def is_enabled(self):
# 		return "/GDL/" in self.window.active_view().settings().get("syntax")

		
# go to
# http://gdl.graphisoft.com/tips-and-tricks/how-to-use-the-lp_xmlconverter-tool
# for detailed information
class HsfBuildCommand(Builder):
	""" Converts a GSM into human readable GDL scripts via the LP_XMLConverter. """

	def run(self, *args, **kwargs):
		""" Sublime Text will call this function.
			We will run the parent class "Builder" first.
			That will give us all the parameters we need.
		"""
		super().run(self)

	def on_done_proj(self):
		# we're coming from super().delegator()
		# own function because quick panel is async
		self.find_gsm()

	def find_gsm(self):
		self.files = []
		log.debug(self.project_folder)
		# r=root, d=directories, f=files
		for r, d, f in os.walk(self.project_folder):
			for file in f:
				if '.gsm' in file:
					self.files.append(os.path.join(r, file))

		if len(self.files) <= 0:
			sublime.error_message("GDL build error: No GSM found.")
		elif len(self.files) > 1:
			self.show_quick_panel(self.files, self.select_gsm)
{'fraction_non_alphanumeric': 0.1156106593672007, 'fraction_numerical': 0.0025762821028902667, 'mean_word_length': 4.139429044269756, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '426537', 'n_tokens_mistral': 4603, 'n_tokens_neox': 4140, 'n_words': 1121}