Skip to content

Commit

Permalink
Fix and enhance the 'Setup Nimsuggest' command.
Browse files Browse the repository at this point in the history
  • Loading branch information
Varriount committed Feb 9, 2016
1 parent 0c5bb9e commit d3ceeca
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 32 deletions.
1 change: 1 addition & 0 deletions NimLime.sublime-settings
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// These *must* be in absolute form, or the name of the executable
// (if it's in the PATH environment variable)
"nimble.executable": "nimble",
"nimsuggest.executable": "nimsuggest",
"error_handler.enabled": true,
"error_handler.logpath": "",

Expand Down
101 changes: 75 additions & 26 deletions nimlime_core/commands/idecommands.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,25 @@
Commands and code to expose nimsuggest functionality to the user.
"""
import os
import platform
import shutil
import subprocess
import tarfile
from pprint import pprint
import traceback
from shutil import copytree
from tempfile import mkdtemp
from zipfile import ZipFile

import sublime
from sublime_plugin import ApplicationCommand

import NimLime
import sublime
from nimlime_core import configuration
from nimlime_core.utils.error_handler import catch_errors
from nimlime_core.utils.misc import (send_self, get_next_method, samefile,
run_process, busy_frames)
run_process, busy_frames, format_msg,
loop_status_msg, start_file)
from nimlime_core.utils.mixins import (NimLimeOutputMixin, IdetoolMixin,
NimLimeMixin)
from sublime_plugin import ApplicationCommand


class NimIdeCommand(NimLimeOutputMixin, IdetoolMixin, ApplicationCommand):
Expand All @@ -26,11 +30,18 @@ class NimIdeCommand(NimLimeOutputMixin, IdetoolMixin, ApplicationCommand):
st2_compatible = False


setup_error_msg = format_msg("""
Nimsuggest doesn't appear to have been setup correctly.\\n
Please look at the output of the debug console (ctrl+`) for more information.
""")


class NimCompileInternalNimsuggest(NimLimeMixin, ApplicationCommand):
"""
Compile the version of Nimsuggest bundled with NimLime.
"""
requires_nim = True
st2_compatible = False

@send_self
@catch_errors
Expand All @@ -39,35 +50,74 @@ def run(self):
window = sublime.active_window()
view = window.active_view()

frames = ["Compiling Internal Nimsuggest" + f for f in busy_frames]

exe_path = yield window.show_input_panel(
"Path to copy nimsuggest to? (Blank for temporary directory)", '',
'Path to copy nimsuggest to? (Blank for home directory)', '',
this.send, None, None
)
if exe_path == '':
exe_path = mkdtemp()
exe_path = exe_path or os.path.expanduser('~')

if not (os.path.exists(exe_path) and os.path.isdir(exe_path)):
sublime.status_message("Invalid path.")
if not (os.path.exists(exe_path) or not os.path.isdir(exe_path)):
sublime.error_message('Invalid path for nimsuggest executable.')
yield

frames = ['Compiling Internal Nimsuggest' + f for f in busy_frames]
stop_status_loop = loop_status_msg(frames, 0.15)

extraction_path = mkdtemp()

nimlime_dir = os.path.dirname(NimLime.__file__)
nimsuggest_file = os.path.join(
nimlime_dir, 'nimsuggest', 'nimsuggest.nim'
nimsuggest_src_source = os.path.join(nimlime_dir, 'nimsuggest')
nimsuggest_src_dest = os.path.join(extraction_path, 'nimsuggest')

nimsuggest_src_exe = os.path.join(
nimsuggest_src_dest, 'nimsuggest'
)
if os.path.exists(nimsuggest_file):
if platform.system() == 'Windows':
nimsuggest_src_exe += '.exe'

if os.path.isdir(nimlime_dir):
# Either we're using an actual file
run_process(
[configuration.nim_executable, 'c', nimsuggest_file]
)
copytree(nimsuggest_src_source, nimsuggest_src_dest)
else:
# Or we're using a zipped version
package_file = ZipFile(os.path.join(nimlime_dir))
package_file.extract('nimsuggest.tar.gz', exe_path)
package_file = ZipFile(nimlime_dir)
package_file.extract('nimsuggest.tar.gz', extraction_path)
tarfile.open(
os.path.join(exe_path, 'nimsuggest.tar.gz')
).extractall(exe_path)
os.path.join(extraction_path, 'nimsuggest.tar.gz')
).extractall(extraction_path)

data = yield run_process(
[configuration.nim_executable, 'c', 'nimsuggest.nim'],
cwd=nimsuggest_src_dest,
callback=this.send,
stdout=subprocess.PIPE
)

yield stop_status_loop(get_next_method(this))

setup_error = False
if data[0].poll() != 0:
setup_error = True
sublime.error_message(setup_error_msg)

try:
shutil.copy(nimsuggest_src_exe, exe_path)
except:
setup_error = True
sublime.error_message(setup_error_msg)
traceback.print_exc()

if not setup_error:
sublime.status_message('Nimsuggest compiled.')
sublime.run_command("open_file", {
"file": "${packages}/User/NimLime/NimLime.sublime-settings"
})
sublime.message_dialog("Please make sure to set the "
"'nimsuggest.exe' setting!")
start_file(exe_path)

print(data[1])
yield


class NimGotoDefinition(NimIdeCommand):
Expand Down Expand Up @@ -100,7 +150,7 @@ def run(self):

if len(entries) == 0:
sublime.status_message(
"NimLime: No definition found in project files."
'NimLime: No definition found in project files.'
)
yield
elif len(entries) > 1 and not self.ask_on_multiple_results:
Expand Down Expand Up @@ -195,8 +245,8 @@ def run(self):
yield sublime.set_timeout(get_next_method(this), 1000)
view.show_at_center(view.text_point(int(entry[5]), int(entry[6])))
else:
sublime.status_message("NimLime: No definition found in project "
"files.")
sublime.status_message('NimLime: No definition found in project '
'files.')

yield

Expand Down Expand Up @@ -261,7 +311,6 @@ def run(self):
output, entries = yield nimsuggest.get_suggestions(
nim_file, dirty_file, line, column, this.send
)
pprint(entries)
yield

# class NimOutputInvokation(NimIdeCommand):
6 changes: 3 additions & 3 deletions nimlime_core/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@
in NimLime's settings file to 'False'.
""")

nimsuggest_not_found_msg = not_found_msg + format_msg("""\\n
nimsuggest_not_found_msg = format_msg("""\\n
NOTE: The Nimsuggest must be the versions generated by the
'setup nimsuggest' command.
""")
'setup nimsuggest' command.\\n
""") + not_found_msg

def gen_exe_check(program_name, setting_key, default_exe, message=None):
"""
Expand Down
17 changes: 15 additions & 2 deletions nimlime_core/utils/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Misc. functions that don't really fit anywhere else.
"""
import os
import platform
import subprocess
import sys
from functools import wraps
Expand Down Expand Up @@ -201,9 +202,12 @@ def run_process(cmd, callback=None, timeout=0, *args, **kwargs):


def _run_process_worker(cmd, callback, timeout, args, kwargs):
if platform.system() == "Windows":
kwargs = kwargs.copy()
kwargs['creationflags'] = 0x08000000

process = subprocess.Popen(
cmd,
creationflags=0x08000000,
universal_newlines=True,
*args,
**kwargs
Expand All @@ -217,7 +221,8 @@ def kill_process():
sublime.set_timeout(kill_process, int(timeout * 1000))

stdout, stderr = process.communicate()
sublime.set_timeout(lambda: callback((process, stdout, stderr)), 0)
if callback is not None:
sublime.set_timeout(lambda: callback((process, stdout, stderr)), 0)


def split_semicolons(string):
Expand Down Expand Up @@ -300,6 +305,14 @@ def samefile(path_one, path_two):
stat_one.st_dev == stat_two.st_dev
)

def start_file(path):
if platform.system() == "Windows":
os.startfile(path)
elif platform.system() == "Darwin":
subprocess.Popen(["open", path])
else:
subprocess.Popen(["xdg-open", path])


def exec_(code, global_dict=None, local_dict=None):
"""
Expand Down
3 changes: 2 additions & 1 deletion nimlime_core/utils/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"""
import json
import os
import platform
import re

import sublime
Expand Down Expand Up @@ -56,7 +57,7 @@ def _find_project_in_data(session_data, win_id):
for window in session_data.get('windows', ()):
if window.get('window_id') == win_id and 'workspace_name' in window:
project = window['workspace_name']
if sublime.platform() == 'windows':
if platform.system() == "Windows":
project = os.path.normpath(
project.lstrip("/").replace("/", ":/", 1)
)
Expand Down

0 comments on commit d3ceeca

Please sign in to comment.