Example #1
0
    def _focus_zathura(self, pid):
        if which('xdotool') is not None:
            try:
                self._focus_xdotool(pid)
                return
            except:
                pass

        if which('wmctrl') is not None:
            try:
                self._focus_wmctrl(pid)
            except:
                pass
Example #2
0
    def _focus_zathura(self, pid):
        if which('xdotool') is not None:
            try:
                self._focus_xdotool(pid)
                return
            except:
                pass

        if which('wmctrl') is not None:
            try:
                self._focus_wmctrl(pid)
            except:
                pass
Example #3
0
def get_sublime_exe():
    '''
    Utility function to get the full path to the currently executing
    Sublime instance.
    '''
    processes = ['subl', 'sublime_text']

    def check_processes(st2_dir=None):
        if st2_dir is None or os.path.exists(st2_dir):
            for process in processes:
                try:
                    if st2_dir is not None:
                        process = os.path.join(st2_dir, process)

                    m = SUBLIME_VERSION.search(
                        check_output([process, '-v'], use_texpath=False))
                    if m and m.group(1) == version:
                        return process
                except:
                    pass

        return None

    platform = sublime.platform()

    plat_settings = get_setting(platform, {})
    sublime_executable = plat_settings.get('sublime_executable', None)

    if sublime_executable:
        return sublime_executable

    # we cache the results of the other checks, if possible
    if hasattr(get_sublime_exe, 'result'):
        return get_sublime_exe.result

    # are we on ST3
    if hasattr(sublime, 'executable_path'):
        get_sublime_exe.result = sublime.executable_path()
        # on osx, the executable does not function the same as subl
        if platform == 'osx':
            get_sublime_exe.result = os.path.normpath(
                os.path.join(os.path.dirname(get_sublime_exe.result), '..',
                             'SharedSupport', 'bin', 'subl'))
        # on linux, it is preferable to use subl if it points to the
        # correct version see issue #710 for a case where this is useful
        elif (platform == 'linux'
              and not get_sublime_exe.result.endswith('subl')):
            subl = which('subl')
            if subl is not None:
                try:
                    m = SUBLIME_VERSION.search(
                        check_output([subl, '-v'], use_texpath=False))

                    if m and m.group(1) == sublime.version():
                        get_sublime_exe.result = subl
                except:
                    pass

        return get_sublime_exe.result
    # in ST2 on Windows the Python executable is actually "sublime_text"
    elif platform == 'windows' and sys.executable != 'python' and \
            os.path.isabs(sys.executable):
        get_sublime_exe.result = sys.executable
        return get_sublime_exe.result

    # guess-work for ST2
    version = sublime.version()

    # hope its on the path
    result = check_processes()
    if result is not None:
        get_sublime_exe.result = result
        return result

    # guess the default location
    if platform == 'windows':
        st2_dir = os.path.expandvars('%PROGRAMFILES%\\Sublime Text 2')
        result = check_processes(st2_dir)
        if result is not None:
            get_sublime_exe.result = result
            return result
    elif platform == 'linux':
        for path in [
                '$HOME/bin', '$HOME/sublime_text_2', '$HOME/sublime_text',
                '/opt/sublime_text_2', '/opt/sublime_text', '/usr/local/bin',
                '/usr/bin'
        ]:
            st2_dir = os.path.expandvars(path)
            result = check_processes(st2_dir)
            if result is not None:
                get_sublime_exe.result = result
                return result
    else:
        st2_dir = '/Applications/Sublime Text 2.app/Contents/SharedSupport/bin'
        result = check_processes(st2_dir)
        if result is not None:
            get_sublime_exe.result = result
            return result
        try:
            folder = check_output(
                ['mdfind', '"kMDItemCFBundleIdentifier == com.sublimetext.2"'],
                use_texpath=False)

            st2_dir = os.path.join(folder, 'Contents', 'SharedSupport', 'bin')
            result = check_processes(st2_dir)
            if result is not None:
                get_sublime_exe.result = result
                return result
        except:
            pass

    print('Cannot determine the path to your Sublime installation. Please '
          'set the "sublime_executable" setting in your settings for your '
          'platform.')

    return None
