找回密码
 立即注册!
搜索

小喇叭+ 发布

12-31 23:03
系统消息:尊敬的用户,动象论坛的邮件系统已经完美修复,您现在可以顺利使用自助注册和找回密码功能了。万分感谢你对动象论坛的喜爱与支持~
06-10 15:28
系统消息:很抱歉的通知您,当前论坛的邮件系统暂时出现故障,因此自助注册和找回密码的功能将无法使用。如有任何需要,您可以直接添加客服QQ:230273459进行人工操作。对此给您带来的不便,我们深感歉意。
06-10 09:11
admin动象论坛祝大家端午快乐~悠悠粽草,人间芳华,年年岁岁皆如愿,岁岁年年长安康。
06-10 09:09
系统消息:动象论坛祝大家高考加油~
06-09 15:13
系统消息:各位坛友,由于“两会”封网原因,动象论坛服务中止了约一个星期,对于由此给您造成的麻烦我们感到万分抱歉。
03-18 23:04
admin动象论坛在这里祝大家2024龙年新年快乐~
02-09 14:58
系统消息:论坛端口问题已经解决~您可以直接访问论坛域名mcmc.ltd(www.mcmc.ltd)啦~(Tips:如访问时提示“连接被重置”报错,请清空您的DNS缓存与浏览器缓存。)
02-05 19:14
系统消息:论坛预计今天晚间将端口问题修复完成,请留意论坛动态,感谢您对动象论坛的支持~
02-05 14:06
系统消息:动象论坛目前正在紧急迁移服务器,目前请您先访问https://mcmc.ltd:150。论坛正在全力找CDN以修复端口问题,由此给您造成影响亿常抱歉。。
02-05 11:23
系统消息:动象论坛祝大家2024年新年快乐吖~祝大家前路浩浩荡荡,万事皆可期待~
12-31 22:41
系统消息:动象论坛拟于7月20日至7月21日进行服务器迁移和域名更换,届时论坛服务将暂时不可用。对此给您带来的麻烦,我们感到十分抱歉。
07-18 19:51
Mozillahello world
07-04 17:39
系统消息:高考倒计时2天!动象论坛祝大家2023高考完胜!加油!!!!!!
06-04 23:44
神秘人:
03-21 07:20
系统消息:向各位论坛坛友公开一下,我们现在吸收了@luoying2334 为论坛管理团队成员,管理讨论区、软件分享区和得闲饮茶区。如您有任何质疑,请您在【意见与建议】版块发帖,感谢您的支持~
03-20 23:23
admin论坛没啥人气啊emmm,欢迎大家来推荐退荐~
03-12 22:34
02-05 11:11
luoying2334给我学狗叫啊,三回啊三回
02-05 11:11
Civilmafia追尾黑色高级车
02-04 14:27
查看: 1188|回复: 6

Sublime_plugin源代码免费分享!

[复制链接]

54

主题

156

回帖

371

积分

试剑江湖

致敬·Mozilla Firefox

积分
371

最佳新人活跃会员

