126 lines
4.7 KiB
Python
126 lines
4.7 KiB
Python
import sublime
|
|
import sublime_plugin
|
|
import os
|
|
|
|
from threading import Thread
|
|
from subprocess import Popen, PIPE
|
|
from os import environ
|
|
|
|
# Related reading;
|
|
# https://stackoverflow.com/questions/39881091/how-to-run-sublimetext-with-visual-studio-environment-enabled/
|
|
|
|
# For the unfamiliar, Visual Studio ships with a batch file which sets up the
|
|
# environment variables you need to be able to run visual studio tools from a
|
|
# command prompt.
|
|
#
|
|
# This pluguin was written in response to someone that wanted to know how you
|
|
# could run Sublime and have it have the visual studio environment already set
|
|
# up.
|
|
#
|
|
# This plugin will use a subprocess to execute the batch file in the background
|
|
# and then issue the 'set' command to get the command interpreter to output the
|
|
# state of the environment before it exits.
|
|
#
|
|
# This output is gathered and parsed to come up with a dictionary similar to
|
|
# the environ table that python uses. From here we can easily detect what new
|
|
# environment variables were added and the values of those that changed, and
|
|
# set them as appropriate.
|
|
#
|
|
# As written Sublime needs to be restarted in order to execute the batch file
|
|
# again. A more elegant solution would be to save the environment prior to
|
|
# modifying it so that it could be restored and a new environment applied.
|
|
|
|
# To use this, you need to specify a setting in your user preferences named
|
|
# 'vc_vars_cmd' which should contain a complete path to the batch file you want
|
|
# to execute. Optionally you can also specify 'vc_vars_arch', which will be
|
|
# passed as a command line argument to the batch file executed. Remember that
|
|
# the preferences are JSON, so you need to quote all path separators.
|
|
|
|
SENTINEL="SUBL_VC_VARS"
|
|
|
|
def _get_vc_env():
|
|
"""
|
|
Run the batch file specified in the vc_vars_cmd setting (with an
|
|
optional architecture type) and return back a dictionary of the
|
|
environment that the batch file sets up.
|
|
|
|
Returns None if the preference is missing or the batch file fails.
|
|
"""
|
|
settings = sublime.load_settings("Preferences.sublime-settings")
|
|
vars_cmd = settings.get("vc_vars_cmd")
|
|
vars_arch = settings.get("vc_vars_arch", "amd64")
|
|
|
|
if vars_cmd is None:
|
|
settings = sublime.load_settings("Remedy.sublime-settings")
|
|
if settings:
|
|
vars_cmd = settings.get("vc_vars_cmd")
|
|
vars_arch = settings.get("vc_vars_arch", "amd64")
|
|
|
|
if type(vars_cmd) == list:
|
|
for it in vars_cmd:
|
|
if os.path.isfile(it):
|
|
vars_cmd = it
|
|
break
|
|
|
|
if vars_cmd is None:
|
|
print("set_vc_vars: Cannot set Visual Studio Environment")
|
|
print("set_vc_vars: Add 'vc_vars_cmd' setting to settings and restart")
|
|
return None
|
|
|
|
try:
|
|
# Run the batch, outputting a sentinel value so we can separate out
|
|
# any error messages the batch might generate.
|
|
shell_cmd = "\"{0}\" {1} && echo {2} && set".format(
|
|
vars_cmd, vars_arch, SENTINEL)
|
|
|
|
output = Popen(shell_cmd, stdout=PIPE, shell=True).stdout.read()
|
|
|
|
lines = [line.strip() for line in output.decode("utf-8").splitlines()]
|
|
env_lines = lines[lines.index(SENTINEL) + 1:]
|
|
except:
|
|
return None
|
|
|
|
# Convert from var=value to dictionary key/value pairs. We upper case the
|
|
# keys, since Python does that to the mapping it stores in environ.
|
|
env = {}
|
|
for env_var in env_lines:
|
|
parts = env_var.split("=", maxsplit=1)
|
|
env[parts[0].upper()] = parts[1]
|
|
|
|
return env
|
|
|
|
def install_vc_env():
|
|
"""
|
|
Try to collect the appropriate Visual Studio environment variables and
|
|
set them into the current environment.
|
|
"""
|
|
vc_env = _get_vc_env()
|
|
if vc_env is None:
|
|
print("set_vc_vars: Unable to fetch the Visual Studio Environment")
|
|
return sublime.status_message("Error fetching VS Environment")
|
|
|
|
# Add newly set environment variables
|
|
for key in vc_env.keys():
|
|
if key not in environ:
|
|
environ[key] = vc_env[key]
|
|
|
|
# Update existing variables whose values changed.
|
|
for key in environ:
|
|
if key in vc_env and environ[key] != vc_env[key]:
|
|
environ[key] = vc_env[key]
|
|
|
|
# Set a sentinel variable so we know not to try setting up the path again.
|
|
environ[SENTINEL] = "BOOTSTRAPPED"
|
|
sublime.status_message("VS Environment enabled")
|
|
|
|
def plugin_loaded():
|
|
if sublime.platform() != "windows":
|
|
return sublime.status_message("VS is not supported on this platform")
|
|
|
|
# To reload the environment if it changes, restart Sublime.
|
|
if SENTINEL in environ:
|
|
return sublime.status_message("VS Environment already enabled")
|
|
|
|
# Update in the background so we don't block the UI
|
|
Thread(target=install_vc_env).start()
|