Example #4
0
    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)
Example #5
0
    def run(self):
        texpath = self.texpath
        results = []

        env = copy.deepcopy(os.environ)

        if texpath is not None:
            env['PATH'] = texpath
        if self.build_env is not None:
            update_environment(env, self.build_env)

        table = [
            ['Variable', 'Value']
        ]

        table.append(['PATH', env.get('PATH', '')])

        if self.uses_miktex:
            get_tex_path_variable = get_tex_path_variable_miktex
            should_run = which('findtexmf', path=texpath) is not None
        else:
            get_tex_path_variable = get_tex_path_variable_texlive
            should_run = which('kpsewhich', path=texpath) is not None

        if should_run:
            for var in ['TEXINPUTS', 'BIBINPUTS', 'BSTINPUTS']:
                table.append([var, get_tex_path_variable(var, env)])

        if self.uses_miktex:
            for var in ['BIBTEX', 'LATEX', 'PDFLATEX', 'MAKEINDEX',
                        'MAKEINFO', 'TEX', 'PDFTEX', 'TEXINDEX']:
                value = env.get(var, None)
                if value is not None:
                    table.append([var, value])

        results.append(table)

        table = [
            ['Program', 'Location', 'Status', 'Version']
        ]

        # skip sublime_exe on OS X
        # we only use this for the hack to re-focus on ST
        # which doesn't work on OS X anyway
        if sublime.platform() != 'osx':
            sublime_exe = self.sublime_exe
            available = sublime_exe is not None

            if available:
                if not os.path.isabs(sublime_exe):
                    sublime_exe = which(sublime_exe)

                basename, extension = os.path.splitext(sublime_exe)
                if extension is not None:
                    sublime_exe = ''.join((basename, extension.lower()))

            version_info = get_version_info(
                sublime_exe, env=env
            ) if available else None

            table.append([
                'sublime',
                sublime_exe if available and version_info is not None else u'',
                (u'available'
                    if available and version_info is not None else u'missing'),
                version_info if version_info is not None else u'unavailable'
            ])

        # a list of programs, each program is either a string or a list
        # of alternatives (e.g. 32/64 bit version)
        programs = [
            'latexmk' if not self.uses_miktex else 'texify', 'pdflatex',
            'xelatex', 'lualatex', 'biber', 'bibtex', 'bibtex8', 'kpsewhich'
        ]

        if _HAS_PREVIEW:
            # ImageMagick requires gs to work with PDFs
            programs += [['magick', 'convert']]

        for program in programs:
            if isinstance(program, list):
                program_list = program
                program = program_list[0]
                location = None
                for p in program_list:
                    location = which(p, path=texpath)
                    if location is not None:
                        program = p
                        break
            else:
                location = which(program, path=texpath)

            # convert.exe on Windows can refer to %sysroot%\convert.exe,
            # which should not be used; in that case, simple report magick.exe
            # as not existing
            if program == 'convert' and sublime.platform() == 'windows':
                system_root = get_system_root().lower()
                if location.lower().startswith(system_root):
                    program = 'magick'
                    location = None

            available = location is not None

            if available:
                basename, extension = os.path.splitext(location)
                if extension is not None:
                    location = ''.join((basename, extension.lower()))

            version_info = get_version_info(
                location, env=env
            ) if available else None

            available_str = (
                u'available' if available and version_info is not None
                else u'missing'
            )

            if (available and program in ['magick', 'convert'] and
                    not convert_installed()):
                available_str = u'restart required'

            table.append([
                program,
                location if available and version_info is not None else u'',
                available_str,
                version_info if version_info is not None else u'unavailable'
            ])

        program = 'ghostscript'
        location = get_gs_command()

        available = location is not None

        if available:
            basename, extension = os.path.splitext(location)
            if extension is not None:
                location = ''.join((basename, extension.lower()))

        version_info = get_version_info(
            location, env=env
        ) if available else None

        available_str = (
            u'available' if available and version_info is not None
            else u'missing'
        )

        if available and _HAS_PREVIEW and not ghostscript_installed():
            available_str = u'restart required'

        table.append([
            program,
            location if available and version_info is not None else u'',
            available_str,
            version_info if version_info is not None else u'unavailable'
        ])

        results.append(table)

        # This really only works for the default template
        # Note that no attempt is made to find other packages that the
        # included package depends on
        if (_HAS_PREVIEW and ghostscript_installed() and
                get_setting('preview_math_template_file') is None and
                get_setting("preview_math_mode", view=self.view) != "none"):

            find_package_re = re.compile(
                r'\\usepackage(?:\[[^\]]*\])?\{(?P<pkg>[^\}]*)\}'
            )

            packages = ["standalone.cls", "preview.sty", "xcolor.sty"]

            package_settings = get_setting(
                "preview_math_template_packages", [], view=self.view)
            # extract all packages from each package line
            for pkg_str in package_settings:
                # search for all \usepackage in the line
                for m in find_package_re.finditer(pkg_str):
                    pkg_arg = m.group("pkg")
                    # search for each package in the \usepackage argument
                    for pkg in pkg_arg.split(","):
                        pkg = pkg.strip()
                        if pkg:
                            packages.append(pkg + ".sty")

            if packages:
                table = [[u'Packages for equation preview', u'Status']]

                for package in packages:
                    available = kpsewhich(package) is not None
                    package_name = package.split(".")[0]
                    table.append([
                        package_name,
                        (u'available' if available else u'missing')
                    ])

                results.append(table)

        run_on_main_thread(partial(self._on_main_thread, results), timeout=30)
