def start_process(self, conf_path, classpath, cache_dir, java_home, java_flags): Util.mkdir_p(cache_dir) log_path = os.path.join(cache_dir, "server.log") log = open(log_path, "w") null = open("/dev/null", "r") args = ( [os.path.join(java_home, "bin", "java")] + ["-cp", classpath] + [a for a in java_flags.split(" ") if a != ""] + ["-Densime.config={}".format(conf_path), "org.ensime.server.Server"]) process = subprocess.Popen( args, stdin=null, stdout=log, stderr=subprocess.STDOUT) pid_path = os.path.join(cache_dir, "server.pid") Util.write_file(pid_path, str(process.pid)) def on_stop(): log.close() with catch(Exception, lambda e: None): os.remove(pid_path) return EnsimeProcess(cache_dir, process, log_path, on_stop)
def start_process(self, classpath): cache_dir = self.config['cache-dir'] java_flags = self.config['java-flags'] Util.mkdir_p(cache_dir) log_path = os.path.join(cache_dir, "server.log") log = open(log_path, "w") null = open("/dev/null", "r") java = os.path.join(self.config['java-home'], 'bin', 'java') if not os.path.exists(java): raise InvalidJavaPathError(errno.ENOENT, 'No such file or directory', java) elif not os.access(java, os.X_OK): raise InvalidJavaPathError(errno.EACCES, 'Permission denied', java) args = ( [java, "-cp", classpath] + [a for a in java_flags if a != ""] + ["-Densime.config={}".format(self._config_path), "org.ensime.server.Server"]) process = subprocess.Popen( args, stdin=null, stdout=log, stderr=subprocess.STDOUT) pid_path = os.path.join(cache_dir, "server.pid") Util.write_file(pid_path, str(process.pid)) def on_stop(): log.close() with catch(Exception, lambda e: None): os.remove(pid_path) return EnsimeProcess(cache_dir, process, log_path, on_stop)
def start_process(self, classpath): cache_dir = self.config['cache-dir'] java_flags = self.config['java-flags'] Util.mkdir_p(cache_dir) log_path = os.path.join(cache_dir, "server.log") log = open(log_path, "w") null = open(os.devnull, "r") java = os.path.join(self.config['java-home'], 'bin', 'java') if not os.path.exists(java): raise InvalidJavaPathError(errno.ENOENT, 'No such file or directory', java) elif not os.access(java, os.X_OK): raise InvalidJavaPathError(errno.EACCES, 'Permission denied', java) args = ([java, "-cp", classpath] + [a for a in java_flags if a != ""] + [ "-Densime.config={}".format(self._config_path), "org.ensime.server.Server" ]) process = subprocess.Popen(args, stdin=null, stdout=log, stderr=subprocess.STDOUT) pid_path = os.path.join(cache_dir, "server.pid") Util.write_file(pid_path, str(process.pid)) def on_stop(): log.close() null.close() with catch(Exception, lambda e: None): os.remove(pid_path) return EnsimeProcess(cache_dir, process, log_path, on_stop)
def install(self): """Installs ENSIME server with a bootstrap sbt project and generates its classpath.""" project_dir = os.path.dirname(self.classpath_file) sbt_plugin = """addSbtPlugin("{0}" % "{1}" % "{2}")""" Util.mkdir_p(project_dir) Util.mkdir_p(os.path.join(project_dir, "project")) Util.write_file( os.path.join(project_dir, "build.sbt"), self.build_sbt()) Util.write_file( os.path.join(project_dir, "project", "build.properties"), "sbt.version={}".format(self.SBT_VERSION)) Util.write_file( os.path.join(project_dir, "project", "plugins.sbt"), sbt_plugin.format(*self.SBT_COURSIER_COORDS)) # Synchronous update of the classpath via sbt # see https://github.com/ensime/ensime-vim/issues/29 cd_cmd = "cd {}".format(project_dir) sbt_cmd = "sbt -Dsbt.log.noformat=true -batch saveClasspath" if int(self.vim.eval("has('nvim')")): import tempfile import re tmp_dir = tempfile.gettempdir() flag_file = "{}/ensime-vim-classpath.flag".format(tmp_dir) self.vim.command("echo 'Waiting for generation of classpath...'") if re.match(".+fish$", self.vim.eval("&shell")): sbt_cmd += "; echo $status > {}".format(flag_file) self.vim.command("terminal {}; and {}".format(cd_cmd, sbt_cmd)) else: sbt_cmd += "; echo $? > {}".format(flag_file) self.vim.command("terminal ({} && {})".format(cd_cmd, sbt_cmd)) # Block execution when sbt is run waiting_for_flag = True while waiting_for_flag: waiting_for_flag = not os.path.isfile(flag_file) if not waiting_for_flag: with open(flag_file, "r") as f: rtcode = f.readline() os.remove(flag_file) if rtcode and int(rtcode) != 0: # error self.vim.command( "echo 'Something wrong happened, check the " "execution log...'") return None else: time.sleep(0.2) else: self.vim.command("!({} && {})".format(cd_cmd, sbt_cmd)) success = self.reorder_classpath(self.classpath_file) if not success: self.vim.command("echo 'Classpath ordering failed.'") return True
def __init__(self, vim, launcher, config_path): def setup_neovim(): """Set up neovim and execute global commands.""" self.vim = vim self.vim_command("highlight_enerror") if not self.vim_eval("exists_enerrorstyle"): self.vim_command("set_enerrorstyle") self.vim_command("set_updatetime") self.vim_command("set_ensime_completion") def setup_logger_and_paths(): """Set up paths and logger.""" osp = os.path self.config_path = osp.abspath(config_path) config_dirname = osp.dirname(self.config_path) self.ensime_cache = osp.join(config_dirname, ".ensime_cache") self.log_dir = self.ensime_cache \ if osp.isdir(self.ensime_cache) else "/tmp/" self.log_file = os.path.join(self.log_dir, "ensime-vim.log") setup_logger_and_paths() setup_neovim() self.log("__init__: in") self.ws = None self.ensime = None self.launcher = launcher self.ensime_server = None self.call_id = 0 self.call_options = {} self.refactor_id = 1 self.refactorings = {} self.receive_callbacks = {} self.matches = [] self.errors = [] self.queue = Queue() self.suggestions = None self.completion_timeout = 10 #seconds self.completion_started = False self.en_format_source_id = None self.enable_fulltype = False self.enable_teardown = True self.connection_attempts = 0 self.tmp_diff_folder = "/tmp/ensime-vim/diffs/" Util.mkdir_p(self.tmp_diff_folder) self.debug_thread_id = None self.running = True Thread(target=self.queue_poll, args=()).start() self.handlers = {} self.register_responses_handlers() self.websocket_exists = module_exists("websocket") if not self.websocket_exists: self.tell_module_missing("websocket-client")
def generate_classpath(self, scala_version, classpath_file): project_dir = self.classpath_project_dir(scala_version) Util.mkdir_p(project_dir) Util.mkdir_p(os.path.join(project_dir, "project")) Util.write_file( os.path.join(project_dir, "build.sbt"), self.build_sbt(scala_version, classpath_file)) Util.write_file( os.path.join(project_dir, "project", "build.properties"), "sbt.version={}".format(self.sbt_version)) Util.write_file( os.path.join(project_dir, "project", "plugins.sbt"), """addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.0-M11")""") # Synchronous update of the classpath via sbt # see https://github.com/ensime/ensime-vim/issues/29 cd_cmd = "cd {}".format(project_dir) sbt_cmd = "sbt -Dsbt.log.noformat=true -batch saveClasspath" inside_nvim = int(self.vim.eval("has('nvim')")) if inside_nvim: import tempfile import re tmp_dir = tempfile.gettempdir() flag_file = "{}/ensime-vim-classpath.flag".format(tmp_dir) self.vim.command("echo 'Waiting for generation of classpath...'") if re.match(".+fish$", self.vim.eval("&shell")): sbt_cmd += "; echo $status > {}".format(flag_file) self.vim.command("terminal {}; and {}".format(cd_cmd, sbt_cmd)) else: sbt_cmd += "; echo $? > {}".format(flag_file) self.vim.command("terminal ({} && {})".format(cd_cmd, sbt_cmd)) # Block execution when sbt is run waiting_for_flag = True while waiting_for_flag: waiting_for_flag = not os.path.isfile(flag_file) if not waiting_for_flag: with open(flag_file, "r") as f: rtcode = f.readline() os.remove(flag_file) if rtcode and int(rtcode) != 0: # error self.vim.command( "echo 'Something wrong happened, check the " "execution log...'") return None else: time.sleep(0.2) else: self.vim.command("!({} && {})".format(cd_cmd, sbt_cmd)) success = self.reorder_classpath(classpath_file) if not success: self.vim.command("echo 'Classpath ordering failed.'") return True
def _start_process(self, classpath): """Given a classpath prepared for running ENSIME, spawns a server process in a way that is otherwise agnostic to how the strategy installs ENSIME. Args: classpath (list of str): list of paths to jars or directories (Within this function the list is joined with a system dependent path separator to create a single string argument to suitable to pass to ``java -cp`` as a classpath) Returns: EnsimeProcess: A process handle for the launched server. """ cache_dir = self.config['cache-dir'] java_flags = self.config['java-flags'] Util.mkdir_p(cache_dir) log_path = os.path.join(cache_dir, "server.log") log = open(log_path, "w") null = open(os.devnull, "r") java = os.path.join(self.config['java-home'], 'bin', 'java' if os.name != 'nt' else 'java.exe') if not os.path.exists(java): raise InvalidJavaPathError(errno.ENOENT, 'No such file or directory', java) elif not os.access(java, os.X_OK): raise InvalidJavaPathError(errno.EACCES, 'Permission denied', java) args = ( [java, "-cp", (':' if os.name != 'nt' else ';').join(classpath)] + [a for a in java_flags if a] + [ "-Densime.config={}".format(self.config.filepath), "org.ensime.server.Server" ]) process = subprocess.Popen(args, stdin=null, stdout=log, stderr=subprocess.STDOUT) pid_path = os.path.join(cache_dir, "server.pid") Util.write_file(pid_path, str(process.pid)) def on_stop(): log.close() null.close() with catch(Exception): os.remove(pid_path) return EnsimeProcess(cache_dir, process, log_path, on_stop)
def _start_process(self, classpath): """Given a classpath prepared for running ENSIME, spawns a server process in a way that is otherwise agnostic to how the strategy installs ENSIME. Args: classpath (list of str): list of paths to jars or directories (Within this function the list is joined with a system dependent path separator to create a single string argument suitable to pass to ``java -cp`` as a classpath) Returns: EnsimeProcess: A process handle for the launched server. """ cache_dir = self.config['cache-dir'] java_flags = self.config['java-flags'] iswindows = os.name == 'nt' Util.mkdir_p(cache_dir) log_path = os.path.join(cache_dir, "server.log") log = open(log_path, "w") null = open(os.devnull, "r") java = os.path.join(self.config['java-home'], 'bin', 'java.exe' if iswindows else 'java') if not os.path.exists(java): raise InvalidJavaPathError(errno.ENOENT, 'No such file or directory', java) elif not os.access(java, os.X_OK): raise InvalidJavaPathError(errno.EACCES, 'Permission denied', java) args = ( [java, "-cp", (';' if iswindows else ':').join(classpath)] + [a for a in java_flags if a] + ["-Densime.config={}".format(self.config.filepath), "org.ensime.server.Server"]) process = subprocess.Popen( args, stdin=null, stdout=log, stderr=subprocess.STDOUT) pid_path = os.path.join(cache_dir, "server.pid") Util.write_file(pid_path, str(process.pid)) def on_stop(): log.close() null.close() with catch(Exception): os.remove(pid_path) return EnsimeProcess(cache_dir, process, log_path, on_stop)
def parse_conf(self, path): def paired(iterable): """s -> (s0, s1), (s2, s3), (s4, s5), ...""" cursor = iter(iterable) return zip(cursor, cursor) def unwrap_if_sexp_symbol(datum): """ Convert Symbol(':key') to ':key' (Symbol isn't hashable for dict keys). """ return datum.value() if isinstance(datum, sexpdata.Symbol) else datum def sexp2dict(sexps): """ Transforms a nested list structure from sexpdata to dict. NOTE: This probably isn't general for all S-expression shapes parsed by sexpdata, focused only on .ensime thus far. """ newdict = {} # Turn flat list into associative pairs for key, value in paired(sexps): key = str(unwrap_if_sexp_symbol(key)).lstrip(':') # Recursively transform nested lists if isinstance(value, list) and value and isinstance(value[0], list): newdict[key] = [sexp2dict(value[0])] else: newdict[key] = value return newdict conf = sexpdata.loads(Util.read_file(path)) return sexp2dict(conf)
def launch(self): if not self.isinstalled(): raise LaunchError('Bootstrap classpath file does not exist at {}' .format(self.classpath_file)) classpath = Util.read_file(self.classpath_file) + ':' + self.toolsjar return self._start_process(classpath)
def load_classpath(self, scala_version, java_home): project_dir = self.classpath_project_dir(scala_version) classpath_file = os.path.join(project_dir, "classpath") if not os.path.exists(classpath_file): if not self.generate_classpath(scala_version, classpath_file): return None return "{}:{}/lib/tools.jar".format( Util.read_file(classpath_file), java_home)
def parse_conf(self, path): conf = Util.read_file(path).replace("\n", "").replace( "(", " ").replace(")", " ").replace('"', "").split(" :") pattern = re.compile("([^ ]*) *(.*)$") conf = [(m[0], m[1])for m in [pattern.match(x).groups() for x in conf]] result = {} for item in conf: result[item[0]] = item[1] return result
def generate_classpath(self, scala_version, classpath_file): project_dir = self.classpath_project_dir(scala_version) Util.mkdir_p(project_dir) Util.mkdir_p(os.path.join(project_dir, "project")) Util.write_file(os.path.join(project_dir, "build.sbt"), self.build_sbt(scala_version, classpath_file)) Util.write_file(os.path.join(project_dir, "project", "build.properties"), "sbt.version={}".format(self.sbt_version)) log_file = os.path.join(project_dir, "build.log") log = open(log_file, 'w') null = open("/dev/null", "r") # see https://github.com/ensime/ensime-vim/issues/29 on why we use this method self.vim.command("!(cd {};sbt -Dsbt.log.noformat=true -batch saveClasspath)".format(project_dir))
def inspect_package(self, args): pkg = None if not args: pkg = Util.extract_package_name(self.vim.current.buffer) msg = commands["display_message"].format( "Using Currently Focused Package") self.vim.command(msg) else: pkg = args[0] self.send_request({"typehint": "InspectPackageByPathReq", "path": pkg})
def inspect_package(self, args): pkg = None if not args: pkg = Util.extract_package_name(self.vim.current.buffer) msg = commands["display_message"].format("Using Currently Focused Package") self.vim.command(msg) else: pkg = args[0] self.send_request({ "typehint": "InspectPackageByPathReq", "path": pkg })
def load_classpath(self): if not os.path.exists(self.classpath_file): if not self.generate_classpath(): return None classpath = "{}:{}/lib/tools.jar".format(Util.read_file(self.classpath_file), self.config["java-home"]) # Allow override with a local development server jar, see: # http://ensime.github.io/contributing/#manual-qa-testing for x in os.listdir(self.base_dir): if fnmatch.fnmatch(x, "ensime_" + self.scala_minor + "*-assembly.jar"): classpath = os.path.join(self.base_dir, x) + ":" + classpath return classpath
def load_classpath(self, scala_version, java_home): project_dir = self.classpath_project_dir(scala_version) classpath_file = os.path.join(project_dir, "classpath") if not os.path.exists(classpath_file): if not self.generate_classpath(scala_version, classpath_file): return None classpath = "{}:{}/lib/tools.jar".format( Util.read_file(classpath_file), java_home) for x in os.listdir(self.base_dir): if fnmatch.fnmatch(x, "ensime_" + scala_version[:4] + "*-assembly.jar"): classpath = os.path.join(self.base_dir, x) + ":" + classpath return classpath
def load_classpath(self): if not os.path.exists(self.classpath_file): if not self.generate_classpath(): return None classpath = "{}:{}/lib/tools.jar".format( Util.read_file(self.classpath_file), self.config['java-home']) # Allow override with a local development server jar, see: # http://ensime.github.io/contributing/#manual-qa-testing for x in os.listdir(self.base_dir): if fnmatch.fnmatch(x, "ensime_" + self.scala_minor + "*-assembly.jar"): classpath = os.path.join(self.base_dir, x) + ":" + classpath return classpath
def parse(path): """Parse an ``.ensime`` config file from S-expressions. Args: path (str): Path of an ``.ensime`` file to parse. Returns: dict: Configuration values with string keys. """ def paired(iterable): """s -> (s0, s1), (s2, s3), (s4, s5), ...""" cursor = iter(iterable) return zip(cursor, cursor) def unwrap_if_sexp_symbol(datum): """Convert Symbol(':key') to ':key' (Symbol isn't hashable for dict keys). """ return datum.value() if isinstance(datum, sexpdata.Symbol) else datum def sexp2dict(sexps): """Transforms a nested list structure from sexpdata to dict.""" newdict = {} # Turn flat list into associative pairs for key, value in paired(sexps): key = str(unwrap_if_sexp_symbol(key)).lstrip(':') # Recursively transform nested lists if isinstance(value, list) and value: if isinstance(value[0], list): newdict[key] = [sexp2dict(val) for val in value] elif isinstance(value[0], sexpdata.Symbol): newdict[key] = sexp2dict(value) else: newdict[key] = value else: newdict[key] = value return newdict conf = sexpdata.loads(Util.read_file(path)) return sexp2dict(conf)
def parse_config(path): """Parse an .ensime project config file, from S-expressions to dict.""" def paired(iterable): """s -> (s0, s1), (s2, s3), (s4, s5), ...""" cursor = iter(iterable) return zip(cursor, cursor) def unwrap_if_sexp_symbol(datum): """ Convert Symbol(':key') to ':key' (Symbol isn't hashable for dict keys). """ return datum.value() if isinstance(datum, sexpdata.Symbol) else datum def sexp2dict(sexps): """ Transforms a nested list structure from sexpdata to dict. NOTE: This probably isn't general for all S-expression shapes parsed by sexpdata, focused only on .ensime thus far. """ newdict = {} # Turn flat list into associative pairs for key, value in paired(sexps): key = str(unwrap_if_sexp_symbol(key)).lstrip(':') # Recursively transform nested lists if isinstance(value, list) and value and isinstance( value[0], list): newdict[key] = [sexp2dict(value[0])] else: newdict[key] = value return newdict conf = sexpdata.loads(Util.read_file(path)) return sexp2dict(conf)
def http_port(self): return int(Util.read_file(os.path.join(self.cache_dir, "http")))
def __init__(self, vim, launcher, config_path): def setup_vim(): """Set up vim and execute global commands.""" self.vim = vim if not int(self.vim_eval("exists_enerrorstyle")): self.vim_command("set_enerrorstyle") self.vim_command("highlight_enerror") self.vim_command("set_updatetime") self.vim_command("set_ensime_completion") self.vim.command("autocmd FileType package_info nnoremap <buffer> <Space> :call EnPackageDecl()<CR>") self.vim.command("autocmd FileType package_info setlocal splitright") super(EnsimeClient, self).__init__() def setup_logger_and_paths(): """Set up paths and logger.""" osp = os.path self.config_path = osp.abspath(config_path) config_dirname = osp.dirname(self.config_path) self.ensime_cache = osp.join(config_dirname, ".ensime_cache") self.log_dir = self.ensime_cache if not osp.isdir(self.ensime_cache): try: os.mkdir(self.ensime_cache) except OSError: self.log_dir = "/tmp/" self.log_file = os.path.join(self.log_dir, "ensime-vim.log") with open(self.log_file, "w") as f: now = datetime.datetime.now() tm = now.strftime("%Y-%m-%d %H:%M:%S.%f") f.write("{}: {} - {}\n".format(tm, "Initializing project", config_dirname)) def fetch_runtime_paths(): """Fetch all the runtime paths of ensime-vim plugin.""" paths = self.vim_eval("runtimepath") tag = "ensime-vim" ps = [p for p in paths.split(',') if tag in p] home = os.environ.get("HOME") if home: ps = map(lambda s: s.replace(home, "~"), ps) return ps setup_logger_and_paths() setup_vim() self.log("__init__: in") self.ws = None self.ensime = None self.launcher = launcher self.ensime_server = None self.call_id = 0 self.call_options = {} self.refactor_id = 1 self.refactorings = {} self.receive_callbacks = {} self.matches = [] self.errors = [] # Queue for messages received from the ensime server. self.queue = Queue() self.suggestions = None self.completion_timeout = 10 # seconds self.completion_started = False self.en_format_source_id = None self.full_types_enabled = False """Whether fully-qualified types are displayed by inspections or not""" self.toggle_teardown = True self.connection_attempts = 0 self.tmp_diff_folder = "/tmp/ensime-vim/diffs/" Util.mkdir_p(self.tmp_diff_folder) # Set the runtime path here in case we need # to disable the plugin. It needs to be done # beforehand since vim.eval is not threadsafe self.runtime_paths = fetch_runtime_paths() # By default, don't connect to server more than once self.number_try_connection = 1 self.debug_thread_id = None self.running = True thread = Thread(target=self.queue_poll, args=()) thread.daemon = True thread.start() self.handlers = {} self.register_responses_handlers() self.websocket_exists = module_exists("websocket") if not self.websocket_exists: self.tell_module_missing("websocket-client") if not module_exists("sexpdata"): self.tell_module_missing("sexpdata")
def __init__(self, vim, launcher, config_path): def setup_vim(): """Set up vim and execute global commands.""" self.vim = vim if not int(self.vim_eval("exists_enerrorstyle")): self.vim_command("set_enerrorstyle") self.vim_command("highlight_enerror") self.vim_command("set_updatetime") self.vim_command("set_ensime_completion") self.vim.command( "autocmd FileType package_info nnoremap <buffer> <Space> :call EnPackageDecl()<CR>" ) self.vim.command( "autocmd FileType package_info setlocal splitright") super(EnsimeClient, self).__init__() def setup_logger_and_paths(): """Set up paths and logger.""" osp = os.path self.config_path = osp.abspath(config_path) config_dirname = osp.dirname(self.config_path) self.ensime_cache = osp.join(config_dirname, ".ensime_cache") self.log_dir = self.ensime_cache if not osp.isdir(self.ensime_cache): try: os.mkdir(self.ensime_cache) except OSError: self.log_dir = "/tmp/" self.log_file = os.path.join(self.log_dir, "ensime-vim.log") with open(self.log_file, "w") as f: now = datetime.datetime.now() tm = now.strftime("%Y-%m-%d %H:%M:%S.%f") f.write("{}: {} - {}\n".format(tm, "Initializing project", config_dirname)) def fetch_runtime_paths(): """Fetch all the runtime paths of ensime-vim plugin.""" paths = self.vim_eval("runtimepath") tag = "ensime-vim" ps = [p for p in paths.split(',') if tag in p] home = os.environ.get("HOME") if home: ps = map(lambda s: s.replace(home, "~"), ps) return ps setup_logger_and_paths() setup_vim() self.log("__init__: in") self.ws = None self.ensime = None self.launcher = launcher self.ensime_server = None self.call_id = 0 self.call_options = {} self.refactor_id = 1 self.refactorings = {} self.receive_callbacks = {} self.matches = [] self.errors = [] # Queue for messages received from the ensime server. self.queue = Queue() self.suggestions = None self.completion_timeout = 10 # seconds self.completion_started = False self.en_format_source_id = None self.full_types_enabled = False """Whether fully-qualified types are displayed by inspections or not""" self.toggle_teardown = True self.connection_attempts = 0 self.tmp_diff_folder = "/tmp/ensime-vim/diffs/" Util.mkdir_p(self.tmp_diff_folder) # Set the runtime path here in case we need # to disable the plugin. It needs to be done # beforehand since vim.eval is not threadsafe self.runtime_paths = fetch_runtime_paths() # By default, don't connect to server more than once self.number_try_connection = 1 self.debug_thread_id = None self.running = True thread = Thread(target=self.queue_poll, args=()) thread.daemon = True thread.start() self.handlers = {} self.register_responses_handlers() self.websocket_exists = module_exists("websocket") if not self.websocket_exists: self.tell_module_missing("websocket-client") if not module_exists("sexpdata"): self.tell_module_missing("sexpdata")
def __init__(self, vim, launcher, config_path): def setup_vim(): """Set up vim and execute global commands.""" self.vim = vim if not int(self.vim_eval("exists_enerrorstyle")): self.vim_command("set_enerrorstyle") self.vim_command("highlight_enerror") self.vim_command("set_updatetime") self.vim_command("set_ensime_completion") def setup_logger_and_paths(): """Set up paths and logger.""" osp = os.path self.config_path = osp.abspath(config_path) config_dirname = osp.dirname(self.config_path) self.ensime_cache = osp.join(config_dirname, ".ensime_cache") self.log_dir = self.ensime_cache \ if osp.isdir(self.ensime_cache) else "/tmp/" self.log_file = os.path.join(self.log_dir, "ensime-vim.log") def fetch_runtime_paths(): """Fetch all the runtime paths of ensime-vim plugin.""" paths = self.vim_eval("runtimepath") tag = "ensime-vim" ps = [p for p in paths.split(',') if tag in p] home = os.environ.get("HOME") if home: ps = map(lambda s: s.replace(home, "~"), ps) return ps setup_logger_and_paths() setup_vim() self.log("__init__: in") self.ws = None self.ensime = None self.launcher = launcher self.ensime_server = None self.call_id = 0 self.call_options = {} self.refactor_id = 1 self.refactorings = {} self.receive_callbacks = {} self.matches = [] self.errors = [] self.queue = Queue() self.suggestions = None self.completion_timeout = 10 # seconds self.completion_started = False self.en_format_source_id = None self.enable_fulltype = False self.toggle_teardown = True self.connection_attempts = 0 self.tmp_diff_folder = "/tmp/ensime-vim/diffs/" Util.mkdir_p(self.tmp_diff_folder) # Set the runtime path here in case we need # to disable the plugin. It needs to be done # beforehand since vim.eval is not threadsafe self.runtime_paths = fetch_runtime_paths() # By default, don't connect to server more than once self.number_try_connection = 1 self.debug_thread_id = None self.running = True Thread(target=self.queue_poll, args=()).start() self.handlers = {} self.register_responses_handlers() self.websocket_exists = module_exists("websocket") if not self.websocket_exists: self.tell_module_missing("websocket-client")