发表于 2020-5-3 15:31:35 | 显示全部楼层 |阅读模式 IP:江苏苏州
本帖最后由 Mozilla 于 2020-5-3 16:02 编辑 $ b+ s1 [1 F/ E
" Y. o" o8 @% Z! i8 x, E
sublime_text3组件Sublime_plugin源代码免费分享!请不要翻译此页!
" a0 Q. A, X# W5 S( E" f
  1. import imp2 T) N9 D! ?* r. X6 V" t. p9 Q
  2. import importlib0 z4 U) w. G0 Y# q/ Z
  3. import os
    7 p/ r  s6 }9 g! I
  4. import sys6 o: w& p6 X6 n7 A
  5. import threading
    2 }( Y& O) a5 _* e; a7 K
  6. import time2 |8 {9 n+ s( `3 d- R, j2 s! i
  7. import traceback
      k- `4 z  [& S% Z
  8. import zipfile
    0 W8 O! R# b. l" r7 |' S/ C

  9. ; G: e: V; a1 o4 C3 y
  10. import sublime
    0 H* [% R' g1 [9 h% Y( e
  11. import sublime_api
    % J( K2 P0 V3 Y) ~
  12. ; B2 x# i. x  h2 P# h" j
  13. ) K( I* q8 O) c) w1 @0 p% i8 Z
  14. api_ready = False$ M% A. Z4 O- V& ~2 D# U; L+ M

  15. % O  ?& c  P. f/ K6 J; ?7 {5 N
  16. application_command_classes = []' A* W" M) _% `$ b. q. k* ?7 Q
  17. window_command_classes = []
    1 N) Z; [5 [* q) E' y; A' p
  18. text_command_classes = []0 ^3 r; B4 @& U6 k3 x

  19. ( ?) D9 B3 D3 m
  20. view_event_listener_classes = []4 c" `6 o$ B: K6 D4 ~6 M) v- R3 Z+ l
  21. view_event_listeners = {}
    9 H; c" W+ S: Y9 o' N7 S- T  ^1 ~0 x

  22. # P: p& x. p& ~# ?# O0 G# g: X" D
  23. all_command_classes = [
    9 U% F. `' H  f8 h2 }' s* ^2 O
  24.     application_command_classes,8 a" Q  j) p7 B  R+ ^! A' p; A
  25.     window_command_classes,
    * N, o% Q& i2 z" F/ ]4 t
  26.     text_command_classes]
    8 V8 m0 d6 }; X& U2 i
  27.   b2 W; P# x" y0 d
  28. all_callbacks = {( ^  H/ K( O  F$ o0 U
  29.     'on_new': [],3 o  q' p: j9 G% F$ f
  30.     'on_clone': [],
    + s; {& n* c% D( z" W0 ~
  31.     'on_load': [],5 s+ n- {# D4 T( m1 [
  32.     'on_pre_close': [],
    9 ?/ P" f( Y% Q1 L7 R
  33.     'on_close': [],
    5 R, ?" Z. D( X1 ?$ G! v( ~. ]& E% W
  34.     'on_pre_save': [],% D# ?: k+ I9 z1 [
  35.     'on_post_save': [],
    & P2 m( k' ?7 I6 Y
  36.     'on_modified': [],
    , T0 P& K# f$ t5 \+ E- i1 S9 D  B" j
  37.     'on_selection_modified': [],
    / K; ^2 K) k, Y* y' z
  38.     'on_activated': [],  S" P) v: ?2 ^/ E/ j/ B: ]
  39.     'on_deactivated': [],
    ' D) a1 n4 w' P1 ~& M6 I
  40.     'on_query_context': [],; ~9 ~1 ~2 T; H4 I+ _( `& ~1 n
  41.     'on_query_completions': [],: U- n. ^9 `+ a. y4 Q3 S
  42.     'on_hover': [],
    6 e& k6 D  J# t' w. }6 @# S
  43.     'on_text_command': [],4 [2 j0 u5 L# v( H; e0 t. k
  44.     'on_window_command': [],
    4 J2 O* Q6 w; e4 H+ S
  45.     'on_post_text_command': [],- d/ m; Z1 Y$ C% O5 q0 x
  46.     'on_post_window_command': [],
    $ h( A, X# X9 q9 }% p8 s. v7 ?
  47.     'on_modified_async': [],
    8 C' O; {: b& J5 B0 h
  48.     'on_selection_modified_async': [],! v& k1 M+ {- r  x8 w& m
  49.     'on_pre_save_async': [],1 v1 d: z" [# B: L  w# v) M
  50.     'on_post_save_async': [],; n% H$ V) r  c  P9 d
  51.     'on_activated_async': [],5 m* o) k) m( f8 z+ }
  52.     'on_deactivated_async': [],
    " Z# C9 _; B# w6 H
  53.     'on_new_async': [],
    ! b% P. f- v" u8 @  H
  54.     'on_load_async': [],
    , T/ A3 Y, G" @4 e* {5 W4 z8 `
  55.     'on_clone_async': []}' j) q: p% f& k8 _: ~

  56. 3 `% d' ?2 E8 s0 T
  57. pending_on_activated_async_lock = threading.Lock()
    + `3 }- l" S& T1 r/ M

  58. 9 `: r2 N/ z2 ?) j1 x: z
  59. pending_on_activated_async_callbacks = {1 k& O+ l! z- W' |8 o
  60.     'EventListener': [],4 h! f7 H- U. S) M' M* ^7 s  e1 R
  61.     'ViewEventListener': []}) P* T. f& U; \/ `- i5 v% O5 T

  62. 6 S7 G/ a( o+ U. e0 C) z5 Q. L
  63. profile = {}
    - C; r6 o5 s4 Q" d
  64. 9 ]) I) H3 }2 ]) ]7 Q1 _
  65. ( ?& R) ]# c0 c/ G
  66. def unload_module(module):4 [7 {+ l0 s/ }8 Z
  67.     if "plugin_unloaded" in module.__dict__:" @) y" r6 B1 {9 e# J* n* N% H4 u
  68.         module.plugin_unloaded()! z$ g9 D' g# M' W% r& J6 V3 }
  69.     # Check unload_handler too, for backwards compat2 L7 V+ [) }. B  [& T# Y) Z
  70.     if "unload_handler" in module.__dict__:
    ( g2 k% z) `4 e6 }1 B% R6 {
  71.         module.unload_handler()
    * E+ n( [4 y7 F, l- w' s

  72. , P' H9 M# Y" w
  73.     # Unload the old plugins3 I0 U( b: i( l$ I2 i; E
  74.     if "__plugins__" in module.__dict__:
    " s9 ^0 n: T/ e: x
  75.         for view_id, listener_instances in view_event_listeners.items():
    3 H9 T% A4 |) Y$ ]  K: C% V
  76.             for vel in listener_instances[:]:
    ) j. O- C. L' A6 t+ j* n7 u
  77.                 if vel.__class__ in module.__plugins__:
    . y, r! a  a& X$ e6 l: h& n4 \5 e* s
  78.                     listener_instances.remove(vel)
    ) D$ q" i7 Y( i2 d5 t

  79. + {! l: O; l! p  N# ]
  80.         for p in module.__plugins__:* P7 y3 k# y, Q9 h" g0 E  }# M# D
  81.             for cmd_cls_list in all_command_classes:
    1 L( W( B: q/ z6 X
  82.                 try:
    ! @0 o8 j6 u3 I! c/ E
  83.                     cmd_cls_list.remove(p), |! p7 T9 J2 D6 x$ i
  84.                 except ValueError:9 u4 l6 C% ~' u* G: u, r8 I1 M) K: W
  85.                     pass
    % Y/ p, `7 S. Q2 b% I9 V/ o3 P: ]
  86.             for c in all_callbacks.values():
    1 q4 u: p% W/ E: J- g7 T0 T8 R& S
  87.                 try:
    3 J7 ]3 R8 R+ d7 c0 _: P
  88.                     c.remove(p)1 x5 d# _5 P( {: i  |8 _% T$ T/ }
  89.                 except ValueError:
    % q7 r2 y7 R: Q- b) f. B
  90.                     pass
    ( u9 y& s7 C4 C, @# T6 ?
  91. * w& a2 B  [4 y5 I& a
  92.             try:
    - l6 g$ Q$ m  W+ [3 ~
  93.                 view_event_listener_classes.remove(p)
    ! Q+ d3 q3 d1 G0 ~* Q+ e  `( j$ y
  94.             except ValueError:
    * ^/ x1 I0 k0 Y9 q
  95.                 pass
    0 Z( n# C4 c* V3 B/ `' A7 Z
  96. : [! \# K/ R! B5 f

  97. 7 y6 F+ Z7 Q7 A3 J7 [5 K, D: J
  98. def unload_plugin(modulename):
    - [  i& J' b1 W; u8 y6 E/ _
  99.     print("unloading plugin", modulename)8 `# D6 d4 |! k' W* U
  100. # B) {/ S- W2 ]' \. ]
  101.     was_loaded = modulename in sys.modules
    $ m* P2 d6 j0 p& ?; P2 V) z. e* [
  102.     if was_loaded:2 `: G6 S) X5 ^1 h7 t0 H! l* D
  103.         m = sys.modules[modulename]) b# R7 n2 w# S1 _1 S! i" D
  104.         unload_module(m)2 g4 J9 h8 H! }3 z2 k
  105.         del sys.modules[modulename]
    6 _0 D, U% |- w* o% r

  106. 4 R& L. K  e& x5 `

  107. # s0 \: W" @" X7 i, n$ a
  108. def reload_plugin(modulename):1 t. K8 ?1 h! z, |$ @: C
  109.     print("reloading plugin", modulename)& K# y5 [/ m7 e7 b1 m) G5 R
  110. ; p6 U2 [7 M1 g! B
  111.     if modulename in sys.modules:
    ( A$ F# D6 M: m1 o3 j" O" |
  112.         m = sys.modules[modulename]
    ( D0 B2 l5 L8 |9 a; |% y* n
  113.         unload_module(m)2 \. G3 Q2 U0 w' u, Q4 i1 M
  114.         m = imp.reload(m)/ W  B- I( s$ ]) y$ c
  115.     else:& w2 {) |3 j  A- H& D9 x* T2 ^
  116.         m = importlib.import_module(modulename)  O. {' G  g; ~9 o0 f$ I0 c9 m

  117.   @6 L0 X. m* X& e8 m7 M' v7 a1 e
  118.     module_plugins = []& T0 V6 ]: z* {9 r, v
  119.     on_activated_targets = []! V2 S0 G) t/ C4 ]6 a3 z! l. f# L
  120.     vel_on_activated_classes = []8 y) I1 O  L9 D# w$ A% H1 M$ o
  121.     el_on_activated_async_targets = []& P3 y) k9 \1 M5 U4 N8 Z$ \
  122.     vel_on_activated_async_targets = []% G, E; L/ \6 C- ?
  123.     module_view_event_listener_classes = []
    # D" s$ g/ i+ E: `. A
  124.     for type_name in dir(m):, O' A0 ~% c5 I: w
  125.         try:; h% W( |* }& u$ V
  126.             t = m.__dict__[type_name]& g% p4 Q( u' N' w" g" S! s. b5 F
  127.             if t.__bases__:0 g# J* L/ c& f/ s3 M
  128.                 is_plugin = False
    5 y% d& g$ I5 ~/ f6 ^, q2 K
  129.                 if issubclass(t, ApplicationCommand):
    , v4 ]- N, C! D' e% F6 B, m
  130.                     application_command_classes.append(t)
    " [9 b7 t8 n' ], N  x0 K4 U
  131.                     is_plugin = True  P' x' a; a' d
  132.                 if issubclass(t, WindowCommand):3 Z. e( I6 V9 b
  133.                     window_command_classes.append(t)
    2 b. P5 {5 v3 K: f+ N+ ~1 D, |4 }
  134.                     is_plugin = True
    # m3 L0 Y7 \4 T3 p2 b( Z$ {* ~
  135.                 if issubclass(t, TextCommand):% F* C$ T% j- C) M# X
  136.                     text_command_classes.append(t)$ \" I1 [: ]& A9 f, I6 s
  137.                     is_plugin = True
    9 @- m7 X0 G+ N1 g1 S( E& J

  138. 1 M0 c2 W& r3 I) Z, ^& u
  139.                 if is_plugin:% C9 n; Q- Z! Q: i5 c
  140.                     module_plugins.append(t)
    ' I1 G& q8 H8 N! b3 b3 x
  141. 9 W, l0 W. H0 j9 [4 ~
  142.                 if issubclass(t, EventListener):. [3 m) \; s' K
  143.                     obj = t()
    3 b( K7 H/ z. d0 y) b' {
  144.                     for p in all_callbacks.items():
    % ^# M* @7 n, L, _
  145.                         if p[0] in dir(obj):8 F9 f* L3 _& L! s* q: `4 b) L
  146.                             p[1].append(obj)/ J2 e" [% ~$ t% O
  147. 1 D5 R1 V3 A' x, H0 d
  148.                     if "on_activated" in dir(obj):
    $ B# H; A3 {# h* m  x! x4 M( D& r
  149.                         on_activated_targets.append(obj)  o. ]/ s# z% E7 G& X! D  g
  150. ( T+ E4 W+ k/ v% y& T
  151.                     if "on_activated_async" in dir(obj):8 E7 l& _3 ~# Q0 R2 {
  152.                         el_on_activated_async_targets.append(obj)
    2 v9 d% s* {3 r( R/ s0 k9 ~+ E% P

  153. % L8 J5 a; }/ ^& E( @! K( i
  154.                     module_plugins.append(obj)$ F: _6 m% N2 p$ h

  155. ) P5 K% s6 U  E$ ?! j7 d( X
  156.                 if issubclass(t, ViewEventListener):
    & `* X0 Z# N1 t- b
  157.                     view_event_listener_classes.append(t)
    0 g* J! X  k, q4 A, s
  158.                     module_view_event_listener_classes.append(t)
    , M" t. j! W$ g" U: o0 `+ W
  159.                     if "on_activated" in dir(t):2 A! j6 w; u: L1 B6 l
  160.                         vel_on_activated_classes.append(t)9 w3 s1 X: a' O2 ~1 E9 D6 p
  161.                     if "on_activated_async" in dir(t):
    6 H/ M  m5 x3 n& Y8 ?5 w! |
  162.                         vel_on_activated_async_targets.append(t)' C) o! R: }# u; d: u+ v8 A, @
  163.                     module_plugins.append(t)
    ; `. H. b+ x0 G! `
  164. : I" ?% N: v- {
  165.         except AttributeError:( P+ V( _) l- ^9 F
  166.             pass$ D; S' R* B) ?1 @
  167. " `. k+ j4 w0 e- }, ]& K1 J* e
  168.     if el_on_activated_async_targets or vel_on_activated_async_targets:
    ; L& `) ^# l$ y
  169.         with pending_on_activated_async_lock:
    3 C# J5 Q+ i. K4 E6 X
  170.             pending_on_activated_async_callbacks['EventListener'].extend(
    ! O1 `3 Q! x3 A. [3 X4 o5 D+ r
  171.                 el_on_activated_async_targets3 E; h) N. U# M5 n
  172.             )2 D8 S( x! B4 N3 a2 G
  173.             pending_on_activated_async_callbacks['ViewEventListener'].extend(
    ; [* b/ E) t4 L
  174.                 vel_on_activated_async_targets
    3 {- u4 {& ?; [3 y& S, V8 \+ h
  175.             )6 s2 R9 _8 v2 m2 w
  176. ! X. V4 J( Q- A/ x: D
  177.     if len(module_plugins) > 0:0 `" a) F/ g( ]0 I$ M
  178.         m.__plugins__ = module_plugins8 k2 V7 N: s& ]5 H- G: N3 t* Z

  179.   ^3 N* S! W/ J' T/ z& l
  180.     if api_ready:
    7 Y- Y/ K3 |  I. ?4 q6 a+ a
  181.         if "plugin_loaded" in m.__dict__:
    1 M6 X7 F! V5 T2 ]% A$ d
  182.             try:& }  m( j1 U2 H, M  P. {
  183.                 m.plugin_loaded()
    , {8 a" L; z( {  Z7 v
  184.             except:
    - Z# u7 J" d( Y/ _2 W) F7 e$ H
  185.                 traceback.print_exc()
    4 L( O! i9 `" Q5 F
  186. * ^- c- J; a0 R5 G1 z* |
  187.         # Create any require ViewEventListener objects1 h: z% g* n' G: p5 D  s
  188.         if len(module_view_event_listener_classes) > 0:% J2 H) R  G1 v/ b' ^
  189.             for w in sublime.windows():
      B8 o' n4 g2 Q; C5 a* y  ]6 Q
  190.                 for v in w.views():
    2 ?3 C8 z; A0 a2 `
  191.                     create_view_event_listeners(4 Z9 B8 M/ \% D+ J# F8 M8 n9 a
  192.                         module_view_event_listener_classes, v); Q5 K! G1 y  B1 W! V8 ^

  193. - ?2 x% l9 X' i
  194.         # Synthesize any required on_activated calls
    8 Z; G) n. D5 N* {# {8 R! P
  195.         w = sublime.active_window()
    1 W7 _" h7 [: a# W9 b
  196.         if w:
    2 D, }  ]. J/ d9 r( [% c
  197.             v = w.active_view()
    ; E5 C: G2 Z) K) J5 Q" m
  198.             if v:
    . m7 z6 r/ p; R( F
  199.                 for el in on_activated_targets:
    2 i2 X, V9 M5 S  b7 c0 b) o* I1 j: `
  200.                     try:
      p; L, V1 I* O# p  }/ e6 t2 J
  201.                         el.on_activated(v)
    + M/ j8 M: J1 D) P6 O; ~4 c$ H5 n
  202.                     except:
    7 A1 h/ Q: ^7 C: u
  203.                         traceback.print_exc()2 H  C0 A0 B, ^# b  X

  204. 5 ]+ R0 J- E; k5 h
  205.                 for vel_cls in vel_on_activated_classes:
    5 _. Z: C" U+ j! U; a# R
  206.                     vel = find_view_event_listener(v, vel_cls)
    / }% y$ y' H4 R9 s! O
  207.                     if not vel:6 ~0 k  |% l  `# Q+ v: L. V+ s/ _# u
  208.                         continue8 C7 z' n5 I% Q+ m4 c
  209.                     try:: n3 V; L; B! k
  210.                         vel.on_activated()3 \# V( t2 R! |* M
  211.                     except:& D0 Y( ]! Q1 o
  212.                         traceback.print_exc()
    2 v' N- I) a" G
  213. ! m8 {& |" u" \0 l- S- ]( J% T
  214. 9 J- S) i; G! I5 X6 S" d  u- Z% V/ i1 t% n
  215. def synthesize_on_activated_async():" n0 ^/ s& h. H9 c) R/ Y
  216.     if not api_ready:: G" q6 ^/ J( s
  217.         return! o- z7 b  ?0 i# F, J

  218. 4 s7 t* `) `/ J1 D( O
  219.     with pending_on_activated_async_lock:
      {3 _: [6 [5 }1 c" D) {" s* _
  220.         els = pending_on_activated_async_callbacks['EventListener']! H( U( _; }1 V3 X" ~/ e0 c+ C
  221.         vels = pending_on_activated_async_callbacks['ViewEventListener']' v( S: n- t; T+ n2 U  }" ?
  222.         pending_on_activated_async_callbacks['EventListener'] = []& @4 K6 z) S, R/ z9 ~/ h4 ?
  223.         pending_on_activated_async_callbacks['ViewEventListener'] = []
    & F7 r1 V8 t% f4 U
  224. # ~( H8 V$ ^0 \  f+ H8 l! d
  225.     for el in els:. w9 Q+ X! N  l/ R; B
  226.         w = sublime.active_window()
    ( D" I, J+ I* X, W* ~2 h8 d) v0 E
  227.         if not w:& F3 i. I, K* {
  228.             continue
    - U9 y! g$ N) s" i/ M* w6 p5 [
  229.         v = w.active_view()
    , ]* s/ ]/ U) N5 y
  230.         if not v:! N  k' d. S) g. |
  231.             continue
    + E1 c8 j, z4 o: O+ a  r3 ?
  232.         try:4 Y- v+ o$ R) W( `
  233.             el.on_activated_async(v)
    ( U, E+ d2 w/ h4 M
  234.         except:! b8 u5 I/ v6 S, F  B0 L" L6 g
  235.             traceback.print_exc()' `1 |: Z$ J7 e
  236.   Y$ m5 d* o' _) ~9 y
  237.     for vel_cls in vels:4 o, G6 F5 `( S7 {5 O" \7 ?
  238.         w = sublime.active_window()' n* |1 {3 n3 d- E( `% g
  239.         if not w:# b3 q9 J1 e2 b% ^1 k3 D
  240.             continue+ D& Q! g, ^4 B; S' o, w) V  }
  241.         v = w.active_view()
      r/ Y- C6 z! D; N8 h& u
  242.         if not v:
    : L( M* c0 h: ~) D7 ?
  243.             continue$ A% l2 D0 z, G; X. A' z! `2 N
  244.         vel = find_view_event_listener(v, vel_cls)
    5 \, ~$ H# Z$ P4 o" ]3 g. e) \
  245.         if not vel:
    ' l' g$ \8 I5 D2 z$ \
  246.             continue( b5 ?. N9 U/ O; q
  247.         try:
    9 H6 f+ u. H2 }: c) T
  248.             vel.on_activated_async()
    9 i  y7 m5 S4 y' [) u% A9 h
  249.         except:
    ) ]& E6 j# R! J" A% F5 g7 h
  250.             traceback.print_exc()* K) J+ \; W( E3 _' Y5 U' n

  251. ' k$ j) @. r8 ]1 z0 V

  252. - U3 \) q) J! r0 k' k5 z6 o  o
  253. def create_application_commands():' m" l$ ?6 f5 N! U& a
  254.     cmds = []
    3 h: \2 F1 e  T9 D/ t! X
  255.     for class_ in application_command_classes:
    / T: D/ e% v' w; o1 k, I, g
  256.         cmds.append(class_())
    , V# k; f  F! K: ?6 a+ Y! q: @
  257.     sublime_api.notify_application_commands(cmds)# P9 }" H# F' h' U# X

  258. 4 `, i2 W0 G2 t3 D5 ?

  259. 9 z4 ]0 B, G( v
  260. def create_window_commands(window_id):
    ; `$ C3 S2 M; b' Q/ V
  261.     window = sublime.Window(window_id)- c4 o! |; T$ N, E/ I, o
  262.     cmds = []) `. g/ j3 W  g
  263.     for class_ in window_command_classes:
    ' d0 @& o9 I$ c) h+ m
  264.         cmds.append(class_(window))" ?2 {2 ]( f% F9 m% M! b9 k
  265.     return cmds- U; x4 y: E1 e1 O' m

  266. 0 h/ g( \6 Y! }# M. ~$ @  q. B  z
  267. 6 f0 O$ P3 V& c1 H" G% T0 ^) ~3 W
  268. def create_text_commands(view_id):
    ' g" f- q1 Z! ]) C
  269.     view = sublime.View(view_id)! Y- R7 @. J8 b8 I
  270.     cmds = []. n# c# T; n3 _) O* R  L, v
  271.     for class_ in text_command_classes:, K- `$ \! {' B! H! ^: _: d* l
  272.         cmds.append(class_(view))3 I2 m4 O# c$ o* b" y4 i8 V
  273.     return cmds
    . d6 a) G3 d. C' W$ z* c( o3 Z
  274. % K1 O5 ?* ?% x2 b

  275. + q$ |& N. C; s' g) [
  276. def on_api_ready():
    % l+ {6 Y- w3 R2 t; o1 z% e- b- ]
  277.     global api_ready
    8 P" a' I  X' ^" Y5 d* b) z8 H
  278.     api_ready = True
    ) c6 O0 E: _6 o6 p& w2 e+ t. |

  279. 1 k4 a, F; j: p: }) V
  280.     for m in list(sys.modules.values()):+ ~8 R, e  Y. ^
  281.         if "plugin_loaded" in m.__dict__:
    # I/ T- R) p' a" }8 |$ q
  282.             try:
    " H" i9 Y' G  J) `% X# f9 ^( `! D
  283.                 m.plugin_loaded(): j$ u$ `; q1 r  r9 w
  284.             except:5 n' F0 f2 j, T% i' i6 _  U
  285.                 traceback.print_exc()4 B5 Y6 v6 T! s8 E( A% q, r
  286. " W! }% ]: \& h, e6 C' I
  287.     # Create ViewEventListener instances$ i" D" g) d$ c' F- @# w% p
  288.     if len(view_event_listener_classes) > 0:
    9 `4 b* v$ z7 h2 U
  289.         for w in sublime.windows():3 E0 K* x7 ~/ R) H
  290.             for v in w.views():
    $ B! T! @+ X- ]7 U* K# h" e, i: w
  291.                 attach_view(v)
    5 c6 B$ V2 |+ \  y
  292. 1 n0 H9 k5 v* u$ k3 u
  293.     # Synthesize an on_activated call( V9 \' V9 d) }
  294.     w = sublime.active_window()* `- |& W% h; p' ~
  295.     if w:7 ~8 S9 a0 `6 o: r! {1 L0 @, R
  296.         view_id = sublime_api.window_active_view(w.window_id)% p6 A7 H3 @7 V0 @' L0 K& A
  297.         if view_id != 0:7 D4 H% O. z/ ~
  298.             try:
    " _  b- w: d- w1 S6 s; n( G
  299.                 on_activated(view_id)! h4 \7 V4 A  [2 B# |! Z) q, _
  300.             except:9 K  I( @3 R, p6 G$ W' M
  301.                 traceback.print_exc()
    ! Q+ v) w' {: h. |1 ~
  302. 0 B  c7 k. A% n$ l) W) x
  303. 5 N0 L* E0 k- ^$ `5 m
  304. def is_view_event_listener_applicable(cls, view):$ d5 x" c, S4 z/ N' s2 x$ Q  _
  305.     if not cls.is_applicable(view.settings()):5 U5 @( d( ]: ~3 X
  306.         return False
    / A! X; e3 f3 K' C# G

  307. ' F8 Q4 {, p3 h4 }5 A% V1 S
  308.     if cls.applies_to_primary_view_only() and not view.is_primary():' F2 r, U. e- U$ _) J6 W+ c
  309.         return False' F# M# E1 i; {5 \  L1 p" @. ^

  310. 7 Z/ J; ?. N3 ]5 a. N5 Y
  311.     return True
    ( o: l+ n* W' f1 q) s! F
  312. 9 H3 q9 S, S# O4 q; T
  313. ' Q( G  F$ z* S  k' T% {  _3 |9 \
  314. def create_view_event_listeners(classes, view):; L, `3 r! J" h" Q# x# {  p( s
  315.     if len(classes) > 0:
    8 d) o3 x/ k1 c
  316.         if view.view_id not in view_event_listeners:' W. ^8 ?& C# S; b
  317.             view_event_listeners[view.view_id] = []
    * g: G4 F  t' R$ t
  318. " |+ P3 S5 s" P  z' D- `" {
  319.         for c in classes:
    ; U# O+ C1 X* Z
  320.             if is_view_event_listener_applicable(c, view):
    ( `7 H/ A( z, [& W% U0 j3 r
  321.                 view_event_listeners[view.view_id].append(c(view))
    & [) q8 @' e) N* ~
  322. % ^& j' d+ j- Y0 F
  323. + Y8 s* Q% q' p1 `0 v2 w: T
  324. def check_view_event_listeners(view):4 r( p8 w' }$ \. }* v  i9 w
  325.     if len(view_event_listener_classes) > 0:3 a( J" l7 {+ c9 e5 S+ s- f
  326.         if view.view_id not in view_event_listeners:
    ! w/ F1 Q1 j0 j1 I% \  ]
  327.             view_event_listeners[view.view_id] = []
    9 u1 N4 h1 _7 t8 d4 S. `

  328. ) {6 R* U% D/ u. N  n* j& a
  329.         listeners = view_event_listeners[view.view_id], x% w* k  q' |! f

  330.   C4 w. R6 _  e% O7 J
  331.         for cls in view_event_listener_classes:
      U# ]% x* ]* p1 X( E
  332.             found = False
    * J" O( `  C) D4 F- W
  333.             instance = None
    , f, n( X  }) R7 i7 b# x* g
  334.             for l in listeners:
    9 T- e3 T& e9 ]2 N0 n# z
  335.                 if l.__class__ == cls:$ K# t' e" D6 C4 {: J9 A
  336.                     found = True
    * X3 A9 C! N, [/ F+ b
  337.                     instance = l
    + F; Q8 ]# m4 F; u: M5 [" F
  338.                     break8 z# I5 q8 h0 ^/ m/ E

  339. $ M& E" A3 b5 K% r" z+ s( ^
  340.             want = is_view_event_listener_applicable(cls, view)+ r7 X3 f' H" }) ~! c3 T
  341. 4 C* K. L, q  [5 s/ Y& m
  342.             if want and not found:9 y- Q4 A: C6 y0 L8 S4 U; R, U
  343.                 listeners.append(cls(view))# ^- r4 Y; P8 ~! A- _5 c
  344.             elif found and not want:
    4 K( k4 h& e! S1 ~9 b1 w) C4 k
  345.                 listeners.remove(instance)% O$ _- S+ D# b0 }
  346. 9 M: d* f% p- F. H0 }$ ]' o0 Q# {

  347. * w+ N- n; c2 X5 A1 p0 q( Y
  348. def attach_view(view):' Z/ C) s3 \0 O6 c/ B# f' L( T
  349.     check_view_event_listeners(view)
    3 [, W/ W) p$ \% j

  350. + Q& k" m" D8 \  C' C
  351.     view.settings().add_on_change(
    $ w5 h0 k) Z0 C9 v
  352.         "check_view_event_listeners",
    + S5 K, }% K" P9 [# Q
  353.         lambda: check_view_event_listeners(view)), M: X) Q/ `# I; o2 `! X
  354. 4 y9 A5 S. H" K2 B0 @/ o3 l0 w# l
  355. 3 K$ |6 p9 K* u$ n9 P
  356. check_all_view_event_listeners_scheduled = False
    7 T1 T" `. L$ C, Z, l, z9 A

  357. / I5 p/ G  H* R7 e  y

  358. % }6 t+ ]7 X3 ~: X: ?2 j( m! H6 H
  359. def check_all_view_event_listeners():, Z7 L0 w, Y: t8 d5 }1 a/ v9 s
  360.     global check_all_view_event_listeners_scheduled
    3 x) u. E5 E1 I  u+ j
  361.     check_all_view_event_listeners_scheduled = False( i0 |9 c% Z! @# j( {% q& Q: P- U
  362.     for w in sublime.windows():2 P1 j" t/ J9 H$ M
  363.         for v in w.views():
    5 U" f- I$ t/ S* K3 k; {
  364.             check_view_event_listeners(v)
    # |) t$ O' T) d( k
  365. / T  ?4 c) N: g5 W" l

  366. ' P1 j# w' f; \4 C8 u
  367. def detach_view(view):* Q! H1 W' i  Z2 k. m3 t
  368.     if view.view_id in view_event_listeners:6 M: H. n3 P# j( m. R
  369.         del view_event_listeners[view.view_id]! j0 M1 b# f' o  \8 v
  370. % F+ v. S4 W" P" [: H7 I3 o
  371.     # A view has closed, which implies 'is_primary' may have changed, so see if
    $ t4 M1 C- C& a# U) M
  372.     # any of the ViewEventListener classes need to be created.
    1 M9 ~8 ]5 H) X" d. Y# l& c9 N+ W
  373.     # Call this in a timeout, as 'view' will still be reporting itself as a
    " a* O5 U% ]' C7 F
  374.     # primary at this stage
    , ^7 E2 k7 ?2 u3 a- J
  375.     global check_all_view_event_listeners_scheduled
    % x# a& g4 p+ q, p! T9 L+ M$ C
  376.     if not check_all_view_event_listeners_scheduled:
    8 K% w# _7 k- ~8 C
  377.         check_all_view_event_listeners_scheduled = True$ ?- k. j) }; V% P, U
  378.         sublime.set_timeout(check_all_view_event_listeners)0 U3 v. X' X1 C& a6 j
  379. : v" O4 U- s8 R' ?; J
  380. ' [$ d' `# R/ v7 N
  381. def event_listeners_for_view(view):1 U4 U6 `: A4 Q" |$ M. w) S8 ^
  382.     if view.view_id in view_event_listeners:
      z+ g8 t, X9 p7 z8 j
  383.         return view_event_listeners[view.view_id]
    " h& P! [9 l6 U. c" l
  384.     else:
    % c5 I+ g; U; N% y( u. x' ?! X" Q
  385.         return []  N+ R$ M7 p6 f7 V+ F
  386. 0 s4 S6 m" N/ A7 ~0 l: z

  387. % [9 p6 k; P+ _$ \2 J  @2 \# I
  388. def find_view_event_listener(view, cls):
    / E9 n$ t3 {" E* ]
  389.     if view.view_id in view_event_listeners:; j, ?8 X7 _- M& c+ M( y- |8 X
  390.         for vel in view_event_listeners[view.view_id]:2 z$ j1 ?, t: U* T2 i
  391.             if vel.__class__ == cls:) N9 ^1 X& ^3 ?2 Y# E: P. P+ u, t3 B9 Z# y
  392.                 return vel
    4 I, j7 I: l) y& O
  393.     return None
    & e2 o$ ?  j# m3 \* o8 E
  394. ; X- r$ ^! O" ?6 C
  395. 8 D$ U) G% e1 q) t6 F9 R9 U0 p, e
  396. def on_new(view_id):2 y% ]- d  \' L9 @$ O8 u9 B
  397.     v = sublime.View(view_id); O7 H1 r  `9 k+ D) T

  398. , i3 x( j0 D, ~7 ~3 ]; `
  399.     attach_view(v)
    6 @6 \3 \4 D6 R9 f8 P1 ~2 X

  400. + \" e# l, A7 l* W
  401.     for callback in all_callbacks['on_new']:+ ]$ @' V# j* S+ L
  402.         try:& t9 q( Q1 T9 o& F4 Q) p8 L8 ~
  403.             callback.on_new(v)
    . G" X3 v2 _$ d" J6 Y! O: ?5 N
  404.         except:
    / G( @) m1 w0 q# F5 ?! D( ~
  405.             traceback.print_exc()5 z* P; g3 b4 B& u+ q" A
  406. 0 |- R* N1 ^, [1 f1 i9 ~

  407. " q; \5 p1 U$ ?8 H
  408. def on_new_async(view_id):* [! h  h- |) x! U4 h( s( h
  409.     v = sublime.View(view_id)
    , B$ Q: ]. U8 z7 o, F
  410.     for callback in all_callbacks['on_new_async']:% a' K4 F8 A7 k5 t0 ^+ F
  411.         try:4 X) O) Y0 m% m0 N9 N
  412.             callback.on_new_async(v)9 V: {1 Y. U3 {- l2 E" x
  413.         except:
    6 q5 b( ^3 H7 o4 d% T* _
  414.             traceback.print_exc()
    % a9 m5 w" _1 A* J
  415. ' G2 i0 Y  S3 F( a! ?: C

  416. " l  A/ l; Y$ `/ g1 z
  417. def on_clone(view_id):2 y* F/ n" |1 @' [) h  S7 s
  418.     v = sublime.View(view_id)- W7 \6 R* s( q0 w8 `- E' L

  419. ! K5 F$ C! C7 ^0 n& t' m* @
  420.     attach_view(v). e2 R3 M- h# A5 Z: {! E
  421. ' x9 p# N+ O% N$ B( ?  d
  422.     for callback in all_callbacks['on_clone']:4 t$ R$ q/ w& S5 y- I1 V- T$ e
  423.         try:
    5 o* K9 R' ^7 h8 J8 f
  424.             callback.on_clone(v)% b- ~" i5 X5 P- U
  425.         except:
    6 l, U# B+ b4 y+ A  H2 u! P
  426.             traceback.print_exc()6 |! y' {% r, m  g- h0 n* u2 I
  427.   Z8 v6 z2 o1 A+ n' g

  428. ) I- Z5 ^% Y7 P! ]# j0 p
  429. def on_clone_async(view_id):
    7 D2 C; z8 h- b  u9 d: z
  430.     v = sublime.View(view_id)
      b- u+ d: T6 |+ Z# j% ~: B! k# D
  431.     for callback in all_callbacks['on_clone_async']:
    ! `: l7 X6 @! \  ^. U# G
  432.         try:
    3 q) L: _+ K7 x5 }
  433.             callback.on_clone_async(v)
      ^( N; r7 Y. ^& P! x8 v3 j
  434.         except:8 X4 h- x/ I9 V+ e' n
  435.             traceback.print_exc()0 E7 j1 w! M  y0 I# W

  436. 9 ?5 t2 H* f# T$ |2 y7 \  w" p

  437. , D- }+ E4 M* U/ R) N$ ]- L
  438. class Summary(object):$ t+ y& n7 z9 q3 N, X3 t
  439.     def __init__(self):
    6 T6 I+ h2 b/ O/ v
  440.         self.max = 0.0
    ! }- a3 M! H8 k0 g. u- R
  441.         self.sum = 0.0
    ( M; G. ?* Q, S7 W8 y
  442.         self.count = 05 q4 B: B* q, H/ i/ K& k# D6 y
  443. ; P& J3 j' V  V% T
  444.     def record(self, x):
    4 a" F2 Z% w8 v; L
  445.         self.count += 16 x8 O% S4 C+ s$ k% s- _
  446.         self.sum += x
      C* q+ r/ s  i% N6 y
  447.         self.max = max(self.max, x)" W0 G6 f% T2 [( b# }, Q7 d
  448. $ H0 `9 g. s& [2 s: s+ W) [
  449.     def __str__(self):5 [6 d% R- r  H9 C3 K: f  ^0 Q# P
  450.         if self.count > 1:
    4 c9 m; b  U  H9 i
  451.             return "{0:.3f}s total, mean: {1:.3f}s, max: {2:.3f}s".format(self.sum, self.sum / self.count, self.max)/ E$ U. ]/ X) |2 J
  452.         elif self.count == 1:- m  U7 p: `& @: C6 M9 R& ~
  453.             return "{0:.3f}s total".format(self.sum)9 _5 t% X7 z0 m* W' e
  454.         else:
    , J, X/ L1 c8 z* ]1 e
  455.             return "0s total"0 W. m; n% r+ {
  456. 3 ~" E* X  h: @! f

  457. 4 d! p* e9 y! n/ e* K, s& R" O  z
  458. def run_callback(event, callback, expr):# H4 e# {2 y' ~% v. [3 N' e6 ]
  459.     t0 = time.time(): U5 @! a- T2 u+ p# S  b
  460. 3 U& ~: O' [2 y  f9 M
  461.     try:) o* Y/ K8 O; j4 b* |. y$ `$ v& _" W
  462.         expr()8 V) Q9 v7 H7 r1 E
  463.     except:
    . A6 @% O2 g4 f. b! ^# t
  464.         traceback.print_exc()* R, Z$ x' }& |* X" y; m, [0 i
  465. 1 A8 u6 @6 L4 d1 J  C) s, N& V6 g
  466.     elapsed = time.time() - t00 Y! ^& F. Y% o9 h; D

  467. : c- m9 l: I* o. u  k
  468.     if event not in profile:
    - W9 \) W2 ?$ [
  469.         profile[event] = {}
    ; Y, a4 `9 _0 ]

  470. ( c( B0 b9 X! z2 s! Y- E' h, A
  471.     p = profile[event]( s9 h+ @+ w  e" Q4 d# n

  472. 1 o% H8 `+ A( L6 ]6 U; D, ]
  473.     name = callback.__module__( g1 c" Q9 j! i  C
  474.     if name not in p:+ M- c5 g" f6 ?9 ]
  475.         p[name] = Summary()- d: Q* b. @4 Q7 Q3 {9 I% `
  476. 1 m6 X6 U3 v0 `
  477.     p[name].record(elapsed)
    # R3 R5 T* V- H8 ^" j7 s8 r
  478. 7 I( \0 T& L1 I( T' p

  479. 3 h) H3 O& w" _9 ^- f
  480. def run_view_listener_callback(view, name):
    $ p$ u/ ]% z/ W# _2 {6 d6 }7 z
  481.     for vel in event_listeners_for_view(view):
    : O) I& Z$ t2 Y: h$ y
  482.         if name in vel.__class__.__dict__:. J0 |. I; b  W2 `+ M" K
  483.             run_callback(name, vel, lambda: vel.__class__.__dict__[name](vel))8 k( K& v: `0 I! n1 r
  484. 0 t1 R1 n% B/ P8 ]
  485. 6 r7 M5 C; P! x& o# m  j5 @! i
  486. def run_async_view_listener_callback(view, name):/ i! y7 I5 S  Y: i/ H) I, p8 |
  487.     for vel in event_listeners_for_view(view):, x& I  c# J. S! b3 N
  488.         if name in vel.__class__.__dict__:
    0 e- `0 v- g3 S# c5 M& S) g
  489.             try:
    0 h% F6 r' M6 H6 \
  490.                 vel.__class__.__dict__[name](vel)4 O$ r2 r' `* v+ h
  491.             except:
    9 ~" a5 ?( L  Y  N0 F: z) a( c  B) ^
  492.                 traceback.print_exc()1 a5 R% ~8 X$ O# @4 e2 j$ i
  493. 3 W8 A6 n* {! t# z9 X+ F
  494. 6 U3 f4 r) d3 A
  495. def on_load(view_id):
    7 b8 U: s8 N& y* Z; L
  496.     v = sublime.View(view_id)5 X3 H8 e3 F+ Z: a  T* W6 I4 i
  497. 0 X8 a3 K& L. i% o- ?! ?( h
  498.     attach_view(v)" D1 c  X3 a) X$ n
  499. " D& i1 {$ }* J9 k4 n+ k3 O  H
  500.     for callback in all_callbacks['on_load']:
    8 e( w6 s$ a& T' c
  501.         run_callback('on_load', callback, lambda: callback.on_load(v))
    8 l# n% N+ X  ~+ n0 F8 B+ t
  502.     run_view_listener_callback(v, 'on_load'): L* l/ x4 R! o

  503. 8 e+ C% L! s! S1 g- c

  504. + ?" R( z6 j; E: @5 X
  505. def on_load_async(view_id):
    . [" l+ G; Q$ l9 t! V
  506.     v = sublime.View(view_id)# N$ X; Y( A+ z5 o0 S3 ^
  507.     for callback in all_callbacks['on_load_async']:
    ' I- ?" w: H! O2 c! z& R
  508.         try:
    5 k( h+ V7 @" b+ V  N
  509.             callback.on_load_async(v)/ H  L+ i+ Y# J! h; x
  510.         except:
    ( n9 Z/ o$ H( T. C# Y- b, O
  511.             traceback.print_exc()
    ' _1 ?* Q, g4 F
  512.     run_async_view_listener_callback(v, 'on_load_async'). h5 t% n9 t) u0 k
  513. . ]* L9 `1 i  w7 j9 r0 l
  514. / O4 ?8 f6 `. q6 f! Q! `
  515. def on_pre_close(view_id):
    2 F8 P& L. T' |! R
  516.     v = sublime.View(view_id)
      i/ k. g# Y# g$ n( N
  517.     for callback in all_callbacks['on_pre_close']:( l) h. @6 ]4 ]
  518.         run_callback('on_pre_close', callback, lambda: callback.on_pre_close(v))( S- d# A+ R  ]- J. \2 H' V7 m
  519.     run_view_listener_callback(v, 'on_pre_close'), {: \8 `& R" t: G( ]; F( J

  520. + \5 C$ b7 F, D9 T! a

  521. , j, M3 d2 M  N. q# X
  522. def on_close(view_id):
    8 J2 `2 }; x0 I: b) M: V
  523.     v = sublime.View(view_id)
    1 h  d5 `& l( Y  ~0 N

  524. ; C: m" d5 A- z5 _# j4 l
  525.     run_view_listener_callback(v, 'on_close')" l( b5 v2 Y$ Z  ^: }$ d
  526.     detach_view(v)
    0 }2 c( Q1 v/ B3 ^# K: X
  527. # V- G) k4 c! x; ?0 O, D
  528.     for callback in all_callbacks['on_close']:
    5 K: C7 ?# l4 d( `( k8 p
  529.         run_callback('on_close', callback, lambda: callback.on_close(v))9 X2 H( R* J& c8 ~

  530. ! @1 @8 s" G+ g8 j: R# y

  531. ( e0 j' S( T$ W7 t  L4 u
  532. def on_pre_save(view_id):+ J, b  \# |: T. k
  533.     v = sublime.View(view_id)
    & h3 h8 K( }" `, g+ [( f0 c& }
  534.     for callback in all_callbacks['on_pre_save']:( N4 V& R  l: p) t# w( e3 n
  535.         run_callback('on_pre_save', callback, lambda: callback.on_pre_save(v))
    5 w( S& S9 b4 f
  536.     run_view_listener_callback(v, 'on_pre_save')
      J7 c5 d, G& t8 L

  537. . `, H* d( w0 J
  538. , b  a7 N) o8 J' V
  539. def on_pre_save_async(view_id):
    ( C$ t# @% M' V% P
  540.     v = sublime.View(view_id)
    / h) u4 }2 [! U' X6 k4 w; u; b
  541.     for callback in all_callbacks['on_pre_save_async']:2 Z8 y  q- S7 M& j4 T
  542.         try:
    5 L# L+ J6 Y5 c. l% \5 E& y
  543.             callback.on_pre_save_async(v)7 h- H$ x% [: F6 g( @& h
  544.         except:
    0 P4 T  l6 w  t) Q1 H5 ]( m8 ?5 u
  545.             traceback.print_exc()
    8 P: {) K1 A. x: l7 r& a6 U
  546.     run_async_view_listener_callback(v, 'on_pre_save_async')
    - A& o3 J# J' N( f' a+ w& p

  547. $ B1 {! i3 n: f' ^

  548. 5 Z1 }0 {3 t+ \# s2 S$ @2 K0 n8 |, a
  549. def on_post_save(view_id):0 b8 q2 ^# L- w, i$ j
  550.     v = sublime.View(view_id)
    7 L, z/ [. m& M
  551.     for callback in all_callbacks['on_post_save']:
    4 ?* j. a: p1 T8 ]/ S
  552.         run_callback('on_post_save', callback, lambda: callback.on_post_save(v))! l- M' w9 u: V) J3 j+ b3 u
  553.     run_view_listener_callback(v, 'on_post_save')
    ! Z% }6 X0 Y# o, p" k

  554. 2 {6 @0 q; B  J- N8 i, ~, s4 T
  555. 8 [* K* t- S! p1 c& m- Y
  556. def on_post_save_async(view_id):
    8 r7 _3 O- A. i* w
  557.     v = sublime.View(view_id)9 I, K" e) y8 ^6 U2 W
  558.     for callback in all_callbacks['on_post_save_async']:5 J( ?3 @4 P& J8 O# f1 l! m5 H
  559.         try:" C4 o! G! z: h0 c
  560.             callback.on_post_save_async(v)
    9 Z0 g- Q. e" v% u
  561.         except:# j% I# {( |7 d' I3 S" J5 C1 e! {& O! W
  562.             traceback.print_exc()% B5 a9 {, f# V  S  N" u' Y
  563.     run_async_view_listener_callback(v, 'on_post_save_async')1 {% T$ X9 R1 f/ w4 W7 U+ n
  564. - [7 y; r9 V* p, |; [' y5 C

  565. ! H. Y/ B7 R: |* X& |5 A
  566. def on_modified(view_id):2 t1 h; g5 C, a0 F0 Q$ q2 C
  567.     v = sublime.View(view_id)
    * y0 u4 z. |. V8 I3 V' `& w; D4 w' Q
  568.     for callback in all_callbacks['on_modified']:3 K$ N9 {6 t# W' c; {
  569.         run_callback('on_modified', callback, lambda: callback.on_modified(v))( }! N3 R( T) n- w
  570.     run_view_listener_callback(v, 'on_modified')+ k7 |4 j: M: O1 w

  571. ! O  M* Q8 N- o+ ^
  572.   Z1 J' V8 G3 _5 X: \, g
  573. def on_modified_async(view_id):
    7 K3 J) B! R, m6 q: [" {
  574.     v = sublime.View(view_id)
    - @" ?% {  k3 i' k, l% u. U' w) C
  575.     for callback in all_callbacks['on_modified_async']:
    ' R- f  W2 _8 Q
  576.         try:
    6 |+ t( L' \$ _3 ~
  577.             callback.on_modified_async(v)
    & O# B0 [, D# G1 M
  578.         except:3 m+ {1 v; ~- ^' f
  579.             traceback.print_exc()
    7 L6 ~: L8 ~1 O; n+ W. T8 ^% h
  580.     run_async_view_listener_callback(v, 'on_modified_async'), P1 q0 U& T% H
  581. ' ^& O- @: H- h, g2 |8 |
  582. " S( \" W' w8 p" ]% l
  583. def on_selection_modified(view_id):
    , O/ Z  [+ p# \5 E. t" J$ i7 U
  584.     v = sublime.View(view_id)  T5 }' t- c/ v
  585.     for callback in all_callbacks['on_selection_modified']:. G" ^4 I+ F8 |7 U: U6 A8 @  p. n
  586.         run_callback('on_selection_modified', callback, lambda: callback.on_selection_modified(v))3 c- |. W* V, u& W! b
  587.     run_view_listener_callback(v, 'on_selection_modified')
    % ?" e- e8 x9 p
  588. 8 T- [. G8 S# f- S  K) c- z

  589. : w: A; K6 n5 q- }, Y" B0 E
  590. def on_selection_modified_async(view_id):8 w- J  S4 A, y$ ^, K
  591.     v = sublime.View(view_id)
    % k3 r- O/ i1 p# [5 _/ ~
  592.     for callback in all_callbacks['on_selection_modified_async']:
    4 E7 a! ]$ y( i5 |6 l1 D
  593.         try:
    5 `6 L4 J& a  A, T
  594.             callback.on_selection_modified_async(v)
    8 }# w" F% m/ F9 d, i0 a! N8 s
  595.         except:
    - t; K0 H" L9 I. c7 H* ?) t7 J9 B) m
  596.             traceback.print_exc()
    / \% `. B0 U) K4 v6 l$ s
  597.     run_async_view_listener_callback(v, 'on_selection_modified_async')1 d6 N- u7 S% ]2 W; c, U

  598. & G) j' J. Z# k# H3 t
  599. / |8 [5 u$ G3 D# {# {
  600. def on_activated(view_id):( V8 ~2 t0 _' K$ o' r9 z6 \
  601.     v = sublime.View(view_id); G$ O9 R4 i$ K+ U! w4 i
  602.     for callback in all_callbacks['on_activated']:& F' s% h9 ?" J7 s* w
  603.         run_callback('on_activated', callback, lambda: callback.on_activated(v))/ K# `( h+ J! R# Z
  604.     run_view_listener_callback(v, 'on_activated')/ J; n; L# x1 e2 M9 [* J/ C4 C

  605. * O+ u" b$ I2 S4 G
  606. 6 T0 I4 ~6 P0 z/ [
  607. def on_activated_async(view_id):* e& \* u+ U1 t" _% F8 O
  608.     v = sublime.View(view_id)0 s* J' V) I: ?" {) b
  609.     for callback in all_callbacks['on_activated_async']:2 x7 V$ h+ h6 a; U+ I  O
  610.         try:
    , _' v2 ~$ T% w, U, u, m
  611.             callback.on_activated_async(v)5 f$ j! W7 F/ |/ _
  612.         except:
    " W) |7 D/ o2 L' h* N+ a
  613.             traceback.print_exc()
    6 ~; K. E# E8 Q4 z3 y
  614.     run_async_view_listener_callback(v, 'on_activated_async')
    6 F" [- M' K/ g" a' Y" b
  615. 5 L) A% e' l' \7 Y! a" F
  616. ; W  j( n$ g9 y
  617. def on_deactivated(view_id):& b! Z( n+ `% j+ j5 E( f6 Y' A) U
  618.     v = sublime.View(view_id)6 S; n. v4 ]' M
  619.     for callback in all_callbacks['on_deactivated']:7 I( \/ I) I2 u
  620.         run_callback('on_deactivated', callback, lambda: callback.on_deactivated(v))
    " U# s9 X, \( ]6 @/ D
  621.     run_view_listener_callback(v, 'on_deactivated')
    , E- ?$ _/ t4 \# d6 F2 |
  622. , s1 Q. P% Q2 w8 ~
  623. * f. H# b" S- E
  624. def on_deactivated_async(view_id):# `7 P# e6 y: g7 y2 i
  625.     v = sublime.View(view_id)! A) B0 l& J  [: ]# g" r
  626.     for callback in all_callbacks['on_deactivated_async']:1 d( v4 g; D4 ^1 E  u3 s! O8 e, ^7 j
  627.         try:
      _( I7 f4 K' \" Z5 w8 {
  628.             callback.on_deactivated_async(v)& y+ Q) h0 s' F7 t, ]& W
  629.         except:
    5 _9 K9 M, W) C% s
  630.             traceback.print_exc()
    ( q5 `* k: N. v% L# U, a- F+ p
  631.     run_async_view_listener_callback(v, 'on_deactivated_async')
    - c+ Z, W! F; ?3 M7 i
  632. + R' Y0 R0 H0 O* G

  633. 5 Z0 f# E5 `5 G
  634. def on_query_context(view_id, key, operator, operand, match_all):
    8 E5 }& d' X# ?2 b: G3 E
  635.     v = sublime.View(view_id)" ?+ y0 h& E& @. B
  636.     for callback in all_callbacks['on_query_context']:
    & X2 v; x4 y. H1 i6 c
  637.         try:: E  E+ l5 A0 _0 o, D6 H- F
  638.             val = callback.on_query_context(v, key, operator, operand, match_all)
    . e5 b. f& v$ {) O' @" h; ~. R/ b7 `
  639.             if val:
    / V4 s% H& C( G( \7 t' J4 h
  640.                 return True' E; K! ?* k! q. f% a
  641.         except:
    6 P7 d  {' r% Y; L- e
  642.             traceback.print_exc()
    $ J' f" j6 m& @/ x/ D& m
  643. : Z# }% ~4 @" x$ r+ b/ j( Z
  644.     for vel in event_listeners_for_view(v):
    " O5 Q( e* X6 v/ i8 z1 t
  645.         if 'on_query_context' in vel.__class__.__dict__:: F: j5 j' C8 g* z0 W+ k4 D3 U
  646.             try:
    0 b* x9 b2 x- U1 D% f8 o
  647.                 val = vel.on_query_context(key, operator, operand, match_all), N& S. U% ^7 E6 P
  648.                 if val:3 e2 g' v* w, s% s$ ]/ F
  649.                     return True' G7 n# F4 u0 r: h# k- {) _% n+ E
  650.             except:
    & B4 {( b7 l! b/ n' W6 v. n
  651.                 traceback.print_exc()
    & J0 n2 A1 F% c$ j- ]; y

  652. ; `& G/ o0 s' q5 y5 a$ V6 p' G
  653.     return False. ?" M+ G& [! b* |5 t4 p
  654. 0 T4 q/ i3 O* h9 O0 T0 c

  655. ! D4 ], a) }- Q4 ~/ a. X
  656. def normalise_completion(c):! d$ A) f  y2 I! ]
  657.     if len(c) == 1:
    8 F  `0 ?* t. n- r3 b/ g0 d- I
  658.         return (c[0], "", "")
    + \* z+ ?; @# P# Y' n  M7 S% T2 g
  659.     elif len(c) == 2:
    8 r: e, n0 a* A, h5 T
  660.         return (c[0], "", c[1])
    * }: V5 B( [" Y  Q  d1 c
  661.     else:, b& J, x; n1 D$ F' H8 r0 Z. l
  662.         return c
    ' K4 c% P6 Y( R( V

  663. ' c2 z4 N# g, s# Z" }' T

  664. & {. v. \. [5 h3 P
  665. def on_query_completions(view_id, prefix, locations):7 Z# Y# \9 j: G" d
  666.     v = sublime.View(view_id)
    6 |9 H1 k5 o) f, F7 z' a3 k1 d
  667. 4 \5 Q# o  S& _& B3 {* S, p3 F
  668.     completions = []  z) U0 g+ x) K* m# g( |
  669.     flags = 01 \# @) w6 h) w' C5 c! _6 x9 t1 c
  670.     for callback in all_callbacks['on_query_completions']:& o- q: |, n, W, k  B; Q4 h' q
  671.         try:* L' Q  [: b8 I; o
  672.             res = callback.on_query_completions(v, prefix, locations)
    # X. \2 J* D, z9 O8 [% d/ D; o1 M
  673. 3 r: b& M* h3 l2 g6 V
  674.             if isinstance(res, tuple):
    * ?8 t* U4 a) Z, U2 m! v
  675.                 completions += [normalise_completion(c) for c in res[0]]+ H# E" K1 d8 ?) }0 w
  676.                 flags |= res[1]
    - V9 N  N" b: Q8 k! g) \) Y
  677.             elif isinstance(res, list):3 }) ^* e( q7 j& e5 c; g9 S6 c3 `
  678.                 completions += [normalise_completion(c) for c in res]# _7 R8 E, G- n1 A
  679.         except:% `9 R3 e2 O. ^# T0 I
  680.             traceback.print_exc()7 r1 E" M' R5 c6 ?. {$ t
  681. 9 ?0 Z! J8 H& [: s. R
  682.     for vel in event_listeners_for_view(v):
    ' O  g- t# r8 d- H2 x1 U
  683.         if 'on_query_completions' in vel.__class__.__dict__:
    # K3 X+ k# b, V% q+ J" E! x$ N
  684.             try:
    7 c* d& _% u( ~& ]5 ~7 x
  685.                 res = vel.on_query_completions(prefix, locations)' p; i. D, Q: A! ?* u

  686. : }) B- O6 z% X6 W+ m
  687.                 if isinstance(res, tuple):7 I. T+ ~2 d7 S6 O6 O' r1 c
  688.                     completions += [normalise_completion(c) for c in res[0]]
    + Q7 u- d7 M2 R8 S, r2 R1 l: p- I
  689.                     flags |= res[1]
    # A4 T0 u+ d1 S# m! Q
  690.                 elif isinstance(res, list):
    9 p5 S# r3 J' _/ b& x7 H& y
  691.                     completions += [normalise_completion(c) for c in res]- a) y: b% k7 Z1 @& K2 ^" z) A
  692.             except:
    $ N7 O) }. s7 b* N
  693.                 traceback.print_exc()
    6 \$ t* F# ^  z  ?

  694. 0 b4 \/ ^" k9 u/ t
  695.     return (completions, flags)- M; q2 v" Q+ W, F4 q- [& O
  696. ! C3 g0 a) W$ |/ M
  697. 8 {8 }6 g6 Y7 i  o% F
  698. def on_hover(view_id, point, hover_zone):" l+ d* {  [2 L: |
  699.     v = sublime.View(view_id)+ O& t4 x8 Y' d5 D" j! p
  700.     for callback in all_callbacks['on_hover']:
    / z( t  d! ~* ?: D% C9 T8 y+ m5 Q
  701.         run_callback('on_hover', callback, lambda: callback.on_hover(v, point, hover_zone))
    ; Z) I; _; Z! e( N
  702. ) Q/ p/ S0 c# [0 W, s+ P7 B
  703.     for vel in event_listeners_for_view(v):
    9 N. n5 y2 w6 Y" w+ ?
  704.         if 'on_hover' in vel.__class__.__dict__:0 x* [! N% a% F( ^
  705.             try:  j$ m7 N" V6 H- {. Q
  706.                 vel.on_hover(point, hover_zone)0 z* s9 E8 q9 x/ y6 j( a
  707.             except:
    " |+ ?( Z& x" I% o0 L: H" L$ T
  708.                 traceback.print_exc()  C( T* H7 {* M$ J+ s$ v
  709. * T' x/ w% C5 L* u

  710. ! ?$ g; P$ ^5 p# x* t7 M
  711. def on_text_command(view_id, name, args):3 m$ ^! x) m+ h! c; M) T7 k5 _
  712.     v = sublime.View(view_id)
    ! w2 ?& }. {! S& J

  713. , y! R& h& \0 b: r% b
  714.     for vel in event_listeners_for_view(v):
    . l/ C8 A6 q0 C) N$ c
  715.         if 'on_text_command' in vel.__class__.__dict__:
    / G% E; y2 D7 p
  716.             try:
    ; r+ [$ r  R/ W) p: S8 b
  717.                 res = vel.on_text_command(name, args)7 H& u* P* [1 ~: o
  718.                 if isinstance(res, tuple):
    ! f- V' s0 h$ ?% B( A$ x9 W/ \
  719.                     return res( X7 E4 Z! b, d3 Y
  720.                 elif res:  {( V" U) H& W( Z- g( R/ D; l: ~# e
  721.                     return (res, None)
    0 C- F, @; [6 A* m2 s
  722.             except:% z, w- R1 z3 P+ \7 ~
  723.                 traceback.print_exc()
    % J. H- W0 t- R0 ~

  724. $ q/ j/ w% {+ G& N
  725.     for callback in all_callbacks['on_text_command']:! h$ {+ T; t. k1 ?6 q
  726.         try:" _- P' P/ U! L! L* }" \( S
  727.             res = callback.on_text_command(v, name, args)
    # d6 {0 x1 f) Y5 a; E$ X* }
  728.             if isinstance(res, tuple):0 W1 K( z4 Y2 j  ], M$ n( {
  729.                 return res, x! t% v9 p9 ]
  730.             elif res:
    # F- g* z* e; X  L8 z
  731.                 return (res, None)
    ! V% D6 g3 j  a9 Y$ M% v6 Y
  732.         except:7 U, t/ h. P7 z* M5 _/ D
  733.             traceback.print_exc()7 s2 a0 ^* D% C9 g* {1 p5 N

  734. ; ?2 N' g: E1 c9 \; O# H2 {2 Q
  735.     return ("", None)  m! U: i; C3 [+ Y+ T' X
  736. / @$ {9 ]1 }& V$ }" c0 n+ r

  737. 5 i7 F1 O2 r; [: I6 e5 V" d
  738. def on_window_command(window_id, name, args):
    " ?. I: i1 B/ W( b- o  |# L
  739.     window = sublime.Window(window_id)! N, e1 b" E3 E0 A% K
  740.     for callback in all_callbacks['on_window_command']:! i- {4 K& x/ D! ~/ B4 g
  741.         try:
    , _7 h$ h3 b# L
  742.             res = callback.on_window_command(window, name, args)
    - n3 E) |* a/ r( G, j
  743.             if isinstance(res, tuple):0 h7 p6 ?* r/ a) y! u  L, K
  744.                 return res4 B. }6 m' ]' `2 B; o# S+ {3 o# j
  745.             elif res:
    ( ^) B, \9 \  M  ]
  746.                 return (res, None)
    3 B" d# D" L. U: R1 X, t& l
  747.         except:6 r4 D0 w4 L/ @
  748.             traceback.print_exc()
    % c) }/ M& W& R0 I* {; m; f
  749. ! ~; G1 Q$ h+ ~/ q0 r3 @3 q; N
  750.     return ("", None)
    ' [' q1 P/ P) _! {7 S7 ?
  751. 3 A1 N6 Y* Z: i; J( l' R

  752. * r0 k; Y- e, P
  753. def on_post_text_command(view_id, name, args):
    3 ?: H% Y) o; {  v
  754.     v = sublime.View(view_id)& ^  [8 \- j. I5 x8 g3 q' c
  755.     for callback in all_callbacks['on_post_text_command']:$ a3 b, G2 W3 E# I  W) v9 _$ |! e$ x
  756.         try:
    - O6 [# O( V# g) L3 a
  757.             callback.on_post_text_command(v, name, args)
    ' I4 j7 m8 X5 f6 y# R0 Q  V9 n, e
  758.         except:
    9 B+ ]1 p  g. c+ i( ^$ }) h
  759.             traceback.print_exc()$ E0 W3 ]& C% q7 O( S; ^, K1 V. g

  760. $ ^; Y  ?7 A* {% s2 l, C
  761.     for vel in event_listeners_for_view(v):
    " A3 g' ]) H% `  w
  762.         if 'on_post_text_command' in vel.__class__.__dict__:
    ) e# X3 b9 ~. U6 W
  763.             try:2 l; H1 Y, d$ P  u0 h- i
  764.                 vel.on_post_text_command(name, args)3 C- p: Y5 I( I
  765.             except:
    ( O  [6 R' v" @3 [
  766.                 traceback.print_exc()- J# I( P( e  o* m+ h* \
  767.   X: |8 E1 v3 u' Y
  768. , B# W; \% }9 l) ~/ `  o
  769. def on_post_window_command(window_id, name, args):
    ; u7 e: H; [$ o0 H4 ~# S
  770.     window = sublime.Window(window_id)
    , a8 F* x" Q: w- U
  771.     for callback in all_callbacks['on_post_window_command']:
    2 @% @& u* l6 s
  772.         try:
    . W% }- s# f& b. S. @
  773.             callback.on_post_window_command(window, name, args)
    1 l' e3 s# Y" i4 E) |
  774.         except:, i* l& M) N- c0 |2 R: M3 Z
  775.             traceback.print_exc()  T) e$ S& K) ]8 a* ?* s- _
  776. $ Q! f) q/ a8 s+ w  w' z/ _- N

  777. * F3 Y+ H+ o9 k, m; H
  778. class CommandInputHandler(object):# c: t9 B: f5 d% N5 X: k
  779.     def name(self):
    * B8 l' F7 H6 c2 H
  780.         clsname = self.__class__.__name__) a6 Q) Q. {  k; U
  781.         name = clsname[0].lower()# U$ E7 y5 d* A4 L& l
  782.         last_upper = False
    & W3 j) c4 k9 H8 k: B, y
  783.         for c in clsname[1:]:
    ) t& z7 m+ n9 [2 i+ X& L
  784.             if c.isupper() and not last_upper:, Y7 y! W2 t7 F6 ]" i1 T
  785.                 name += '_'
    2 ^6 ]. Q2 k1 n, W( x' O% N
  786.                 name += c.lower()
    8 T: q; E; m% k! T0 d" S- F
  787.             else:
    + K* X$ `. ^& e: v8 x
  788.                 name += c
    % P+ \+ n  h( ?& N" h% o2 a4 S
  789.             last_upper = c.isupper(); J* p0 g$ P" e/ ~9 j# R7 P
  790.         if name.endswith("_input_handler"):
    ) h+ l5 h) C& g2 v  \
  791.             name = name[0:-14]) w# f9 r3 t. p# A- r- d
  792.         return name
    . ]  _3 g8 W7 d- k& `
  793. ! W* O! `8 D8 ~1 g1 `$ }% w' ~2 C; W$ q
  794.     def next_input(self, args):2 x$ s2 ~- v% e3 F3 r
  795.         return None0 `' j+ t% j; ^) h) Z

  796. , |' p4 E& {8 n. U
  797.     def placeholder(self):
    9 j1 t! Z& t+ w8 I! a
  798.         return ""
    . R5 x0 Q/ S/ \6 B) b7 b7 A
  799. ) p$ y  j7 e) ?( C, S% O) ~3 i* E
  800.     def initial_text(self):
    " ^" K  r9 g+ v
  801.         return ""
    ; o+ ]0 B6 Y+ q# [. c! F
  802. ; k/ ^9 `& ~7 l) b2 J7 o  i' j
  803.     def preview(self, arg):
    7 B  S0 h: B5 y
  804.         return ""2 @5 A; r: w. Z! {* G) I

  805. 2 E0 W" {0 v) W8 J8 x3 b  x
  806.     def validate(self, arg):/ t0 \: |! z3 G4 J' t: q; I
  807.         return True2 g  z( ~( {8 v) l/ T% y. ~1 O* x7 ]
  808. 7 U# x* p& C% m! f( }- @
  809.     def cancel(self):  z, l# h# M$ w- L, x
  810.         pass+ q: `( ~" c2 d

  811. $ V4 T* l* X5 ~3 W" Y& A
  812.     def confirm(self, arg):
    ) O& m. `2 k4 ~2 D  e. S
  813.         pass* N2 a  V. d- m, U

  814. 8 R) R: b. o5 j. D
  815.     def create_input_handler_(self, args):
    0 D* ]( R$ K( M8 y1 o2 T; n1 k# M
  816.         return self.next_input(args): L! Z' B  n8 k* |

  817. 1 u/ L9 w6 j, V
  818.     def preview_(self, v):
    1 q% L1 o2 g- b& F9 ~
  819.         ret = self.preview(v)
    1 `6 U6 H! |8 y0 h. g  p2 r* ~
  820. - O" N5 Z. n# [
  821.         if ret is None:
    4 [1 H$ Q' a3 x$ z2 d* l
  822.             return ("", 0)  R: M7 X8 K" W  f! {
  823.         elif isinstance(ret, sublime.Html):+ ]& }$ ]8 E9 V' \7 Y
  824.             return (ret.data, 1)% R% ?! {+ a* v/ w9 j! U3 e- l
  825.         else:
    ; ^' {( |# W8 w- j& ~$ ~
  826.             return (ret, 0), Y  k- j" b' Z* a) V5 O1 p: m

  827. % u3 d, i8 N3 w8 d" Z& T
  828.     def validate_(self, v):
    5 W  Y6 a$ K5 ^2 h3 Z+ ~- k
  829.         return self.validate(v)
    2 J4 L7 K3 k8 l

  830. 1 R4 s# ^8 v+ T' c
  831.     def cancel_(self):
    / `/ p5 a+ C4 B9 |; H( s
  832.         self.cancel()2 q: N5 U' {3 G& S& L4 A
  833. ; M/ J; q# B6 K+ `9 l% c) _
  834.     def confirm_(self, v):# B; ?2 n6 _  P6 d
  835.         self.confirm(v)
    ; \$ f3 }9 ?2 }2 i

  836. 6 N3 S3 H! n9 n3 f+ \7 K% g1 H
  837. 5 S! e* u7 X5 t" U: @7 C0 O7 D" B' I
  838. class BackInputHandler(CommandInputHandler):, |6 J* L; e7 w: f
  839.     def name(self):9 A% v* X' Q( P- ]+ J  K
  840.         return "_Back"
    , ~4 K" A9 _7 W7 m
  841. - K5 H' P# o# H- q
  842. ) s; n3 }9 s9 Q  G4 r/ ]3 ?
  843. class TextInputHandler(CommandInputHandler):
    $ D; |  {2 e) q% s+ N  \
  844.     def description(self, text):7 z" k+ w+ ^5 n; ]! x( p
  845.         return text8 I1 x8 X, d  X4 i' x
  846. - _, }# p* v* f' n- w# s5 f
  847.     def setup_(self, args):
    ' P) m/ a" J. e
  848.         props = {
    * w' o6 k2 x5 l6 l9 @5 M& E/ U
  849.             "initial_text": self.initial_text(),& X. B2 I$ K4 E- F
  850.             "placeholder_text": self.placeholder(),
    4 t) Z5 S+ N- a, N9 {2 E( @
  851.             "type": "text",& x$ L% j  r5 j. ?( U
  852.         }! `) t5 n  c0 `

  853. & p" v4 ?5 j% h& O% Z
  854.         return ([], props)0 d: x8 I; o/ `
  855. - ], u% F  }5 w1 G& N0 C$ F
  856.     def description_(self, v, text):9 m9 A; }6 S- J
  857.         return self.description(text)2 u+ ^. W' |: D9 a! E+ f
  858. 8 R, c& ^6 N. J0 T

  859. 8 R' I% z9 G7 g
  860. class ListInputHandler(CommandInputHandler):
    0 h2 X: j! T( |2 W+ ^. l. {
  861.     def list_items(self):
    ! ^7 Y* }$ ^8 H
  862.         return []
    ( Z4 d+ e3 d9 q; @7 {1 j

  863. 8 n( Y) p; y! W
  864.     def description(self, v, text):
    + e9 A2 k* L2 Z. z+ g9 j4 S7 O, J
  865.         return text
    * I' |0 J% L+ E3 R. R4 J5 h) b0 C4 Y

  866. 8 I; I+ h7 T% y! X2 J  a/ _0 z
  867.     def setup_(self, args):
    % U2 S$ X4 W! M) q  N. ^
  868.         items = self.list_items()- K$ R. @. }3 d* \) J

  869. # S2 T2 E3 P( J5 @
  870.         selected_item_index = -1
    + }4 x( C/ ~# t: A

  871. 2 J7 P. g% I# ^
  872.         if isinstance(items, tuple):+ K+ Q/ A5 s- ~5 p
  873.             items, selected_item_index = items8 @3 E7 i& ]  Q: _( A$ Z2 J& z
  874. # [7 ]3 e, I; G" ]1 Y1 F
  875.         for i in range(len(items)):
    2 e" c: O8 o% a: l( ^' }; R1 e
  876.             it = items[i]
    ) h/ q/ [+ X7 i! y; C8 f
  877.             if isinstance(it, str):* [- w, c7 a7 d3 D
  878.                 items[i] = (it, it)
    . k7 ]4 W; H! ]  Q' y5 D

  879. - V, O9 @8 b+ z/ ~3 [# S9 P& _2 t! R
  880.         props = {
    ( M5 e2 i" ]1 V# _
  881.             "initial_text": self.initial_text(),9 z" C0 {' q1 B( z7 }
  882.             "placeholder_text": self.placeholder(),- D' l; D# U3 }8 M. ^0 G1 `
  883.             "selected": selected_item_index,
      u- }2 A. `0 [$ ^* l/ n
  884.             "type": "list",
    ( n) a. O  o5 {/ s, Z% \# ?! l
  885.         }
    , A0 v7 k, L# \2 ^
  886. + @. j+ ?: H- \; ]9 a% T6 z$ u
  887.         return (items, props)! u7 r8 S$ v3 c
  888. 9 r% ^, \5 z+ ~8 |" O- [
  889.     def description_(self, v, text):) g, k2 z, |1 z' \1 G& o
  890.         return self.description(v, text)
    , f' |5 f. v% B& ?
  891. ) j9 U$ O/ W, a7 H

  892. 6 r2 W' T2 k( n6 y5 O
  893. class Command(object):
    7 j' h' C" A+ f. r" I7 |
  894.     def name(self):
    0 p. p# {: ^' q9 i1 x7 T$ L
  895.         clsname = self.__class__.__name__2 l& r; ]& G# [; r: K, N- c
  896.         name = clsname[0].lower()
    , P! \- z7 T5 t! |6 a
  897.         last_upper = False" l- v( A/ H. H$ Z2 p1 \  `3 N
  898.         for c in clsname[1:]:% r( F' r( }/ ]* s/ }
  899.             if c.isupper() and not last_upper:
    ( {' D9 p, p$ ]% d' y, O- v
  900.                 name += '_'$ k0 V$ b7 \) {7 ]- K
  901.                 name += c.lower()9 n: {( L* T* s7 |
  902.             else:2 j. H9 n( g, }% \& K5 @) m
  903.                 name += c
    4 Z7 |7 G2 X& L, K* _
  904.             last_upper = c.isupper()
    4 I# U( V5 @* s% J8 B# A
  905.         if name.endswith("_command"):
    1 V+ e% K  B9 Q' U: [
  906.             name = name[0:-8]
    * G7 X; |" G% G4 O# u8 o
  907.         return name7 n! y6 ?( \7 M9 I/ x) M) a
  908. + R3 E  j6 m) S# D/ x7 ]& M
  909.     def is_enabled_(self, args):
    9 x" d0 `. m4 I2 t3 F, B4 x6 Q
  910.         ret = None
    8 i6 d+ y  d7 P( ?/ ~
  911.         try:  G: K6 P" B; G) j3 q
  912.             args = self.filter_args(args)! X2 V! T$ E4 t& C: ]
  913.             if args:
    3 f$ @( N& I' V* I
  914.                 ret = self.is_enabled(**args): H9 W9 _0 {/ o5 X+ y9 u& G+ b
  915.             else:
    " |$ @9 I6 y, V6 @- ]2 w
  916.                 ret = self.is_enabled(): `) I; I( Y  v
  917.         except TypeError:) L7 i0 I; m9 E5 i0 S9 Z
  918.             ret = self.is_enabled()  S3 i) H6 d; t- s8 M
  919. & t5 y0 q# Y, F- g: m- d6 X8 [! f
  920.         if not isinstance(ret, bool):
    $ ?& q' G' V9 q! p7 a
  921.             raise ValueError("is_enabled must return a bool", self)
    ; |1 I& i6 S% y- M+ P

  922. , F4 a- R& ^& T5 t  H% V
  923.         return ret
    5 b9 K9 \) J. z* y+ _. h: Z

  924. $ A3 x( g/ O% I( ?$ O5 ~, J
  925.     def is_enabled(self):- A2 i% V* A4 j: Z8 j; t. R- B2 k8 X
  926.         return True) ^9 i. ^" ?0 ~! c& ]

  927. # c  N3 }$ }$ ?: O
  928.     def is_visible_(self, args):
    ! O4 q& X5 }' H5 h( _! s
  929.         ret = None
    " E5 `# a. F" z$ @( G9 _! T! g/ a
  930.         try:" D" K; a3 \4 Y3 P
  931.             args = self.filter_args(args)5 a  t5 h, n0 M* ]) ~2 g
  932.             if args:+ ?& c4 A4 u6 ~- e9 X* h8 w
  933.                 ret = self.is_visible(**args)* O5 ?+ B1 ?( E3 Q
  934.             else:; x7 x4 p) [$ \
  935.                 ret = self.is_visible()9 k# n; w: a7 P) \
  936.         except TypeError:
    ' b% w$ P. u, ~% R7 s1 ^2 S! _
  937.             ret = self.is_visible()
    . T7 z/ `3 Z. N) v
  938. 4 |) z1 k! K' }* J4 a& r
  939.         if not isinstance(ret, bool):
    ) M# V  f, O% u: C4 |( m5 ?
  940.             raise ValueError("is_visible must return a bool", self)* a: s: J% Q* |' R8 b4 d* Q+ F
  941. . y7 f6 A; C; c7 ]
  942.         return ret
    / v% N  K! [9 b0 ?" G0 Y

  943. 1 H) ^7 O2 j- q9 p6 p/ n6 u
  944.     def is_visible(self):$ u2 ^  X* A+ Y8 x
  945.         return True
    # n% D9 C( I* O" n$ a/ P

  946. % w# }/ ]/ s0 v  L- U" T# o* r4 Y4 ]
  947.     def is_checked_(self, args):8 b% F4 h! E- T5 N" v" G
  948.         ret = None$ s" L0 q# J# d/ g2 T. D' L) _
  949.         try:
    ' t% y2 G' d! k) m
  950.             args = self.filter_args(args)
    8 S+ l) z2 K6 L8 L! ]6 k
  951.             if args:
    & w  P9 H0 g  |# g# K& E9 [" C7 m
  952.                 ret = self.is_checked(**args)& C8 @8 U  I. l, r
  953.             else:
    6 |! g! O! V% A
  954.                 ret = self.is_checked()& w8 o/ ?6 ]6 `/ r) L
  955.         except TypeError:) B& I9 S0 y3 X0 S5 b
  956.             ret = self.is_checked()* T2 f* k2 T  Z3 c6 E

  957. , R% }$ [# K: s0 z8 D, ?! }
  958.         if not isinstance(ret, bool):
    % ?8 V: ^5 G. j
  959.             raise ValueError("is_checked must return a bool", self)4 L+ a5 Y8 X% `  P) x5 G# @; K

  960. 2 E" I* j; A4 k) s% a2 x
  961.         return ret
    & z  `* D5 Q' D, F1 f
  962. 4 x  p3 Y. u& ~6 r
  963.     def is_checked(self):
    8 P7 \, s9 a& P5 @0 {9 j
  964.         return False
    : O! ^% v; ~5 }# k' ]- b+ F

  965. / }* T! w, `( o) `# D
  966.     def description_(self, args):
    8 {. R5 I4 j0 ?5 W
  967.         try:- \* k% q& Y: C# |# V; l5 T
  968.             args = self.filter_args(args)& T6 ^$ `  z! N+ i9 N( c0 V; }1 Q! T
  969.             if args is not None:
    # y5 ?6 T4 |3 I
  970.                 return self.description(**args)6 Q0 @0 _6 y* l) M! u8 A# ~
  971.             else:
    + X1 G4 \9 _5 f# f5 Y
  972.                 return self.description()' A% j) N& \, m$ r' L
  973.         except TypeError:* z9 N. z6 v2 X
  974.             return ""
    3 c5 N5 W' v0 t! A# k0 C1 `
  975. 7 f: S* D. q. l- `, O5 {0 J' r7 t
  976.     def description(self):
    2 C: u' [/ p2 i- z! r
  977.         return ""
    ' A. s" @; g* [* s: q$ _

  978. 0 h; Z% W" `+ J2 j) D
  979.     def filter_args(self, args):
    ; Q+ ?, I0 N* L
  980.         if args:
    ' t  o/ O% Z: f6 @3 [
  981.             if 'event' in args and not self.want_event():
    3 @$ z& Q5 N9 H+ n+ `- \8 Z
  982.                 args = args.copy()
    0 ?' u* H9 E9 X& I* ]
  983.                 del args['event']! h/ b, q3 q9 x2 e
  984. ! H7 q/ q& ?/ [, x3 Q
  985.         return args0 H+ H, j- @8 a$ S" i1 z
  986. ) q! A7 V" u' }/ [
  987.     def want_event(self):: A4 S5 q5 J. Y) D  \0 c
  988.         return False
    2 ~& }$ z! o! U( ]/ R

  989. 9 R2 j- J1 M( ?3 c
  990.     def input(self, args):
    2 j3 ^- d9 O: V5 o% }! r
  991.         return None
    8 }: P0 ?% G/ c  N0 o& v: c

  992. 7 M6 x9 z4 w  h
  993.     def input_description(self):
    ! E9 r6 g' y( ~' d" h5 d4 c! _$ M+ O4 A
  994.         return ""; Z; o- V; E) K* k( q. e

  995. # B/ f! |9 w8 H( `1 P6 L; Y) J
  996.     def create_input_handler_(self, args):+ w1 C7 T0 j" t0 l+ z5 B
  997.         return self.input(args)
    & k' {- l& H/ x% u% b

  998. ' C3 F- d6 g; t! a) W( G7 G
  999. , d  |/ E& [$ q
  1000. class ApplicationCommand(Command):% t# l3 ]& N  E2 m- T  i  ]
  1001.     def run_(self, edit_token, args):) o" Y- ]( i& k
  1002.         args = self.filter_args(args)
    ) p7 A7 |( t8 t, R% d) y9 V. m% m
  1003.         try:
    5 f6 X' Z" D( M) R: S- ^9 w& C) _' s
  1004.             if args:1 }$ A( Y  w. D$ r
  1005.                 return self.run(**args)
    % a/ n* G3 D) L2 S+ W+ W
  1006.             else:7 u- o) a- J0 U/ p7 ~
  1007.                 return self.run()
    , x5 Q. E: |  f& S/ X
  1008.         except (TypeError) as e:
    1 M$ _6 W# u2 ~8 d/ Q6 ?+ p( V
  1009.             if 'required positional argument' in str(e):
    3 {& v' g. Y6 i$ N& [! f7 k8 T; W1 @
  1010.                 if sublime_api.can_accept_input(self.name(), args):! u8 a7 {, K, A- C: `. L% @
  1011.                     sublime.active_window().run_command(4 p( x! T; G! C! c
  1012.                         'show_overlay',
    2 F- x9 _' }/ n& @  Z9 D
  1013.                         {8 h1 d4 @! n* M# {  Q" b; z
  1014.                             'overlay': 'command_palette',! U! K2 B- g$ s3 r' Z
  1015.                             'command': self.name(),3 ]. R5 O+ M. b2 b6 z1 g
  1016.                             'args': args; a% T" {* U: g& _/ m7 c$ z
  1017.                         }( \, p+ b6 Q2 p2 `+ {
  1018.                     )
    9 `! V: W4 Z  m
  1019.                     return
    9 h  Q# z3 y7 I, V1 b4 _
  1020.             raise) I0 C: b/ y5 N9 N6 c
  1021. # `: W; P9 x& U7 Q# j/ S  |
  1022.     def run(self):! C; {1 s, y7 L" T+ N8 f
  1023.         pass& n9 j) ?9 S# E& W) Q
  1024. 1 N9 Z# O- x$ U& Y
  1025. 0 b% Q" o  ?9 \" S" K2 S
  1026. class WindowCommand(Command):
    $ Q: ]% x0 l5 N0 j/ o2 z- G
  1027.     def __init__(self, window):
    2 ?; S( e0 T" S* P" C8 T
  1028.         self.window = window
    + U% f0 m! L( K6 o( s2 m: v
  1029. ; ^( ?' z* ^/ V0 A2 ^- g. B  D4 V
  1030.     def run_(self, edit_token, args):
    , r0 G( i& K: ?3 I. f- y
  1031.         args = self.filter_args(args); |' Q8 P  y  f
  1032.         try:: B( \- z: _/ U( R  K( p
  1033.             if args:* [3 H" q1 X; r( X" j7 u, f) Q
  1034.                 return self.run(**args)8 x: `4 ~; a1 @+ o% k& n* z
  1035.             else:6 c" `% A; v! v5 R0 U
  1036.                 return self.run()/ t. E: P# R$ a$ b) s
  1037.         except (TypeError) as e:
    & T9 M5 n  ^! j. a$ J% K
  1038.             if 'required positional argument' in str(e):
    % L1 t6 x* C2 [0 [% x
  1039.                 if sublime_api.window_can_accept_input(self.window.id(), self.name(), args):
    0 q- ~, z' }" X8 |
  1040.                     sublime_api.window_run_command(
    ; \/ k+ G1 P6 `+ S' L' D: t& ?$ |
  1041.                         self.window.id(),
    ) z- J' D: n# ~7 d, z9 C
  1042.                         'show_overlay',+ _9 [  X% {. z5 ~
  1043.                         {9 C* v8 @, X* A, ?8 ^3 p
  1044.                             'overlay': 'command_palette',
    - T! {$ x$ S- I# P" |0 i
  1045.                             'command': self.name(),- N% L/ a) e3 T( ~
  1046.                             'args': args. U. w8 b  n- ^" W0 r* O2 M4 |' S0 J# l
  1047.                         }
    $ x  p+ U9 o/ ^2 x' Q& Q7 N
  1048.                     )  I* d, }7 q5 ^0 R
  1049.                     return  b, v0 Q6 n( ^4 N) k3 K/ E
  1050.             raise6 ?0 o- n! o0 {: L/ S5 ?# [, X

  1051. + K, V$ H& r' Z$ S; ^
  1052.     def run(self):
    ) [5 E2 |/ O* h6 b
  1053.         pass
    ) Y) G3 ~; l9 ?/ Y+ ^+ T0 J

  1054. ( I/ L: a# `: ^

  1055. , Q) b% K3 Y; H; j8 _
  1056. class TextCommand(Command):
    7 r% e) a4 x7 w; ?" o" H. x& E* c3 u
  1057.     def __init__(self, view):
    7 l/ a) R+ t0 B
  1058.         self.view = view- }: q! p1 j$ k6 M
  1059. * i  Z$ T* Y( A: N8 A8 Q6 T4 h
  1060.     def run_(self, edit_token, args):0 j- [' G6 o5 O' ]
  1061.         args = self.filter_args(args)
    ! [$ u! }6 H' y) B" n
  1062.         try:6 E! C* {3 _3 S! G2 V
  1063.             if args:6 b3 k* M4 }( f2 N
  1064.                 edit = self.view.begin_edit(edit_token, self.name(), args)
    , ?! o% j- F7 `5 Y3 y
  1065.                 try:3 k8 j1 c2 R0 S
  1066.                     return self.run(edit, **args)9 H7 r# \4 A) i* `
  1067.                 finally:
    . |; b0 `( E2 W( i
  1068.                     self.view.end_edit(edit). A; x; w) l+ a2 W* u
  1069.             else:6 F9 S3 ^6 S) H! i+ _
  1070.                 edit = self.view.begin_edit(edit_token, self.name())$ X% I" T( ]+ p! u8 P% V
  1071.                 try:- S- Z# Y9 W( g1 E+ U
  1072.                     return self.run(edit)
    7 Y6 q. f1 b- N' H: Z
  1073.                 finally:
    ; m4 V( n) S) |  x3 ?7 t
  1074.                     self.view.end_edit(edit). q! _) K( ]: @7 C3 C5 U
  1075.         except (TypeError) as e:  G  P5 _# w; @4 O
  1076.             if 'required positional argument' in str(e):
    3 T, b! a; Q) x1 Y, k6 l: }1 {) R. K
  1077.                 if sublime_api.view_can_accept_input(self.view.id(), self.name(), args):5 }8 h/ ]' Y; L& s& b+ F: q
  1078.                     sublime_api.window_run_command(, t+ v3 {) N" }! G/ [$ y; E
  1079.                         sublime_api.view_window(self.view.id()),
    3 Q4 ?2 ?" O/ l# h! F, [$ F' Z
  1080.                         'show_overlay',
    : s+ a8 X& M' l/ f0 I
  1081.                         {
    ' w% p! B) @$ `! t
  1082.                             'overlay': 'command_palette',
    ; W4 l: {9 N# W* E/ I
  1083.                             'command': self.name(),
    ! X, _$ |- C. J1 Z5 G+ @9 Y
  1084.                             'args': args
      y9 `6 B- ^" j
  1085.                         }7 B1 g( t; P* _
  1086.                     ): J- d( h! |: E7 g' D1 V4 ^. O& g
  1087.                     return7 \( l, K9 u/ ?  a5 d
  1088.             raise
    # X/ ]' V/ Q7 [. |* c( a( D! L

  1089. 0 F3 X0 [1 l; p$ N3 Q
  1090.     def run(self, edit):
    ! d' m8 Z  @3 Z2 c# L* V  o
  1091.         pass
    + F) `% I- L' Y  h
  1092. , F% u( t" L# C

  1093. $ j3 T* g- U& `" O$ g
  1094. class EventListener(object):
      J# @6 A& ?* f3 H5 P  j9 p
  1095.     pass
    $ ?$ j- d9 j2 i( A% Q0 U3 h# b

  1096. : F) w3 M6 ]6 _5 L. g( {- s
  1097. + n/ U2 ?' y8 l' _
  1098. class ViewEventListener(object):4 m: q, `* e! U! J) i
  1099.     @classmethod
    * m" L( Y7 B& c$ A9 B
  1100.     def is_applicable(cls, settings):
    6 E8 S" y& _3 E5 \' O' \( `/ p$ u
  1101.         return True
    6 a8 o0 {: v) U+ x4 y: J
  1102. - _5 V9 W5 J: H& r" q! s$ q- h: C
  1103.     @classmethod
    ) g8 @7 A  _# k8 v  j4 a
  1104.     def applies_to_primary_view_only(cls):2 _" ^1 a- o; N  W- t. D, |
  1105.         return True0 `7 D/ |1 [5 f- v6 [$ w8 }
  1106. , Y* K2 d$ v# X4 X0 k
  1107.     def __init__(self, view):( d8 `) ~- X/ P- ^
  1108.         self.view = view- k1 S; s9 W( H5 F

  1109. ! g" ?; @& M, M6 \- Z, E! |

  1110. ; Y# d1 i! ?/ P4 H. p' S+ o
  1111. class MultizipImporter(object):2 n/ m8 K$ a4 `2 U1 a
  1112.     def __init__(self):9 n; M  I6 ~5 Z) |
  1113.         self.loaders = []6 e! x- _; l9 R
  1114.         self.file_loaders = []5 L2 Z& p6 r0 R, ~; [- v6 Y

  1115. 6 ?4 }. M4 o9 r; y: T: z
  1116.     def find_module(self, fullname, path=None):
    1 R; \8 J/ s, j' S# Y
  1117.         if not path:
    * _6 H4 _1 x1 k3 l' x
  1118.             for l in self.loaders:5 P( E, n/ F  A& m
  1119.                 if l.name == fullname:
    , N8 P1 V9 r# h1 H! m  P
  1120.                     return l
    ( p' V! w0 I1 ?& w) K0 q$ Y
  1121. & \: P: ?2 E  |, G
  1122.         for l in self.loaders:4 e. ?; H. ~, X% n( L1 @
  1123.             if path == [l.zippath]:
    ; Z' I' ?$ P8 F7 G2 s
  1124.                 if l.has(fullname):
    1 a8 d. G$ \- P0 d* C3 ~1 c% Y
  1125.                     return l
    " `% H& R4 O) H( j. H
  1126. : ^" y. ]9 O6 z3 w
  1127.         return None! x. Z$ x- A  }6 a
  1128. 0 k0 P$ l5 B& Q
  1129. 0 |& I9 u9 K( g8 ?3 k
  1130. class ZipLoader(object):
    3 m; T6 u1 a4 ~, M4 t" a0 G- ?
  1131.     def __init__(self, zippath):- w4 f8 t$ _5 L% c/ l& j$ ~) Y- N3 L; V& p
  1132.         self.zippath = zippath
    ; J6 _6 p' a; v  W+ X3 W7 G% h
  1133.         self.name = os.path.splitext(os.path.basename(zippath))[0]% t- O' ~& M# i/ W5 D
  1134.         self._scan_zip()
    3 P! Z3 q# n8 `  L  t* o# H7 U
  1135. ; |1 J. e! K1 f9 b; T1 B  @
  1136.     def has(self, fullname):9 v* |/ Y0 f5 ]  F# r
  1137.         name, key = fullname.split('.', 1)6 W. _" _+ K: I* D+ f, {' ]6 q' s
  1138.         if name == self.name and key in self.contents:
    & A- Y& \+ j- n2 M# ]1 w. a: I. d' O
  1139.             return True2 T* M2 c$ t* J+ `) W; j
  1140. . h; g7 k* Z9 G1 r5 \1 @
  1141.         override_file = os.path.join(override_path, os.sep.join(fullname.split('.')) + '.py')8 l4 H$ i- ~# ]. S4 l- V, F8 P6 j
  1142.         if os.path.isfile(override_file):2 G4 M8 V+ q$ S
  1143.             return True
      w  {( E5 O9 O; ]
  1144. / |; h6 |# J4 f8 J4 y5 _, X
  1145.         override_package = os.path.join(override_path, os.sep.join(fullname.split('.')))! O" }1 a! }/ h  X/ J. d8 K  r0 j! M
  1146.         if os.path.isdir(override_package):' B& X, v- e$ O! z* T$ q) ~7 Z6 L
  1147.             return True- G6 C; s3 x, a. m) x0 _! W, _5 z

  1148. * h' ?; c4 X# Y7 ^
  1149.         return False' O' L- ]7 e8 U+ r/ @

  1150. : F, d: W1 u# o- g2 x6 e& G' S
  1151.     def load_module(self, fullname):$ E2 v  \8 l+ s% Z
  1152.         # Only if a module is being reloaded and hasn't been scanned recently
    ) z! ^, ~( o) `9 E1 ^% r% C" }: b
  1153.         # do we force a refresh of the contents of the .sublime-package. This9 d3 k# y& A6 q5 {
  1154.         # allows proper code upgrades using Package Control.( R8 C& `' O; i' }. l5 K
  1155.         if fullname in imp._RELOADING:
    : K9 o# B8 F. e
  1156.             if self.refreshed < time.time() - 5:! P0 j9 H5 @4 n% X
  1157.                 self._scan_zip()2 l) a, f3 q+ p: t0 v+ {% B

  1158. " T, G' R, X7 t" C. o! ~
  1159.         source, source_path, is_pkg = self._read_source(fullname)
    6 C% G! }2 w: O. V( x' x$ @

  1160. ! n. w5 M! {# v& Q4 @
  1161.         if source is None:; \% L0 C+ M# N
  1162.             raise ImportError("No module named '%s'" % fullname)
    " ]0 _6 z7 A8 X5 i
  1163. , {1 H4 M$ U' D4 ]. ~. u, M7 \" |) ~
  1164.         is_new = False# H$ R; N7 e) m0 z/ k7 _3 _7 L+ W
  1165.         if fullname in sys.modules:
    7 m0 N+ m( `, }) D: u. c& K0 c
  1166.             mod = sys.modules[fullname], Z% z3 d* s4 ~+ y5 U
  1167.             old_mod_file = mod.__file__
    2 @4 i4 D  ^6 O( p- f+ ~( ~
  1168.         else:! w7 F4 f7 R. e4 N
  1169.             is_new = True
    , w" Z# Y/ @3 p& x
  1170.             mod = sys.modules.setdefault(fullname, imp.new_module(fullname))
    " Q# y& s( x8 Z" E7 A5 Y1 M
  1171.             mod.__name__ = fullname
    2 c2 a# z/ l! q1 k1 O5 F
  1172.             mod.__path__ = [self.zippath]
      L. z# _9 e9 o+ |; G1 {
  1173.             mod.__loader__ = self
    $ w/ w* X) J5 J2 T% Y% ?! J3 d
  1174. % n: `. E" G& }: F
  1175.         mod.__file__ = source_path% M0 \' P% ~, o* n* z# s9 Q

  1176. " ]/ g; P" }9 e4 d. g; b  B, V1 B
  1177.         if is_pkg:
    9 Y, Q  t( h' `
  1178.             mod.__package__ = mod.__name__
    $ z, H  J' j) f! g4 i
  1179.         else:
    * o/ H0 h: {9 p7 G" ~- i
  1180.             mod.__package__ = fullname.rpartition('.')[0]
    ; j. Y2 q- t" l

  1181. / B8 L4 m; s7 s  p0 A( r
  1182.         try:
    " l0 F7 @$ a, x
  1183.             exec(compile(source, source_path, 'exec'), mod.__dict__)
    $ Y- u2 U9 f9 B, Q- E
  1184.             return mod! [: F: i, S, f) j! |" U: N- [

  1185. & z) s, e; ~- ^  s; f4 Q3 M, w9 Q7 d
  1186.         except:
    $ F( |8 T% M6 }* G8 N
  1187.             if is_new:
    ' M- `* v, S: ~/ ]+ e' G& {
  1188.                 del sys.modules[fullname]
    8 Y' c8 t" s: o' m/ J  Y
  1189.             else:! X; [3 h4 w/ ^  X& y
  1190.                 mod.__file__ = old_mod_file2 X  ^9 \2 J8 f! D( Q# N
  1191.             raise4 _+ X! M8 @. v, T' ?

  1192. 6 _& e: u2 m( A+ A( }$ o
  1193.     def get_source(self, fullname):
    4 i& m0 y7 k4 m2 x, O2 d
  1194.         name, key = fullname.split('.', 1)$ n; D: ^) l2 t
  1195.         if name != self.name:4 q# ]( ?$ n5 J3 _: g
  1196.             return None7 x+ G8 ^2 }! W$ j2 j  a3 ?! A
  1197.         source, _, _ = self._read_source(fullname)) Z/ h. z; E* l! a+ O8 X: s- _
  1198.         return source0 h5 ~/ A" }6 C
  1199. % l0 p9 y5 `1 R( V% @& u) M! D
  1200.     def _read_source(self, fullname):
    : {: V3 F2 x3 j: a5 N- v
  1201.         name_parts = fullname.split('.')1 S" X- A/ d. o& ]# T- a+ B
  1202.         override_basename = os.path.join(override_path, *name_parts)
    , M) Q& H) I. @0 o0 x7 ~# J
  1203.         override_py = override_basename + '.py'
    3 j( y8 h/ ?9 l- I& W. }
  1204.         override_init = os.path.join(override_basename, '__init__.py')7 y8 S- a7 `  I
  1205. 1 l8 G3 t9 S; }" m
  1206.         if os.path.isfile(override_py):
    # J7 @0 j, [, {; y7 x
  1207.             try:$ C$ s. P; l4 I' Q- O4 s
  1208.                 with open(override_py, 'r', encoding='utf-8') as f:) o  N/ j. k  X; B, x8 ?
  1209.                     return (f.read(), override_py, False)
    5 S  S2 a6 w6 F% \: q
  1210.             except (Exception) as e:( a/ U' L3 s0 x
  1211.                 print(override_py, 'could not be read:', e)2 v& p: D& P* O' s% E( q5 j
  1212. 9 @+ C+ H4 ]+ T+ y0 T  }
  1213.         if os.path.isfile(override_init):
    8 _) Y% Z3 D# @( M
  1214.             try:- n9 m/ m6 p& m( }3 l- k
  1215.                 with open(override_init, 'r', encoding='utf-8') as f:
    + o$ s1 r2 k, |! ]
  1216.                     return (f.read(), override_init, True)
    * Z/ ]8 V* U: x" ~
  1217.             except (Exception) as e:* V( l3 S: C9 b5 {5 _, l+ T
  1218.                 print(override_init, 'could not be read:', e)
    ! P* n, [. ^& v

  1219. : U# t! z& N! Z
  1220.         key = '.'.join(name_parts[1:])
    + V8 S& m! u6 C1 @$ v3 ~9 \0 M
  1221.         if key in self.contents:% M4 X/ s) {& U+ ?: N1 Z  f
  1222.             source = self.contents[key]
    - R" Z" N+ W5 e' w* e; ]/ J# ?7 _2 H
  1223.             source_path = os.path.join(self.zippath, self.filenames[key]).rstrip(os.sep)6 i8 S2 e$ a1 h, K
  1224.             is_pkg = key in self.packages2 X" u3 ^: G7 D' o
  1225.             return (source, source_path, is_pkg)
    2 V* a( a' z! I$ D/ a5 z- i* s& `

  1226. . U* T, ?, M3 F. h' t
  1227.         # This allows .py overrides to exist in subfolders that:
    ( X1 Y+ f  y$ m5 r; L6 _  _) K
  1228.         #  1. Do not exist in the .sublime-package file4 d- [5 V! l1 O0 g1 n
  1229.         #  2. Do not contain an __init__.py$ h2 Y: y6 X, }# P. q. x
  1230.         if os.path.isdir(override_basename):# G" j7 b& g! {8 O) ~9 d
  1231.             return ('', override_basename, True)
    4 ]0 U# H8 `( r' ?

  1232. / E' x4 }7 T. Y# k
  1233.         return (None, None, False)3 w& c% V) s* U) j. l; v" R$ S

  1234. " h  Y7 P/ d2 y: B/ z. s" [3 X
  1235.     def _scan_zip(self):
    - E: @0 |" @7 l  o, ^% O' Z
  1236.         self.contents = {"": ""}
    ' |+ e* F4 h1 c: c: x& Q; E" d5 n; c
  1237.         self.filenames = {"": ""}
    5 u' g  M! b# ?. ?+ G5 H. _5 ]
  1238.         self.packages = {""}
    ( T0 p7 Y) a9 s: Z3 U
  1239.         self.refreshed = time.time()  n$ I/ N* b; {( U/ {! d! R
  1240. + x* W+ y' q) f9 Y" W
  1241.         try:
    1 N% {$ @, ]  [1 o, u  U
  1242.             with zipfile.ZipFile(self.zippath, 'r') as z:, c- p2 m* I6 ~& G9 H
  1243.                 files = [i.filename for i in z.infolist()]
    6 E: U- ^8 T0 q5 x  L' e( ^

  1244. 9 {; h* i: k  m
  1245.                 for f in files:
    ' I; s) K1 I% K, s" M9 B
  1246.                     base, ext = os.path.splitext(f)
    # n# }4 m4 V% s9 ^8 Z
  1247.                     if ext != ".py":
    ! s- A( n$ f1 e1 \  Z1 N0 r; ~* U
  1248.                         continue9 W: A  E$ B! W

  1249. ' i$ [3 E( ]9 P% Q! E1 [4 S
  1250.                     paths = base.split('/')0 O) o6 M/ Q  q' P9 D# ]
  1251.                     if len(paths) > 0 and paths[len(paths) - 1] == "__init__":
    ( t1 p! R" P: t8 }* k
  1252.                         paths.pop(); [' x3 y$ I, v/ H- g* H' T
  1253.                         self.packages.add('.'.join(paths))2 I' }/ [5 Z5 e2 v

  1254. ; c8 s. U  s- A5 u) m, Z0 P8 ~
  1255.                     try:
    % D7 V0 v0 q( R
  1256.                         pkg_path = '.'.join(paths)- |0 {, {7 D, M4 T9 e* `
  1257.                         self.contents[pkg_path] = z.read(f).decode('utf-8')9 o' e* [8 r; O: G3 C
  1258.                         self.filenames[pkg_path] = f- a* e# ~( s/ S8 z2 B
  1259.                     except UnicodeDecodeError:
    ( o. C) I0 |1 |5 S+ q6 \" {- I
  1260.                         print(f, "in", self.zippath, "is not utf-8 encoded, unable to load plugin")
    ! n1 f9 a; |- ?+ P
  1261.                         continue& {$ Y. o. S# u( e) L0 @
  1262. . `+ ?' O& B& e  H8 B7 T) f
  1263.                     while len(paths) > 1:/ ^* k- j  ^- ?0 t
  1264.                         paths.pop()
    0 k4 B  J* f  U( k
  1265.                         parent = '.'.join(paths)
    8 V$ J2 Q5 ^$ p, c9 K0 I6 H4 W
  1266.                         if parent not in self.contents:1 u% T1 l) H4 e  R. ]9 e6 I
  1267.                             self.contents[parent] = ""8 G! z, i5 N4 T- S. T& A  {: i
  1268.                             self.filenames[parent] = parent) d. \4 ~7 [5 U3 L0 r. C& R
  1269.                             self.packages.add(parent)
    * z3 y8 u  ^! S$ l, s/ I
  1270.         except (Exception) as e:
    : ~. k# H4 U1 v! ]( A
  1271.             print("Error loading %s:" % self.zippath, e)
    2 U2 {% F% s) o& \3 f( I6 T
  1272. $ N7 N0 r9 j/ r! \! K
  1273. : o0 G9 u$ v! Y8 i- H# w
  1274. override_path = None
    $ t0 u) a& N' u8 U# ]
  1275. multi_importer = MultizipImporter()
    ) l; s7 d! D( y! |4 T. H. ]
  1276. sys.meta_path.insert(0, multi_importer)7 q  k3 g: \9 v" S$ D
  1277. % r; j+ d. W# i* H% H: O2 {1 U
  1278. , c% F0 P* A  A
  1279. def update_compressed_packages(pkgs):. j7 I7 B& a9 I& b( {
  1280.     multi_importer.loaders = []
    " m4 a8 f+ M2 r% d0 O+ x
  1281.     for p in pkgs:
    + |+ U' l' n6 U# s* n' K3 \
  1282.         try:; g. W5 d6 ?. v$ b1 L
  1283.             multi_importer.loaders.append(ZipLoader(p))- G: w! c/ i% q% K4 p
  1284.         except (FileNotFoundError, zipfile.BadZipFile) as e:) M% A( Z) ^* e9 D( W4 Z7 J
  1285.             print("error loading " + p + ": " + str(e))* q6 @. T  [1 P0 E: ]  n% o0 a

  1286. , s  [3 k+ D" ?, `; S5 o

  1287. 6 A4 M4 A7 `* t- ?7 L3 f
  1288. def set_override_path(path):
    ) K- @) [) v- B5 |+ S
  1289.     global override_path
    , W# D. R, O4 }* f6 z* h; F/ p
  1290.     override_path = path; t, v. g% w- @; k: Y& z
复制代码
$ Y+ [. U9 N- V0 V3 N! e# k8 D. ]
! [5 k" A0 W# N5 l$ ?
8 F( v" ]# D: ]7 J( V

5 ^, A; P# [( W8 j
[我是一个默认签名,快去设置里设置一个个性签名吧(*^ワ^*)] 动象论坛欢迎您!(´∇ノ`*)ノ
188

106

主题

1159

回帖

4446

积分

惊鸿侠影

积分
4446

最佳新人活跃会员灌水之王

发表于 2020-5-3 15:34:21 | 显示全部楼层 IP:江西赣州
可以哇,但我懒得看hhh
" E7 R6 _, R. O毕竟不是学这东西的
水帖使我快乐
回复

使用道具 举报

666

266

主题

1395

回帖

1万

积分

清正廉明~管理员

用心做好论坛,用心创造精品!

积分
11043

最佳新人活跃会员热心会员推广达人宣传达人灌水之王突出贡献优秀版主荣誉管理论坛元老

QQ
发表于 2020-5-3 15:36:57 | 显示全部楼层 IP:江西南昌
文外缪朴奂 发表于 2020-5-3 15:345 S! E, H, s! ]. `4 R- E
可以哇,但我懒得看hhh
: B# Z/ @5 z2 z* u毕竟不是学这东西的
6 {* e# U+ {$ ^6 J0 W9 e/ n8 a

4 ]4 Q4 y/ k- n
& S6 r% \4 h  x! P: M4 e
0 i( x: t8 H/ ?
* @9 R$ ^% D# a9 k3 ^& j% @" N! M, o( X

# o0 n1 x* O$ S9 ?2 ?3 f1 I+ |+ ?& e5 o) I( W' Z2 V
2 q& N" n; M9 I8 K) I: Z/ O7 Q
动象论坛
点滴纯粹 简单自然
动象论坛,用心做好论坛!用心创造精品!
[点我进入]www.mjysd.top
回复

使用道具 举报

188

106

主题

1159

回帖

4446

积分

惊鸿侠影

积分
4446

最佳新人活跃会员灌水之王

发表于 2020-5-3 15:38:55 | 显示全部楼层 IP:江西赣州
admin 发表于 2020-5-3 15:36. T9 I1 w$ s0 R# P. k
8 Z. l6 j' T9 {! a

4 \9 ]2 I* s6 x# l7 w' r8 T1 K
0 e& L4 h/ y5 t* ]( ~
made,我才发两行
水帖使我快乐
回复

使用道具 举报

666

266

主题

1395

回帖

1万

积分

清正廉明~管理员

用心做好论坛,用心创造精品!

积分
11043

最佳新人活跃会员热心会员推广达人宣传达人灌水之王突出贡献优秀版主荣誉管理论坛元老

QQ
发表于 2020-5-3 15:39:33 | 显示全部楼层 IP:江西南昌
文外缪朴奂 发表于 2020-5-3 15:38
0 h3 U. i" r* c* n+ L! Z' amade,我才发两行
' ^( ~+ ?8 }; V5 K
- W% ]6 l8 {$ A1 l( M5 E) ]  j4 w
0 F/ Z1 T: ?9 x

2 Y/ m/ M  L2 g4 @& S& Q- e3 i4 P5 a: J+ d; G0 ?" M, S6 d7 G

5 @# [# b# k; i/ W& l& @% G
$ h9 R' u2 u  i6 h6 i2 j" v$ H/ y" `* f2 K& y+ T$ R

1 x. C9 \8 h9 r) o& m! Z% w
7 H: S) @5 `( c! H) e% t5 A, M  Q3 L
/ V9 T* ~) j- |
# l0 U5 T5 U% ]
动象论坛
点滴纯粹 简单自然
动象论坛,用心做好论坛!用心创造精品!
[点我进入]www.mjysd.top
回复

使用道具 举报

188

106

主题

1159

回帖

4446

积分

惊鸿侠影

积分
4446

最佳新人活跃会员灌水之王

发表于 2020-5-3 15:40:30 | 显示全部楼层 IP:江西赣州
admin 发表于 2020-5-3 15:39
5 _6 N, I: _7 _, U/ {# D9 `
7 W8 R1 k& w5 K6 b: a, Y7 A: f4 i+ M; Z
# D3 B0 X6 p; l! B: S
ernrnrnrnrnrnrnrnrn
水帖使我快乐
回复

使用道具 举报

666

266

主题

1395

回帖

1万

积分

清正廉明~管理员

用心做好论坛,用心创造精品!

积分
11043

最佳新人活跃会员热心会员推广达人宣传达人灌水之王突出贡献优秀版主荣誉管理论坛元老

QQ
发表于 2020-5-3 15:51:04 | 显示全部楼层 IP:江西南昌
文外缪朴奂 发表于 2020-5-3 15:405 Q9 @* D, s" c
ernrnrnrnrnrnrnrnrn

  t; R0 [9 Q' w! r& s
. j7 w$ e2 ]+ P5 j5 K4 J! L叫我你从说的你重新金色的放假你手机发的那就哦端午节你肯定放假女粉丝* m/ Z: E9 z* b% l5 T
O(∩_∩)O
动象论坛
点滴纯粹 简单自然
动象论坛,用心做好论坛!用心创造精品!
[点我进入]www.mjysd.top
回复

使用道具 举报

*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册!

本版积分规则

QQ|手机版|小黑屋|网站地图|动象论坛

GMT+8, 2025-4-26 21:01 , Processed in 0.408851 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表