Example #6
0
    def run(self):
        texpath = self.texpath
        results = []

        env = copy.deepcopy(os.environ)

        if texpath is not None:
            env['PATH'] = texpath
        if self.build_env is not None:
            update_environment(env, self.build_env)

        table = [
            ['Variable', 'Value']
        ]

        table.append(['PATH', env.get('PATH', '')])

        if self.uses_miktex:
            get_tex_path_variable = get_tex_path_variable_miktex
            should_run = which('findtexmf', path=texpath) is not None
        else:
            get_tex_path_variable = get_tex_path_variable_texlive
            should_run = which('kpsewhich', path=texpath) is not None

        if should_run:
            for var in ['TEXINPUTS', 'BIBINPUTS', 'BSTINPUTS']:
                table.append([var, get_tex_path_variable(var, env)])

        if self.uses_miktex:
            for var in ['BIBTEX', 'LATEX', 'PDFLATEX', 'MAKEINDEX',
                        'MAKEINFO', 'TEX', 'PDFTEX', 'TEXINDEX']:
                value = env.get(var, None)
                if value is not None:
                    table.append([var, value])

        results.append(table)

        table = [
            ['Program', 'Location', 'Status', 'Version']
        ]

        # skip sublime_exe on OS X
        # we only use this for the hack to re-focus on ST
        # which doesn't work on OS X anyway
        if sublime.platform() != 'osx':
            sublime_exe = self.sublime_exe
            available = sublime_exe is not None

            if available:
                if not os.path.isabs(sublime_exe):
                    sublime_exe = which(sublime_exe)

                basename, extension = os.path.splitext(sublime_exe)
                if extension is not None:
                    sublime_exe = ''.join((basename, extension.lower()))

            version_info = get_version_info(
                sublime_exe, env=env
            ) if available else None

            table.append([
                'sublime',
                sublime_exe,
                (u'available'
                    if available and version_info is not None else u'missing'),
                version_info if version_info is not None else u'unavailable'
            ])

        # a list of programs, each program is either a string or a list
        # of alternatives (e.g. 32/64 bit version)
        programs = [
            'latexmk' if not self.uses_miktex else 'texify', 'pdflatex',
            'xelatex', 'lualatex', 'biber', 'bibtex', 'bibtex8', 'kpsewhich',
            ('gs' if sublime.platform() != 'windows'
                else ['gswin32c', 'gswin64c', 'gs'])
        ]

        if sublime.version() >= '3118':
            # ImageMagick requires gs to work with PDFs
            programs += [['magick', 'convert']]

        for program in programs:
            if isinstance(program, list):
                program_list = program
                program = program_list[0]
                location = None
                for p in program_list:
                    location = which(p, path=texpath)
                    if location is not None:
                        program = p
                        break
            else:
                location = which(program, path=texpath)

            available = location is not None

            if available:
                basename, extension = os.path.splitext(location)
                if extension is not None:
                    location = ''.join((basename, extension.lower()))

            version_info = get_version_info(
                location, env=env
            ) if available else None

            available_str = (
                u'available' if available and version_info is not None
                else u'missing')
            if (available and program in ['magick', 'convert'] and
                    not convert_installed()):
                available_str = u'restart required'

            table.append([
                program,
                location,
                available_str,
                version_info if version_info is not None else u'unavailable'
            ])

        results.append(table)

        run_on_main_thread(partial(self._on_main_thread, results), timeout=30)
