From 0c5bb9eb0531a0b277c1c06f2063b7f8f89324e8 Mon Sep 17 00:00:00 2001 From: Clay Sweetser Date: Tue, 9 Feb 2016 01:43:21 -0500 Subject: [PATCH] Add nimsuggest setup commands. --- Support/Default.sublime-commands | 4 ++ nimlime_core/commands/idecommands.py | 65 ++++++++++++++++++++++++--- nimlime_core/configuration.py | 12 +++-- nimlime_core/utils/error_handler.py | 3 +- nimsuggest.tar.gz | Bin 0 -> 12432 bytes 5 files changed, 73 insertions(+), 11 deletions(-) create mode 100644 nimsuggest.tar.gz diff --git a/Support/Default.sublime-commands b/Support/Default.sublime-commands index 8f2f15c..bef7212 100644 --- a/Support/Default.sublime-commands +++ b/Support/Default.sublime-commands @@ -67,5 +67,9 @@ { "caption": "Nim: Get Suggestion", "command": "nim_get_suggestions" + }, + { + "caption": "Nim: Setup Nimsuggest.", + "command": "nim_compile_internal_nimsuggest" } ] \ No newline at end of file diff --git a/nimlime_core/commands/idecommands.py b/nimlime_core/commands/idecommands.py index 22bdfa3..f80ca98 100644 --- a/nimlime_core/commands/idecommands.py +++ b/nimlime_core/commands/idecommands.py @@ -2,17 +2,23 @@ """ Commands and code to expose nimsuggest functionality to the user. """ +import os +import tarfile from pprint import pprint -from traceback import print_stack - -import sys +from tempfile import mkdtemp +from zipfile import ZipFile import sublime -from nimlime_core.utils.error_handler import catch_errors -from nimlime_core.utils.misc import send_self, get_next_method, samefile -from nimlime_core.utils.mixins import (NimLimeOutputMixin, IdetoolMixin) from sublime_plugin import ApplicationCommand +import NimLime +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) +from nimlime_core.utils.mixins import (NimLimeOutputMixin, IdetoolMixin, + NimLimeMixin) + class NimIdeCommand(NimLimeOutputMixin, IdetoolMixin, ApplicationCommand): requires_nimsuggest = True @@ -20,6 +26,50 @@ class NimIdeCommand(NimLimeOutputMixin, IdetoolMixin, ApplicationCommand): st2_compatible = False +class NimCompileInternalNimsuggest(NimLimeMixin, ApplicationCommand): + """ + Compile the version of Nimsuggest bundled with NimLime. + """ + requires_nim = True + + @send_self + @catch_errors + def run(self): + this = yield + 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)", '', + this.send, None, None + ) + if exe_path == '': + exe_path = mkdtemp() + + if not (os.path.exists(exe_path) and os.path.isdir(exe_path)): + sublime.status_message("Invalid path.") + yield + + nimlime_dir = os.path.dirname(NimLime.__file__) + nimsuggest_file = os.path.join( + nimlime_dir, 'nimsuggest', 'nimsuggest.nim' + ) + if os.path.exists(nimsuggest_file): + # Either we're using an actual file + run_process( + [configuration.nim_executable, 'c', nimsuggest_file] + ) + else: + # Or we're using a zipped version + package_file = ZipFile(os.path.join(nimlime_dir)) + package_file.extract('nimsuggest.tar.gz', exe_path) + tarfile.open( + os.path.join(exe_path, 'nimsuggest.tar.gz') + ).extractall(exe_path) + + class NimGotoDefinition(NimIdeCommand): """ Goto definition of symbol at cursor. @@ -72,6 +122,7 @@ def run(self): yield + class NimShowDefinition(NimIdeCommand): """ Show definition of symbol at cursor. @@ -175,7 +226,7 @@ def run(self): if samefile(filename, view.file_name()): index += 1 else: - del(entries[index]) + del (entries[index]) index = yield window.show_quick_panel( ['({5},{6}) {3}'.format(*entry2) for entry2 in entries], diff --git a/nimlime_core/configuration.py b/nimlime_core/configuration.py index 62d2314..39845fa 100644 --- a/nimlime_core/configuration.py +++ b/nimlime_core/configuration.py @@ -20,8 +20,12 @@ in NimLime's settings file to 'False'. """) +nimsuggest_not_found_msg = not_found_msg + format_msg("""\\n +NOTE: The Nimsuggest must be the versions generated by the +'setup nimsuggest' command. +""") -def gen_exe_check(program_name, setting_key, default_exe): +def gen_exe_check(program_name, setting_key, default_exe, message=None): """ Generates a function that checks if a program is on the path, based off of settings. May also notify the user if the check can't find the @@ -54,7 +58,7 @@ def callback(): sublime.set_timeout(callback, 500) return sublime.error_message( - not_found_msg.format(program_name, setting_key) + (message or not_found_msg).format(program_name, setting_key) ) callback() @@ -74,7 +78,7 @@ def callback(): _nimble_exe_check = gen_exe_check('Nimble', 'nimble.executable', 'nimble.exe') _nim_exe_check = gen_exe_check('Nim', 'nim.executable', 'nim.exe') _nimsuggest_exe_check = gen_exe_check('Nimsuggest', 'nimsuggest.executable', - 'nimsuggest.exe') + 'nimsuggest.exe', nimsuggest_not_found_msg) def _check_for_nimble_exe(): @@ -95,3 +99,5 @@ def _check_for_nimsuggest_exe(): settings.run_on_load_and_change('nimble.executable', _check_for_nimble_exe) settings.run_on_load_and_change('nim.executable', _check_for_nim_exe) settings.run_on_load_and_change('nimsuggest.executable', _check_for_nimsuggest_exe) + +is_zipped = not os.path.isfile(__file__) \ No newline at end of file diff --git a/nimlime_core/utils/error_handler.py b/nimlime_core/utils/error_handler.py index 16ff6db..5fd8259 100644 --- a/nimlime_core/utils/error_handler.py +++ b/nimlime_core/utils/error_handler.py @@ -20,6 +20,7 @@ import os import sys +import tempfile import traceback from time import strftime @@ -51,7 +52,7 @@ 'error_handler.enabled' setting in NimLime's settings file to 'False'. """) -default_logfile_path = os.path.join(root_dir) +default_logfile_path = tempfile.gettempdir() enabled = True logfile_path = default_logfile_path diff --git a/nimsuggest.tar.gz b/nimsuggest.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..601ffd25c9e27c9648b55e3bbacd1713be54c4d9 GIT binary patch literal 12432 zcmV;BFmKNviwFp7ud`MH0B&h*b9HBDWpi{cbYXG;>|N<{<3teVH&wjDV2()O6-kz> z%uy`a1yWprgrh11O0mbbh%FgO-Xt9F&ez>@S|Z7Eglk0+OEWz^Jv}`=-90UBSuC6N zY^Iy`r6>NXYkT|U?blv=4ZnOvzxIA-_tjTke&v-{@9y4xVtZ$Mcjx6N)GJTi!nJPN zynX@{{6DW?{+HE6H!uAo=6?r2kLUkyng4OMTvp}BxX)1cr}TmKeAWEF`r0e6y7}MP z1>DZdJ1@WTgxY>Q|9|;aELT1)Pyl!;0YR#RgY4i`~uGFZiCrvvk z%Av}#ml}Psdg{q%)cs0*^68PXNJX$Rwco1qVzE#QoljI-;X&6Eb-JE4xNYZXX<>`1 z{9HHdMf*WjoekBg9_Q;u+gg%HRWzz7$BXqu1I49kirF%6$McM^90Iqt-M90+RaL10 z-n8f$5K==Fd%1U|ko;A#(Dh5zis)#Du7npwUQWUytd{jchb4_(4xf5b`GQs6G=PW; z^7TcCrJ02QplV!|(-@7uXvg#r(F0;GmtoUI(X>t6(6T0g%4xh$J$XLYrJCqzQR+!@ zUX+vSyh%rBY-yYW3uWWW1b=Na~7m_J*p~?P{bR=Cv!KMcIxpb8X6h)muQt5C!_; zS|&=ph^Mn+_0_y+b+gLHnlKMlk#hA^;pw>a_Yb-0uX(gk;1L`I;it-FCElE=>hNC(kpJ5gSp4ve$vNB)ltjQL-L}#^b*L5j1 z8>5<5#L=Qu+gKEDswSW6k93)oEDU@tbPEKSVQP;#2RAc2B7zY@802Zd6bsiMiX0En z^Lur*+y{xtj7dJInvpvC2ogwz0ZXJy+^U&wKju~Do1p6j8cg&>>Y2C9isqAIF;oM! zug*$+u8Nje*wf1Jb7^Q*Sk!2aRbh!I06&XT7mU{pNMGpjy46OI_a}Ofjqkh=-f3_8Wog*THW4T zEQDE2lDf6hd{|cJ<$E9noj}EF!(JhAe{z9hBGfQwTA?TjS^<;L<;Mh>Vj{Ljij-G| zuJ2PFfhQJiz=PCE+|}^ly>#Yh4YXk{t%P`3&&-tJAJlbK?^Wxv)wKd)Lh&Zw-gInR zH~CDnuu-peg;j0HE(Ud~^q{W3*W)%x`%z=Qc4?~IgknAYgc-cAr$aN7{Cj`h{6cVc z*~B~rmThz^70o!u4ml_*ut4*kS!+WKFkH5CNY%h{)(fp&Fm8UWqHqN?bu%-bkMp8L zku;AHY{K-i!{Rh-iH9E#oBI&aTZ8Xi9==Ut-LEE68Kj#xH>P#8XmQaV_ys{V$(o50 z{`mT8oG(~hJa%Y}DP(5?383yzD<}oB9g2qcx|WC=sOQzQo}PF|!-z>nqb?i&^U#*#NoR1Fs zFzQe)VBW+Mf`~OhcW1{IU^fumA6jbrMkE;=&96t_-yFzo?K8Ywl7X445!)GZAJr2- zxRP$78aHCDc25xu=#^^R#5EuV6>j&lc1U7qkp2R+!ESkHC%u9HuUF&1`M(AKe`n|A z?M?sx?#nydkNy8!^#9xZbfLww_wN7h(8UGfNI(@t16&}W-@A6A&`J#rxX>8OQy+%`u2tPgQkFmMd+IwnFx%M%NE@O_Yw9UMV#MSgVem1aTQ~t;lk1 z0DoFlDB}LUC?VHS94=%=>?)Rg(Mw0x_rc=*2Wb|g7Mg3 zL*^+55d9?EuFlZU6Bq?2ES3Z%-kb$ERWvUoycNJbC#~?go*r8_ma6w1&Gm_~AsPI5 z0I?Zh&)*o8Ovy8TVEg2#O%bY5AM18rO<;X3`9={Hpw|jjG6DD~oJFV|D{w~i4xxs0 zIo3>x#4`j0RCr*j5^L0yaXdvzE4EfXs>+!dbVGVPoP(3{%#AzE^<`|+8cc)LV2D3x zEOw+^ZGGvVaM8GWCe9fhrV|+CYn`UPrDg$AUs5@{F(Fp54V@j&%W#W4mk=8s2U~+Q zpxCW4;0o#U!V@82px6VkK7{L=<-tzF*0axmis#g^=iG@Ok~3%{oZbh<99ik$K4eOI zBtzz3=!n%9kehD2q|=6!G&XLNLYPoM5gv?|>z-}8z(?>sKP<|df**>mjG)Dm+n=h- zYOTieyqsz5JX)c$R&!m$P+R6_w1w58D+Q#0`hcuJqy+)?gFD3IOfLXcWzpJ(eg$kx zohHY^P0|u$mTmWZxug}~o_|lv@{C}c-cn+Rq&W4<%m2C-=+ zoemb->iT-tKy^2EN(VGp@iSy7-liU8&1ykwO$}1dD~=u5)r#SY&UEMqlLW3C3NY*p zEm}Nm2L?NtEMjToi$Qt~4~zjqd^l#8dMLj0P@LqUc*8?+dry22#;LUB#1d#wxuq$K z?!Iouou0!=W;oFFS6HU@*E%MpohkH?>1N0k(-;R`sS`h~>BhW@FUvs3+b0=f%8+WQ z!j!nG9j^Lhy_71M8(X;>R`z?z#S~qZJm6Hlt?ml1J)lK(*OHKwMeM!&bj!_QzeyG+3`1EeUi)+6`foBx2)c6uy-$@jVMkWOV&r+JA z74$C+=h;Zn_$81;Xi_Eu9gETzBB74TNzzsy=!=B7X0ZbJ)wBcWYJYp_$m zZYQrSvC=3*X!&7c0B8m%too{t3g<8eTdl%)RK8g7b~e`+rzP4Pj)UL0^Fk~R!H#Z6600>RgYK8Qp}_FF>*-Y2zs-dROei9D z@Xa6Lh+{{rfGt@zGIq$uL_|co0eW<~0=RuLDos|Nw{k;ZAzQ+mAjjKzV2e??8@n*j zzjJ(Iz>OEia#^&p8`~8Xk6e*n@B@hzu-lz1V?@^{7I-%pwPTR%;Q`9K zZVd6(AzOxP=T)dkg4I|w7iJ)7YMJPi;#Jbn^#g}|mLpA-ts8W(-q9pNe>QH|!<&c^ zu|Y|8UKg#V?Ii&L<3c~w69s6+(6W~Lq_Ll}{ZH)za4145M01Ou(a-m;EDXKj7WfE{ z%$~I?Q?vwlVBr!;pZLFC-S{uZ@>~S?HuAsjzIu0OGyeP9t9KvAfB!l0-|M5iKDcWk z;%H_VUSvd92N(|tq%Xu+P>8Xh2vQDH=%F4RlcDqTG>2X|2`$>s*QElA0F=WL7}C1n z(Xvg2%4Gphi-MDxX~}^^Pp!wWNiQEYk7$GZ8K6JIGNVq@TL@0F(ESDBNnzi=CqU`vkOKon822lt zaj@_$67+85(xV8|iaK$@IQDrJ4$(O8LZIT%r?k61_SuboeiM%Kn}K3{DD8`fqBMQf zuqIGF`^@OsXV5l|Z4M*!e^#VZgsd;t$zt6f?d*4#uRut8+L(l;vGNl!^HCF|ws6k` z?Y!I-bVhN(i9Ma^g|+pz8px2v?dpX>xnnqVcZsf4?}ji)Lr{~8#Hw|KS#eXs9jv65 zVwNXCvmTueW<{w5pw#=)waz)mhjNpckVFP-&gX3|J$zu7m%no(7wOf90G-n4?OU2O&) z?H%0socYf?YwkI3e#v6$o;wR7a~iBV*IunD<1SYQA}`w@k|%iwMN@8}bWt^$_WY}^ zdo~b=4x(=0X(5Rdao8*mvvT7w$A}1@2)Kzv3mQN}nB5w_i^np#*Al0=fXl=H|U;b)MM z+2hT;ypB&Sw{(nw12SfgjL#t062qH-wys9xti7R4GJ!$H(uKXwkhK&hNL06DsUMA3 zH?q@LK_0`ESq#EqYsl{^ecK#yIzx^(xtcgz_+U*33gA;jlTVgV=~^Z1*OtYpOJkWnKc zy-RV@J*MpRXI-uYJni$OP@FY}z5T>GDg{8^@rjn!sCT4nhFPBVQokuvd#pUJk|`%1 z>$XQgt`e&*r(`VgWc$}(t`~&vfWq{@4TY!l~5OX zgX6a4YU*(vYIfOKWx(i08|bI3y=VtR_d*74_&rP0WKxiZJ6*FU!|u>Tw>e@@DnEr5 zW^`lQdB$Dg&oiOYD*(&Rzl2rhum?FvGow=mJt^9%Zq)w$2Z+O-0a?DvPm2XSKHUIc z90}_`1g)BzeG)^yhw*=Wg+u~-1dJXx-;-8@?QAF8W>0_qn?b)j>IhTl=MCGzrJ23{ z$zx#w0(&AG_pXi&*H6?j`6=e-J6AebVe5LStzI%anLU=}$cue1SHf2)rG0M1O$JJd zsEce;kqs_^7{{4Rnm*iBor_-aN2hHy#&{nZE?GEfCI`Lo^`PYQYpKH0fX!k$A*OD2 zasabI)`Ed$c7e(urbP@fC=3~06d_A3P+J)rX~+RYHhVH+8<`%$H27wlLvA5=cTRHz zJB=B~G2)y-CC{=i=y(KGffde_n{ckDo7de`QavQ%ot1WWOY{sbH3n9z$~ln{B7_QP&PDA^D)uz;>6DD7F&SYqU7|Zl-OOvs?_ZH((31?Zu4wV9JQ5n) z%N_0o>1yjGWk}hBwxTuf!VNGf*+89x`HY6Fz!|@tY)KPUsxNZ*kDaB#5}nD1U`DlG zXt0Z?VPh$9AToTjsw{1Kdnc-hY8Nqkp%bS3ysFwyPrr8`u+T4z95N{k?8#1@T`WeU z@W(Vvk8ynO1#3Hpp-O>_qi+D@+(+YxtidF?$3>C0kuomAhjqN&Otee zxgi)FLxdTg12Kwlehz;lWa!&o3E`ya3aFUjo|I1PQzD)?hh3ju7xuhK%=4#=mS*+~ zc|O-?)DlLlE6wL51xYe3ht2K>=@r2vPu8E)dDy|=3QzA(?>OvWklK0L7fScQ1Y^�eMZ2lJ+G)aWrUyGBgUB+ICfw0qUDx1iJhQh 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 O2><|SA8ly> literal 0 HcmV?d00001