def run(self, **args): pdffile = None if 'file' in args: pdffile = args.pop('file', None) else: view = self.window.active_view() root = getTeXRoot.get_tex_root(view) file_name = get_jobname(root) output_directory = get_output_directory(view) if output_directory is None: root = getTeXRoot.get_tex_root(view) pdffile = os.path.join(os.path.dirname(root), file_name + u'.pdf') else: pdffile = os.path.join(output_directory, file_name + u'.pdf') if not os.path.exists(pdffile): pdffile = os.path.join(os.path.dirname(root), file_name + u'.pdf') pdffile = os.path.normpath(pdffile) if not os.path.exists(pdffile): print("Expected PDF file {0} not found".format(pdffile)) return pdffile = os.path.realpath(pdffile) # since we potentially accept an argument, add some extra # safety checks if pdffile is None: print('No PDF file found.') return elif not os.path.exists(pdffile): print(u'PDF file "{0}" does not exist.'.format(pdffile)) sublime.error_message( u'PDF file "{0}" does not exist.'.format(pdffile)) return try: viewer = get_viewer() except NoViewerException: return try: viewer.view_file(pdffile, keep_focus=False) except (AttributeError, NotImplementedError): traceback.print_exception() sublime.error_message( 'Viewer ' + viewer_name + ' does not appear to be a proper LaTeXTools viewer plugin.' + ' Please contact the plugin author.') return
def run(self, **args): pdffile = None if 'file' in args: pdffile = args.pop('file', None) else: view = self.window.active_view() root = getTeXRoot.get_tex_root(view) file_name = get_jobname(root) output_directory = get_output_directory(view) if output_directory is None: pdffile = os.path.join( os.path.dirname(root), file_name + u'.pdf' ) else: pdffile = os.path.join( output_directory, file_name + u'.pdf' ) if not os.path.exists(pdffile): pdffile = os.path.join( os.path.dirname(root), file_name + u'.pdf' ) # since we potentially accept an argument, add some extra # safety checks if pdffile is None: print('No PDF file found.') return elif not os.path.exists(pdffile): print(u'PDF file "{0}" does not exist.'.format(pdffile)) sublime.error_message( u'PDF file "{0}" does not exist.'.format(pdffile) ) return try: viewer = get_viewer() except NoViewerException: return try: viewer.view_file(pdffile, keep_focus=False) except (AttributeError, NotImplementedError): traceback.print_exception() sublime.error_message('Viewer ' + viewer_name + ' does not appear to be a proper LaTeXTools viewer plugin.' + ' Please contact the plugin author.') return
def _on_main_thread(self, results): builder_name = get_setting( 'builder', 'traditional', view=self.view ) if builder_name in ['', 'default']: builder_name = 'traditional' builder_settings = get_setting('builder_settings', view=self.view) builder_path = get_setting('builder_path', view=self.view) if builder_name in ['simple', 'traditional', 'script']: builder_path = None else: bld_path = os.path.join(sublime.packages_path(), builder_path) add_plugin_path(bld_path) builder_name = _classname_to_internal_name(builder_name) try: get_plugin('{0}_builder'.format(builder_name)) builder_available = True except NoSuchPluginException: traceback.print_exc() builder_available = False results.append([ [u'Builder', u'Status'], [ builder_name, u'available' if builder_available else u'missing' ] ]) if builder_path: results.append([[u'Builder Path'], [builder_path]]) if builder_settings is not None: table = [[u'Builder Setting', u'Value']] for key in sorted(builder_settings.keys()): value = builder_settings[key] table.append([key, value]) results.append(table) # is current view a TeX file? view = self.view if view.score_selector(0, 'text.tex.latex') != 0: tex_root = get_tex_root(view) tex_directives = parse_tex_directives( tex_root, multi_values=['options'], key_maps={'ts-program': 'program'} ) results.append([[u'TeX Root'], [tex_root]]) results.append([ [u'LaTeX Engine'], [ tex_directives.get( 'program', get_setting( 'program', 'pdflatex', self.view ) ) ] ]) table = [[u'LaTeX Output Setting', u'Value']] output_directory = get_output_directory(view) if output_directory: table.append( ['output_directory', output_directory] ) aux_directory = get_aux_directory(view) if aux_directory: table.append(['aux_directory', aux_directory]) jobname = get_jobname(view) if jobname and jobname != os.path.splitext( os.path.basename(tex_root) )[0]: table.append(['jobname', jobname]) if len(table) > 1: results.append(table) options = get_setting('builder_settings', {}, self.view).\ get('options', []) if isinstance(options, strbase): options = [options] options.extend(tex_directives.get('options', [])) if len(options) > 0: table = [[u'LaTeX Options']] for option in options: table.append([option]) results.append(table) default_viewer = DEFAULT_VIEWERS.get(sublime.platform(), None) viewer_name = get_setting('viewer', default_viewer) if viewer_name in ['', 'default']: viewer_name = default_viewer try: viewer_plugin = get_plugin(viewer_name + '_viewer') viewer_available = True except NoSuchPluginException: viewer_available = False viewer_location = 'N/A' if viewer_available: if viewer_name == 'command': # assume the command viewer is always valid viewer_location = 'N/A' elif viewer_name in ('evince', 'okular', 'zathura'): viewer_location = which(viewer_name) viewer_available = bool(viewer_location) elif viewer_name == 'preview': viewer_location = '/Applications/Preview.app' if not os.path.exists(viewer_location): try: viewer_location = check_output([ 'osascript', '-e', 'POSIX path of ' '(path to app id "com.apple.Preview")' ], use_texpath=False) except subprocess.CalledProcessError: viewer_location = None viewer_available = False \ if not viewer_location else os.path.exists(viewer_location) elif viewer_name == 'skim': viewer_location = '/Applications/Skim.app' if not os.path.exists(viewer_location): try: viewer_location = check_output([ 'osascript', '-e', 'POSIX path of ' '(path to app id "net.sourceforge.skim-app.skim")' ], use_texpath=False) except subprocess.CalledProcessError: viewer_location = None viewer_available = False \ if not viewer_location else os.path.exists(viewer_location) elif viewer_name == 'sumatra': sumatra_exe = get_setting('viewer_settings', {}).\ get('sumatra', get_setting('windows', {}). get('sumatra', 'SumatraPDF.exe')) or \ 'SumatraPDF.exe' viewer_location = which(sumatra_exe) if not bool(viewer_location): viewer_location = viewer_plugin()._find_sumatra_exe() viewer_available = bool(viewer_location) if not viewer_available: viewer_location = 'N/A' results.append([ [u'Viewer', u'Status', u'Location'], [ viewer_name, u'available' if viewer_available else u'missing', viewer_location ] ]) if callable(self.on_done): self.on_done(results)
def run(self, cmd="", file_regex="", path=""): # Try to handle killing with self.proc_lock: if self.proc: # if we are running, try to kill running process self.output("\n\n### Got request to terminate compilation ###") if sublime.platform() == 'windows': startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW subprocess.call( 'taskkill /t /f /pid {pid}'.format(pid=self.proc.pid), startupinfo=startupinfo, shell=True ) else: os.killpg(self.proc.pid, signal.SIGTERM) self.proc = None return else: # either it's the first time we run, or else we have no running processes self.proc = None view = self.view = self.window.active_view() if view.is_dirty(): print ("saving...") view.run_command('save') # call this on view, not self.window if view.file_name() is None: sublime.error_message('Please save your file before attempting to build.') return self.file_name = getTeXRoot.get_tex_root(view) if not os.path.isfile(self.file_name): sublime.error_message(self.file_name + ": file not found.") return self.tex_base = get_jobname(view) tex_dir = os.path.dirname(self.file_name) if not is_tex_file(self.file_name): sublime.error_message("%s is not a TeX source file: cannot compile." % (os.path.basename(view.file_name()),)) return # Output panel: from exec.py if not hasattr(self, 'output_view'): self.output_view = self.window.get_output_panel("latextools") output_view_settings = self.output_view.settings() output_view_settings.set("result_file_regex", file_regex) output_view_settings.set("result_base_dir", tex_dir) output_view_settings.set("line_numbers", False) output_view_settings.set("gutter", False) output_view_settings.set("scroll_past_end", False) output_view_settings.set( "syntax", "Packages/LaTeXTools/LaTeXTools Console.hidden-tmLanguage" ) output_view_settings.set( "color_scheme", sublime.load_settings('Preferences.sublime-settings'). get('color_scheme') ) self.output_view.set_read_only(True) # Dumb, but required for the moment for the output panel to be picked # up as the result buffer self.window.get_output_panel("latextools") self.hide_panel_level = get_setting("hide_build_panel", "never") if self.hide_panel_level != "always": self.window.run_command("show_panel", {"panel": "output.latextools"}) self.plat = sublime.platform() if self.plat == "osx": self.encoding = "UTF-8" elif self.plat == "windows": self.encoding = getOEMCP() elif self.plat == "linux": self.encoding = "UTF-8" else: sublime.error_message("Platform as yet unsupported. Sorry!") return # Get platform settings, builder, and builder settings platform_settings = get_setting(self.plat, {}) builder_name = get_setting("builder", "traditional") self.display_bad_boxes = get_setting("display_bad_boxes", False) # This *must* exist, so if it doesn't, the user didn't migrate if builder_name is None: sublime.error_message("LaTeXTools: you need to migrate your preferences. See the README file for instructions.") self.window.run_command('hide_panel', {"panel": "output.latextools"}) return # Default to 'traditional' builder if builder_name in ['', 'default']: builder_name = 'traditional' # this is to convert old-style names (e.g. AReallyLongName) # to new style plugin names (a_really_long_name) builder_name = _classname_to_internal_name(builder_name) builder_settings = get_setting("builder_settings", {}) # parse root for any %!TEX directives tex_directives = parse_tex_directives( self.file_name, multi_values=['options'], key_maps={'ts-program': 'program'} ) # determine the engine engine = tex_directives.get('program', builder_settings.get("program", "pdflatex")) engine = engine.lower() # Sanity check: if "strange" engine, default to pdflatex (silently...) if engine not in [ 'pdflatex', "pdftex", 'xelatex', 'xetex', 'lualatex', 'luatex' ]: engine = 'pdflatex' options = builder_settings.get("options", []) if isinstance(options, strbase): options = [options] if 'options' in tex_directives: options.extend(tex_directives['options']) # filter out --aux-directory and --output-directory options which are # handled separately options = [opt for opt in options if ( not opt.startswith('--aux-directory') and not opt.startswith('--output-directory') and not opt.startswith('--jobname') )] self.aux_directory = get_aux_directory(self.file_name) self.output_directory = get_output_directory(self.file_name) # Read the env option (platform specific) builder_platform_settings = builder_settings.get(self.plat) if builder_platform_settings: self.env = builder_platform_settings.get("env", None) else: self.env = None # Now actually get the builder builder_path = get_setting("builder_path", "") # relative to ST packages dir! # Safety check: if we are using a built-in builder, disregard # builder_path, even if it was specified in the pref file if builder_name in ['simple', 'traditional', 'script', 'basic']: builder_path = None if builder_path: bld_path = os.path.join(sublime.packages_path(), builder_path) add_plugin_path(bld_path) try: builder = get_plugin('{0}_builder'.format(builder_name)) except NoSuchPluginException: sublime.error_message("Cannot find builder " + builder_name + ".\n" \ "Check your LaTeXTools Preferences") self.window.run_command('hide_panel', {"panel": "output.latextools"}) return print(repr(builder)) self.builder = builder( self.file_name, self.output, engine, options, self.aux_directory, self.output_directory, self.tex_base, tex_directives, builder_settings, platform_settings ) # Now get the tex binary path from prefs, change directory to # that of the tex root file, and run! self.path = platform_settings['texpath'] os.chdir(tex_dir) CmdThread(self).start() print(threading.active_count())
def run(self, edit, **args): # Check prefs for PDF focus and sync keep_focus = args.get('keep_focus', get_setting('keep_focus', True)) forward_sync = args.get('forward_sync', get_setting('forward_sync', True)) # If invoked from keybinding, we sync # Rationale: if the user invokes the jump command, s/he wants to see the result of the compilation. # If the PDF viewer window is already visible, s/he probably wants to sync, or s/he would have no # need to invoke the command. And if it is not visible, the natural way to just bring up the # window without syncing is by using the system's window management shortcuts. # As for focusing, we honor the toggles / prefs. from_keybinding = args.pop("from_keybinding", False) if from_keybinding: forward_sync = True print (from_keybinding, keep_focus, forward_sync) if not is_tex_file(self.view.file_name()): sublime.error_message("%s is not a TeX source file: cannot jump." % (os.path.basename(view.fileName()),)) return root = getTeXRoot.get_tex_root(self.view) file_name = get_jobname(root) output_directory = get_output_directory(self.view) if output_directory is None: root = getTeXRoot.get_tex_root(self.view) pdffile = os.path.join( os.path.dirname(root), file_name + u'.pdf' ) else: pdffile = os.path.join( output_directory, file_name + u'.pdf' ) if not os.path.exists(pdffile): pdffile = os.path.join( os.path.dirname(root), file_name + u'.pdf' ) (line, col) = self.view.rowcol(self.view.sel()[0].end()) print("Jump to: ", line, col) # column is actually ignored up to 0.94 # HACK? It seems we get better results incrementing line line += 1 # issue #625: we need to pass the path to the file to the viewer when # there are files in subfolders of the main folder. # Thanks rstein and arahlin for this code! srcfile = self.view.file_name() try: viewer = get_viewer() except NoViewerException: return if forward_sync: try: viewer.forward_sync(pdffile, srcfile, line, col, keep_focus=keep_focus) except (AttributeError, NotImplementedError): try: viewer.view_file(pdffile, keep_focus=keep_focus) except (AttributeError, NotImplementedError): traceback.print_exc() sublime.error_message('Viewer ' + viewer_name + ' does not appear to be a proper LaTeXTools viewer plugin.' + ' Please contact the plugin author.') return else: try: viewer.view_file(pdffile, keep_focus=keep_focus) except (AttributeError, NotImplementedError): traceback.print_exc() sublime.error_message('Viewer ' + viewer_name + ' does not appear to be a proper LaTeXTools viewer plugin.' + ' Please contact the plugin author.') return if keep_focus: try: if viewer.supports_keep_focus(): return except (AttributeError, NotImplementedError): pass focus_st()
def run( self, file_regex="", program=None, builder=None, command=None, env=None, path=None, script_commands=None, update_phantoms_only=False, hide_phantoms_only=False, **kwargs ): if update_phantoms_only: if self.show_errors_inline: self.update_phantoms() return if hide_phantoms_only: self.hide_phantoms() return # Try to handle killing with self.proc_lock: if self.proc: # if we are running, try to kill running process self.output("\n\n### Got request to terminate compilation ###") try: if sublime.platform() == 'windows': execute_command( 'taskkill /t /f /pid {pid}'.format(pid=self.proc.pid), use_texpath=False ) else: os.killpg(self.proc.pid, signal.SIGTERM) except: print('Exception occurred while killing build') traceback.print_exc() self.proc = None return else: # either it's the first time we run, or else we have no running processes self.proc = None view = self.view = self.window.active_view() if _HAS_PHANTOMS: self.hide_phantoms() pref_settings = sublime.load_settings("Preferences.sublime-settings") self.show_errors_inline = pref_settings.get("show_errors_inline", True) if view.is_dirty(): print ("saving...") view.run_command('save') # call this on view, not self.window if view.file_name() is None: sublime.error_message('Please save your file before attempting to build.') return self.file_name = getTeXRoot.get_tex_root(view) if not os.path.isfile(self.file_name): sublime.error_message(self.file_name + ": file not found.") return self.tex_base = get_jobname(view) self.tex_dir = os.path.dirname(self.file_name) if not is_tex_file(self.file_name): sublime.error_message("%s is not a TeX source file: cannot compile." % (os.path.basename(view.file_name()),)) return # Output panel: from exec.py if not hasattr(self, 'output_view'): self.output_view = self.window.get_output_panel("latextools") output_view_settings = self.output_view.settings() output_view_settings.set("result_file_regex", file_regex) output_view_settings.set("result_base_dir", self.tex_dir) output_view_settings.set("line_numbers", False) output_view_settings.set("gutter", False) output_view_settings.set("scroll_past_end", False) if get_setting("highlight_build_panel", True): self.output_view.set_syntax_file( "Packages/LaTeXTools/LaTeXTools Console.hidden-tmLanguage" ) output_view_settings.set( "color_scheme", sublime.load_settings('Preferences.sublime-settings'). get('color_scheme') ) self.output_view.set_read_only(True) # Dumb, but required for the moment for the output panel to be picked # up as the result buffer self.window.get_output_panel("latextools") self.hide_panel_level = get_setting("hide_build_panel", "no_warnings") if self.hide_panel_level == "never": self.show_output_panel(force=True) self.plat = sublime.platform() if self.plat == "osx": self.encoding = "UTF-8" elif self.plat == "windows": self.encoding = getOEMCP() elif self.plat == "linux": self.encoding = "UTF-8" else: sublime.error_message("Platform as yet unsupported. Sorry!") return # Get platform settings, builder, and builder settings platform_settings = get_setting(self.plat, {}) self.display_bad_boxes = get_setting("display_bad_boxes", False) if builder is not None: builder_name = builder else: builder_name = get_setting("builder", "traditional") # Default to 'traditional' builder if builder_name in ['', 'default']: builder_name = 'traditional' # this is to convert old-style names (e.g. AReallyLongName) # to new style plugin names (a_really_long_name) builder_name = _classname_to_internal_name(builder_name) builder_settings = get_setting("builder_settings", {}) # override the command if command is not None: builder_settings.set("command", command) # parse root for any %!TEX directives tex_directives = parse_tex_directives( self.file_name, multi_values=['options'], key_maps={'ts-program': 'program'} ) # determine the engine if program is not None: engine = program else: engine = tex_directives.get( 'program', builder_settings.get("program", "pdflatex") ) engine = engine.lower() # Sanity check: if "strange" engine, default to pdflatex (silently...) if engine not in [ 'pdflatex', "pdftex", 'xelatex', 'xetex', 'lualatex', 'luatex' ]: engine = 'pdflatex' options = builder_settings.get("options", []) if isinstance(options, strbase): options = [options] if 'options' in tex_directives: options.extend(tex_directives['options']) # filter out --aux-directory and --output-directory options which are # handled separately options = [opt for opt in options if ( not opt.startswith('--aux-directory') and not opt.startswith('--output-directory') and not opt.startswith('--jobname') )] self.aux_directory = get_aux_directory(self.file_name) self.output_directory = get_output_directory(self.file_name) # Read the env option (platform specific) builder_platform_settings = builder_settings.get(self.plat, {}) if env is not None: self.env = env elif builder_platform_settings: self.env = builder_platform_settings.get("env", None) else: self.env = None # Safety check: if we are using a built-in builder, disregard # builder_path, even if it was specified in the pref file if builder_name in ['simple', 'traditional', 'script', 'basic']: builder_path = None else: # relative to ST packages dir! builder_path = get_setting("builder_path", "") if builder_path: bld_path = os.path.join(sublime.packages_path(), builder_path) add_plugin_path(bld_path) try: builder = get_plugin('{0}_builder'.format(builder_name)) except NoSuchPluginException: sublime.error_message( "Cannot find builder {0}.\n" "Check your LaTeXTools Preferences".format(builder_name) ) self.window.run_command('hide_panel', {"panel": "output.latextools"}) return if builder_name == 'script' and script_commands: builder_platform_settings['script_commands'] = script_commands builder_settings[self.plat] = builder_platform_settings print(repr(builder)) self.builder = builder( self.file_name, self.output, engine, options, self.aux_directory, self.output_directory, self.tex_base, tex_directives, builder_settings, platform_settings ) # Now get the tex binary path from prefs, change directory to # that of the tex root file, and run! if path is not None: self.path = path else: self.path = get_texpath() or os.environ['PATH'] thread = CmdThread(self) thread.start() print(threading.active_count()) # setup the progress indicator display_message_length = long( get_setting('build_finished_message_length', 2.0) * 1000 ) # NB CmdThread will change the success message self.progress_indicator = ProgressIndicator( thread, 'Building', 'Build failed', display_message_length=display_message_length )
def _on_main_thread(self, results): builder_name = get_setting('builder', 'traditional', view=self.view) if builder_name in ['', 'default']: builder_name = 'traditional' builder_settings = get_setting('builder_settings', view=self.view) builder_path = get_setting('builder_path', view=self.view) if builder_name in ['simple', 'traditional', 'script']: builder_path = None else: bld_path = os.path.join(sublime.packages_path(), builder_path) add_plugin_path(bld_path) builder_name = _classname_to_internal_name(builder_name) try: get_plugin('{0}_builder'.format(builder_name)) builder_available = True except NoSuchPluginException: traceback.print_exc() builder_available = False results.append( [[u'Builder', u'Status'], [builder_name, u'available' if builder_available else u'missing']]) if builder_path: results.append([[u'Builder Path'], [builder_path]]) if builder_settings is not None: table = [[u'Builder Setting', u'Value']] for key in sorted(builder_settings.keys()): value = builder_settings[key] table.append([key, value]) results.append(table) # is current view a TeX file? view = self.view if view.score_selector(0, 'text.tex.latex') != 0: tex_root = get_tex_root(view) tex_directives = parse_tex_directives( tex_root, multi_values=['options'], key_maps={'ts-program': 'program'}) results.append([[u'TeX Root'], [tex_root]]) results.append([[u'LaTeX Engine'], [ tex_directives.get( 'program', get_setting('program', 'pdflatex', self.view)) ]]) table = [[u'LaTeX Output Setting', u'Value']] output_directory = get_output_directory(tex_root) if output_directory: table.append(['output_directory', output_directory]) aux_directory = get_aux_directory(tex_root) if aux_directory: table.append(['aux_directory', aux_directory]) jobname = get_jobname(tex_root) if jobname and jobname != os.path.splitext( os.path.basename(tex_root))[0]: table.append(['jobname', jobname]) if len(table) > 1: results.append(table) options = get_setting('builder_settings', {}, self.view).\ get('options', []) options.extend(tex_directives.get('options', [])) if len(options) > 0: table = [[u'LaTeX Options']] for option in options: table.append([option]) results.append(table) default_viewer = DEFAULT_VIEWERS.get(sublime.platform(), None) viewer_name = get_setting('viewer', default_viewer) if viewer_name in ['', 'default']: viewer_name = default_viewer try: viewer_plugin = get_plugin(viewer_name + '_viewer') viewer_available = True except NoSuchPluginException: viewer_available = False viewer_location = 'N/A' if viewer_available: if viewer_name == 'command': # assume the command viewer is always valid viewer_location = 'N/A' elif viewer_name in ('evince', 'okular', 'zathura'): viewer_location = which(viewer_name) viewer_available = bool(viewer_location) elif viewer_name == 'preview': viewer_location = '/Applications/Preview.app' if not os.path.exists(viewer_location): try: viewer_location = check_output([ 'osascript', '-e', 'POSIX path of ' '(path to app id "com.apple.Preview")' ], use_texpath=False) except subprocess.CalledProcessError: viewer_location = None viewer_available = False \ if not viewer_location else os.path.exists(viewer_location) elif viewer_name == 'skim': viewer_location = '/Applications/Skim.app' if not os.path.exists(viewer_location): try: viewer_location = check_output([ 'osascript', '-e', 'POSIX path of ' '(path to app id "net.sourceforge.skim-app.skim")' ], use_texpath=False) except subprocess.CalledProcessError: viewer_location = None viewer_available = False \ if not viewer_location else os.path.exists(viewer_location) elif viewer_name == 'sumatra': sumatra_exe = get_setting('viewer_settings', {}).\ get('sumatra', get_setting('windows', {}). get('sumatra', 'SumatraPDF.exe')) or \ 'SumatraPDF.exe' viewer_location = which(sumatra_exe) if not bool(viewer_location): viewer_location = viewer_plugin()._find_sumatra_exe() viewer_available = bool(viewer_location) if not viewer_available: viewer_location = 'N/A' results.append([[u'Viewer', u'Status', u'Location'], [ viewer_name, u'available' if viewer_available else u'missing', viewer_location ]]) if callable(self.on_done): self.on_done(results)
def run(self, file_regex="", program=None, builder=None, command=None, env=None, path=None, script_commands=None, update_phantoms_only=False, hide_phantoms_only=False, **kwargs): if update_phantoms_only: if self.show_errors_inline: self.update_phantoms() return if hide_phantoms_only: self.hide_phantoms() return # Try to handle killing with self.proc_lock: if self.proc: # if we are running, try to kill running process self.output("\n\n### Got request to terminate compilation ###") try: if sublime.platform() == 'windows': execute_command('taskkill /t /f /pid {pid}'.format( pid=self.proc.pid), use_texpath=False) else: os.killpg(self.proc.pid, signal.SIGTERM) except: print('Exception occurred while killing build') traceback.print_exc() self.proc = None return else: # either it's the first time we run, or else we have no running processes self.proc = None view = self.view = self.window.active_view() if _HAS_PHANTOMS: self.hide_phantoms() pref_settings = sublime.load_settings( "Preferences.sublime-settings") self.show_errors_inline = pref_settings.get( "show_errors_inline", True) if view.is_dirty(): print("saving...") view.run_command('save') # call this on view, not self.window if view.file_name() is None: sublime.error_message( 'Please save your file before attempting to build.') return self.file_name = getTeXRoot.get_tex_root(view) if not os.path.isfile(self.file_name): sublime.error_message(self.file_name + ": file not found.") return self.tex_base = get_jobname(view) self.tex_dir = os.path.dirname(self.file_name) if not is_tex_file(self.file_name): sublime.error_message( "%s is not a TeX source file: cannot compile." % (os.path.basename(view.file_name()), )) return # Output panel: from exec.py if not hasattr(self, 'output_view'): self.output_view = self.window.get_output_panel("latextools") output_view_settings = self.output_view.settings() output_view_settings.set("result_file_regex", file_regex) output_view_settings.set("result_base_dir", self.tex_dir) output_view_settings.set("line_numbers", False) output_view_settings.set("gutter", False) output_view_settings.set("scroll_past_end", False) if get_setting("highlight_build_panel", True, view=view): self.output_view.set_syntax_file( "Packages/LaTeXTools/LaTeXTools Console.hidden-tmLanguage") output_view_settings.set( "color_scheme", sublime.load_settings('Preferences.sublime-settings').get( 'color_scheme')) self.output_view.set_read_only(True) # Dumb, but required for the moment for the output panel to be picked # up as the result buffer self.window.get_output_panel("latextools") self.hide_panel_level = get_setting("hide_build_panel", "no_warnings", view=view) if self.hide_panel_level == "never": self.show_output_panel(force=True) self.plat = sublime.platform() if self.plat == "osx": self.encoding = "UTF-8" elif self.plat == "windows": self.encoding = getOEMCP() elif self.plat == "linux": self.encoding = "UTF-8" else: sublime.error_message("Platform as yet unsupported. Sorry!") return # Get platform settings, builder, and builder settings platform_settings = get_setting(self.plat, {}, view=view) self.display_bad_boxes = get_setting("display_bad_boxes", False, view=view) if builder is not None: builder_name = builder else: builder_name = get_setting("builder", "traditional", view=view) # Default to 'traditional' builder if builder_name in ['', 'default']: builder_name = 'traditional' # this is to convert old-style names (e.g. AReallyLongName) # to new style plugin names (a_really_long_name) builder_name = _classname_to_internal_name(builder_name) builder_settings = get_setting("builder_settings", {}, view=view) # override the command if command is not None: builder_settings.set("command", command) # parse root for any %!TEX directives tex_directives = parse_tex_directives( self.file_name, multi_values=['options'], key_maps={'ts-program': 'program'}) # determine the engine if program is not None: engine = program else: engine = tex_directives.get( 'program', builder_settings.get("program", "pdflatex")) engine = engine.lower() # Sanity check: if "strange" engine, default to pdflatex (silently...) if engine not in [ 'pdflatex', "pdftex", 'xelatex', 'xetex', 'lualatex', 'luatex' ]: engine = 'pdflatex' options = builder_settings.get("options", []) if isinstance(options, strbase): options = [options] if 'options' in tex_directives: options.extend(tex_directives['options']) # filter out --aux-directory and --output-directory options which are # handled separately options = [ opt for opt in options if (not opt.startswith('--aux-directory') and not opt.startswith( '--output-directory') and not opt.startswith('--jobname')) ] self.aux_directory = get_aux_directory(view) self.output_directory = get_output_directory(view) # Read the env option (platform specific) builder_platform_settings = builder_settings.get(self.plat, {}) if env is not None: self.env = env elif builder_platform_settings: self.env = builder_platform_settings.get("env", None) else: self.env = None # Safety check: if we are using a built-in builder, disregard # builder_path, even if it was specified in the pref file if builder_name in ['simple', 'traditional', 'script', 'basic']: builder_path = None else: # relative to ST packages dir! builder_path = get_setting("builder_path", "", view=view) if builder_path: bld_path = os.path.join(sublime.packages_path(), builder_path) add_plugin_path(bld_path) try: builder = get_plugin('{0}_builder'.format(builder_name)) except NoSuchPluginException: try: builder = get_plugin(builder_name) except NoSuchPluginException: sublime.error_message( "Cannot find builder {0}.\n" "Check your LaTeXTools Preferences".format(builder_name)) self.window.run_command('hide_panel', {"panel": "output.latextools"}) return if builder_name == 'script' and script_commands: builder_platform_settings['script_commands'] = script_commands builder_settings[self.plat] = builder_platform_settings print(repr(builder)) self.builder = builder(self.file_name, self.output, engine, options, self.aux_directory, self.output_directory, self.tex_base, tex_directives, builder_settings, platform_settings) # Now get the tex binary path from prefs, change directory to # that of the tex root file, and run! if path is not None: self.path = path else: self.path = get_texpath() or os.environ['PATH'] thread = CmdThread(self) thread.start() print(threading.active_count()) # setup the progress indicator display_message_length = long( get_setting('build_finished_message_length', 2.0, view=view) * 1000) # NB CmdThread will change the success message self.progress_indicator = ProgressIndicator( thread, 'Building', 'Build failed', display_message_length=display_message_length)
def run(self, cmd="", file_regex="", path=""): # Try to handle killing with self.proc_lock: if self.proc: # if we are running, try to kill running process self.output("\n\n### Got request to terminate compilation ###") if sublime.platform() == 'windows': startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW subprocess.call( 'taskkill /t /f /pid {pid}'.format(pid=self.proc.pid), startupinfo=startupinfo, shell=True ) else: os.killpg(self.proc.pid, signal.SIGTERM) self.proc = None return else: # either it's the first time we run, or else we have no running processes self.proc = None view = self.view = self.window.active_view() if view.is_dirty(): print ("saving...") view.run_command('save') # call this on view, not self.window if view.file_name() is None: sublime.error_message('Please save your file before attempting to build.') return self.file_name = getTeXRoot.get_tex_root(view) if not os.path.isfile(self.file_name): sublime.error_message(self.file_name + ": file not found.") return self.tex_base = get_jobname(view) tex_dir = os.path.dirname(self.file_name) if not is_tex_file(self.file_name): sublime.error_message("%s is not a TeX source file: cannot compile." % (os.path.basename(view.file_name()),)) return # Output panel: from exec.py if not hasattr(self, 'output_view'): self.output_view = self.window.get_output_panel("exec") # Dumb, but required for the moment for the output panel to be picked # up as the result buffer self.window.get_output_panel("exec") self.output_view.settings().set("result_file_regex", "^([^:\n\r]*):([0-9]+):?([0-9]+)?:? (.*)$") # self.output_view.settings().set("result_line_regex", line_regex) self.output_view.settings().set("result_base_dir", tex_dir) self.window.run_command("show_panel", {"panel": "output.exec"}) self.output_view.settings().set("result_file_regex", file_regex) self.plat = sublime.platform() if self.plat == "osx": self.encoding = "UTF-8" elif self.plat == "windows": self.encoding = getOEMCP() elif self.plat == "linux": self.encoding = "UTF-8" else: sublime.error_message("Platform as yet unsupported. Sorry!") return # Get platform settings, builder, and builder settings platform_settings = get_setting(self.plat, {}) builder_name = get_setting("builder", "traditional") self.hide_panel_level = get_setting("hide_build_panel", "never") self.display_bad_boxes = get_setting("display_bad_boxes", False) # This *must* exist, so if it doesn't, the user didn't migrate if builder_name is None: sublime.error_message("LaTeXTools: you need to migrate your preferences. See the README file for instructions.") self.window.run_command('hide_panel', {"panel": "output.exec"}) return # Default to 'traditional' builder if builder_name in ['', 'default']: builder_name = 'traditional' # this is to convert old-style names (e.g. AReallyLongName) # to new style plugin names (a_really_long_name) builder_name = _classname_to_internal_name(builder_name) builder_settings = get_setting("builder_settings", {}) # parse root for any %!TEX directives tex_directives = parse_tex_directives( self.file_name, multi_values=['options'], key_maps={'ts-program': 'program'} ) # determine the engine engine = tex_directives.get('program', builder_settings.get("program", "pdflatex")) engine = engine.lower() # Sanity check: if "strange" engine, default to pdflatex (silently...) if engine not in [ 'pdflatex', "pdftex", 'xelatex', 'xetex', 'lualatex', 'luatex' ]: engine = 'pdflatex' options = builder_settings.get("options", []) if isinstance(options, strbase): options = [options] if 'options' in tex_directives: options.extend(tex_directives['options']) # filter out --aux-directory and --output-directory options which are # handled separately options = [opt for opt in options if ( not opt.startswith('--aux-directory') and not opt.startswith('--output-directory') and not opt.startswith('--jobname') )] self.aux_directory = get_aux_directory(self.file_name) self.output_directory = get_output_directory(self.file_name) # Read the env option (platform specific) builder_platform_settings = builder_settings.get(self.plat) if builder_platform_settings: self.env = builder_platform_settings.get("env", None) else: self.env = None # Now actually get the builder builder_path = get_setting("builder_path", "") # relative to ST packages dir! # Safety check: if we are using a built-in builder, disregard # builder_path, even if it was specified in the pref file if builder_name in ['simple', 'traditional', 'script', 'basic']: builder_path = None if builder_path: bld_path = os.path.join(sublime.packages_path(), builder_path) add_plugin_path(bld_path) try: builder = get_plugin('{0}_builder'.format(builder_name)) except NoSuchPluginException: sublime.error_message("Cannot find builder " + builder_name + ".\n" \ "Check your LaTeXTools Preferences") self.window.run_command('hide_panel', {"panel": "output.exec"}) return print(repr(builder)) self.builder = builder( self.file_name, self.output, engine, options, self.aux_directory, self.output_directory, self.tex_base, tex_directives, builder_settings, platform_settings ) # Now get the tex binary path from prefs, change directory to # that of the tex root file, and run! self.path = platform_settings['texpath'] os.chdir(tex_dir) CmdThread(self).start() print(threading.active_count())