Example #7
0
    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)
Example #8
0
    def run(self):
        texpath = self.texpath
        results = []

        env = copy.deepcopy(os.environ)

        if texpath is not None:
            env['PATH'] = texpath
        if self.build_env is not None:
            update_environment(env, self.build_env)

        table = [['Variable', 'Value']]

        table.append(['PATH', env.get('PATH', '')])

        if self.uses_miktex:
            get_tex_path_variable = get_tex_path_variable_miktex
            should_run = which('findtexmf', path=texpath) is not None
        else:
            get_tex_path_variable = get_tex_path_variable_texlive
            should_run = which('kpsewhich', path=texpath) is not None

        if should_run:
            for var in ['TEXINPUTS', 'BIBINPUTS', 'BSTINPUTS']:
                table.append([var, get_tex_path_variable(var, env)])

        if self.uses_miktex:
            for var in [
                    'BIBTEX', 'LATEX', 'PDFLATEX', 'MAKEINDEX', 'MAKEINFO',
                    'TEX', 'PDFTEX', 'TEXINDEX'
            ]:
                value = env.get(var, None)
                if value is not None:
                    table.append([var, value])

        results.append(table)

        table = [['Program', 'Location', 'Status', 'Version']]

        # skip sublime_exe on OS X
        # we only use this for the hack to re-focus on ST
        # which doesn't work on OS X anyway
        if sublime.platform() != 'osx':
            sublime_exe = self.sublime_exe
            available = sublime_exe is not None

            if available:
                if not os.path.isabs(sublime_exe):
                    sublime_exe = which(sublime_exe)

                basename, extension = os.path.splitext(sublime_exe)
                if extension is not None:
                    sublime_exe = ''.join((basename, extension.lower()))

            version_info = get_version_info(sublime_exe,
                                            env=env) if available else None

            table.append([
                'sublime', sublime_exe,
                (u'available'
                 if available and version_info is not None else u'missing'),
                version_info if version_info is not None else u'unavailable'
            ])

        # a list of programs, each program is either a string or a list
        # of alternatives (e.g. 32/64 bit version)
        programs = [
            'latexmk' if not self.uses_miktex else 'texify', 'pdflatex',
            'xelatex', 'lualatex', 'biber', 'bibtex', 'bibtex8', 'kpsewhich'
        ]

        if _HAS_PREVIEW:
            # ImageMagick requires gs to work with PDFs
            programs += [['magick', 'convert']]

        for program in programs:
            if isinstance(program, list):
                program_list = program
                program = program_list[0]
                location = None
                for p in program_list:
                    location = which(p, path=texpath)
                    if location is not None:
                        program = p
                        break
            else:
                location = which(program, path=texpath)

            available = location is not None

            if available:
                basename, extension = os.path.splitext(location)
                if extension is not None:
                    location = ''.join((basename, extension.lower()))

            version_info = get_version_info(location,
                                            env=env) if available else None

            available_str = (u'available' if available
                             and version_info is not None else u'missing')

            if (available and program in ['magick', 'convert']
                    and not convert_installed()):
                available_str = u'restart required'

            table.append([
                program, location, available_str,
                version_info if version_info is not None else u'unavailable'
            ])

        program = 'ghostscript'
        location = get_gs_command()

        available = location is not None

        if available:
            basename, extension = os.path.splitext(location)
            if extension is not None:
                location = ''.join((basename, extension.lower()))

        version_info = get_version_info(location,
                                        env=env) if available else None

        available_str = (u'available' if available and version_info is not None
                         else u'missing')

        if available and _HAS_PREVIEW and not ghostscript_installed():
            available_str = u'restart required'

        table.append([
            program, location, available_str,
            version_info if version_info is not None else u'unavailable'
        ])

        results.append(table)

        # This really only works for the default template
        # Note that no attempt is made to find other packages that the
        # included package depends on
        if (_HAS_PREVIEW and convert_installed()
                and get_setting('preview_math_template_file') is None and
                get_setting("preview_math_mode", view=self.view) != "none"):

            find_package_re = re.compile(
                r'\\usepackage(?:\[[^\]]*\])?\{(?P<pkg>[^\}]*)\}')

            packages = ["standalone.cls", "preview.sty", "xcolor.sty"]

            package_settings = get_setting("preview_math_template_packages",
                                           [],
                                           view=self.view)
            # extract all packages from each package line
            for pkg_str in package_settings:
                # search for all \usepackage in the line
                for m in find_package_re.finditer(pkg_str):
                    pkg_arg = m.group("pkg")
                    # search for each package in the \usepackage argument
                    for pkg in pkg_arg.split(","):
                        pkg = pkg.strip()
                        if pkg:
                            packages.append(pkg + ".sty")

            if packages:
                table = [[u'Packages for equation preview', u'Status']]

                for package in packages:
                    available = kpsewhich(package) is not None
                    package_name = package.split(".")[0]
                    table.append([
                        package_name,
                        (u'available' if available else u'missing')
                    ])

                results.append(table)

        run_on_main_thread(partial(self._on_main_thread, results), timeout=30)
Example #9
0
def external_command(command, cwd=None, shell=False, env=None,
                     stdin=__sentinel__, stdout=__sentinel__,
                     stderr=__sentinel__, preexec_fn=None,
                     use_texpath=True, show_window=False):
    '''
    Takes a command object to be passed to subprocess.Popen.

    Returns a subprocess.Popen object for the corresponding process.

    Raises OSError if command not found
    '''
    if command is None:
        raise ValueError('command must be a string or list of strings')

    _env = dict(os.environ)

    if use_texpath:
        _env['PATH'] = get_texpath() or os.environ['PATH']

    if env is not None:
        update_env(_env, env)

    # if command is a string rather than a list, convert it to a list
    # unless shell is set to True on a non-Windows platform
    if (
        (shell is False or sublime.platform() == 'windows') and
        isinstance(command, strbase)
    ):
        if sys.version_info < (3,):
            command = str(command)

        command = split(command)

        if sys.version_info < (3,):
            command = [unicode(c) for c in command]
    elif (
        shell is True and sublime.platform() != 'windows' and
        (isinstance(command, list) or isinstance(command, tuple))
    ):
        command = u' '.join(command)

    # Windows-specific adjustments
    startupinfo = None
    if sublime.platform() == 'windows':
        # ensure console window doesn't show
        startupinfo = subprocess.STARTUPINFO()
        startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW

        if show_window:
            startupinfo.wShowWindow = 1

        if not os.path.isabs(command[0]):
            _command = which(
                command[0], path=_env['PATH'] or os.environ['PATH']
            )

            if command:
                command[0] = _command

        # encode cwd in the file system encoding; this is necessary to support
        # some non-ASCII paths; see PR #878. Thanks to anamewing for the
        # suggested fix
        if not _ST3 and cwd:
            cwd = cwd.encode(sys.getfilesystemencoding())

    if stdin is __sentinel__:
        stdin = None

    if stdout is __sentinel__:
        stdout = PIPE

    if stderr is __sentinel__:
        stderr = STDOUT

    try:
        print(u'Running "{0}"'.format(u' '.join([quote(s) for s in command])))
    except UnicodeError:
        try:
            print(u'Running "{0}"'.format(command))
        except:
            pass

    p = Popen(
        command,
        stdin=stdin,
        stdout=stdout,
        stderr=stderr,
        startupinfo=startupinfo,
        preexec_fn=preexec_fn,
        shell=shell,
        env=_env,
        cwd=cwd
    )

    return p
def external_command(command, cwd=None, shell=False, env=None,
                     stdin=__sentinel__, stdout=__sentinel__,
                     stderr=__sentinel__, preexec_fn=None,
                     use_texpath=True, show_window=False):
    '''
    Takes a command object to be passed to subprocess.Popen.

    Returns a subprocess.Popen object for the corresponding process.

    Raises OSError if command not found
    '''
    if command is None:
        raise ValueError('command must be a string or list of strings')

    _env = dict(os.environ)

    if use_texpath:
        _env['PATH'] = get_texpath() or os.environ['PATH']

    if env is not None:
        update_env(_env, env)

    # if command is a string rather than a list, convert it to a list
    # unless shell is set to True on a non-Windows platform
    if (
        (shell is False or sublime.platform() == 'windows') and
        isinstance(command, strbase)
    ):
        if sys.version_info < (3,):
            command = str(command)

        command = split(command)

        if sys.version_info < (3,):
            command = [unicode(c) for c in command]
    elif (
        shell is True and sublime.platform() != 'windows' and
        (isinstance(command, list) or isinstance(command, tuple))
    ):
        command = u' '.join(command)

    # Windows-specific adjustments
    startupinfo = None
    if sublime.platform() == 'windows':
        # ensure console window doesn't show
        startupinfo = subprocess.STARTUPINFO()
        startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW

        if show_window:
            startupinfo.wShowWindow = 1

        if not os.path.isabs(command[0]):
            _command = which(
                command[0], path=_env['PATH'] or os.environ['PATH']
            )

            if _command:
                command[0] = _command

        # encode cwd in the file system encoding; this is necessary to support
        # some non-ASCII paths; see PR #878. Thanks to anamewing for the
        # suggested fix
        if not _ST3 and cwd:
            cwd = cwd.encode(sys.getfilesystemencoding())

    if stdin is __sentinel__:
        stdin = None

    if stdout is __sentinel__:
        stdout = PIPE

    if stderr is __sentinel__:
        stderr = STDOUT

    try:
        print(u'Running "{0}"'.format(u' '.join([quote(s) for s in command])))
    except UnicodeError:
        try:
            print(u'Running "{0}"'.format(command))
        except:
            pass

    p = Popen(
        command,
        stdin=stdin,
        stdout=stdout,
        stderr=stderr,
        startupinfo=startupinfo,
        preexec_fn=preexec_fn,
        shell=shell,
        env=_env,
        cwd=cwd
    )

    return p
Example #11
0
def get_sublime_exe():
    '''
    Utility function to get the full path to the currently executing
    Sublime instance.
    '''
    processes = ['subl', 'sublime_text']

    def check_processes(st2_dir=None):
        if st2_dir is None or os.path.exists(st2_dir):
            for process in processes:
                try:
                    if st2_dir is not None:
                        process = os.path.join(st2_dir, process)

                    p = subprocess.Popen(
                        [process, '-v'],
                        stdout=subprocess.PIPE,
                        startupinfo=startupinfo,
                        shell=shell,
                        env=os.environ
                    )
                except:
                    pass
                else:
                    stdout, _ = p.communicate()

                    if p.returncode == 0:
                        m = SUBLIME_VERSION.search(stdout.decode('utf8'))
                        if m and m.group(1) == version:
                            return process
        return None

    platform = sublime.platform()

    plat_settings = get_setting(platform, {})
    sublime_executable = plat_settings.get('sublime_executable', None)

    if sublime_executable:
        return sublime_executable

    # we cache the results of the other checks, if possible
    if hasattr(get_sublime_exe, 'result'):
        return get_sublime_exe.result

    # are we on ST3
    if hasattr(sublime, 'executable_path'):
        get_sublime_exe.result = sublime.executable_path()
        # on osx, the executable does not function the same as subl
        if platform == 'osx':
            get_sublime_exe.result = os.path.normpath(
                os.path.join(
                    os.path.dirname(get_sublime_exe.result),
                    '..',
                    'SharedSupport',
                    'bin',
                    'subl'
                )
            )
        # on linux, it is preferable to use subl if it points to the
        # correct version see issue #710 for a case where this is useful
        elif (
            platform == 'linux' and
            not get_sublime_exe.result.endswith('subl')
        ):
            subl = which('subl')
            if subl is not None:
                try:
                    p = subprocess.Popen(
                        [subl, '-v'],
                        stdout=subprocess.PIPE,
                        env=os.environ
                    )
                except:
                    pass
                else:
                    stdout, _ = p.communicate()

                    if p.returncode == 0:
                        m = SUBLIME_VERSION.search(stdout.decode('utf8'))
                        if m and m.group(1) == sublime.version():
                            get_sublime_exe.result = subl

        return get_sublime_exe.result
    # in ST2 on Windows the Python executable is actually "sublime_text"
    elif platform == 'windows' and sys.executable != 'python' and \
            os.path.isabs(sys.executable):
        get_sublime_exe.result = sys.executable
        return get_sublime_exe.result

    # guess-work for ST2
    version = sublime.version()

    startupinfo = None
    shell = False
    if platform == 'windows':
        startupinfo = subprocess.STARTUPINFO()
        startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
        shell = sublime.version() >= '3000'

    # hope its on the path
    result = check_processes()
    if result is not None:
        get_sublime_exe.result = result
        return result

    # guess the default location
    if platform == 'windows':
        st2_dir = os.path.expandvars('%PROGRAMFILES%\\Sublime Text 2')
        result = check_processes(st2_dir)
        if result is not None:
            get_sublime_exe.result = result
            return result
    elif platform == 'linux':
        for path in [
            '$HOME/bin',
            '$HOME/sublime_text_2',
            '$HOME/sublime_text',
            '/opt/sublime_text_2',
            '/opt/sublime_text',
            '/usr/local/bin',
            '/usr/bin'
        ]:
            st2_dir = os.path.expandvars(path)
            result = check_processes(st2_dir)
            if result is not None:
                get_sublime_exe.result = result
                return result
    else:
        st2_dir = '/Applications/Sublime Text 2.app/Contents/SharedSupport/bin'
        result = check_processes(st2_dir)
        if result is not None:
            get_sublime_exe.result = result
            return result
        try:
            p = subprocess.Popen(
                ['mdfind', '"kMDItemCFBundleIdentifier == com.sublimetext.2"'],
                stdout=subprocess.PIPE,
                env=os.environ
            )
        except:
            pass
        else:
            stdout, _ = p.communicate()
            if p.returncode == 0:
                st2_dir = os.path.join(
                    stdout.decode('utf8'),
                    'Contents',
                    'SharedSupport',
                    'bin'
                )
                result = check_processes(st2_dir)
                if result is not None:
                    get_sublime_exe.result = result
                    return result

    print(
        'Cannot determine the path to your Sublime installation. Please '
        'set the "sublime_executable" setting in your settings for your '
        'platform.'
    )

    return None